mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-01-28 10:34:44 +01:00
add copy/paste support to the frequency selector
This commit is contained in:
parent
08f3a7d201
commit
1cbc8ec6f5
@ -3,6 +3,7 @@
|
|||||||
#include <gui/style.h>
|
#include <gui/style.h>
|
||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
#include <backend.h>
|
#include <backend.h>
|
||||||
|
#include <utils/hrfreq.h>
|
||||||
|
|
||||||
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
@ -90,6 +91,7 @@ void FrequencySelect::moveCursorToDigit(int i) {
|
|||||||
|
|
||||||
void FrequencySelect::draw() {
|
void FrequencySelect::draw() {
|
||||||
auto window = ImGui::GetCurrentWindow();
|
auto window = ImGui::GetCurrentWindow();
|
||||||
|
auto io = ImGui::GetIO();
|
||||||
widgetPos = ImGui::GetWindowContentRegionMin();
|
widgetPos = ImGui::GetWindowContentRegionMin();
|
||||||
ImVec2 cursorPos = ImGui::GetCursorPos();
|
ImVec2 cursorPos = ImGui::GetCursorPos();
|
||||||
widgetPos.x += window->Pos.x + cursorPos.x;
|
widgetPos.x += window->Pos.x + cursorPos.x;
|
||||||
@ -132,7 +134,7 @@ void FrequencySelect::draw() {
|
|||||||
ImVec2 mousePos = ImGui::GetMousePos();
|
ImVec2 mousePos = ImGui::GetMousePos();
|
||||||
bool leftClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
bool leftClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
||||||
bool rightClick = ImGui::IsMouseClicked(ImGuiMouseButton_Right);
|
bool rightClick = ImGui::IsMouseClicked(ImGuiMouseButton_Right);
|
||||||
int mw = ImGui::GetIO().MouseWheel;
|
int mw = io.MouseWheel;
|
||||||
bool onDigit = false;
|
bool onDigit = false;
|
||||||
bool hovered = false;
|
bool hovered = false;
|
||||||
|
|
||||||
@ -174,7 +176,7 @@ void FrequencySelect::draw() {
|
|||||||
moveCursorToDigit(i + 1);
|
moveCursorToDigit(i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto chars = ImGui::GetIO().InputQueueCharacters;
|
auto chars = io.InputQueueCharacters;
|
||||||
|
|
||||||
// For each keyboard characters, type it
|
// For each keyboard characters, type it
|
||||||
for (int j = 0; j < chars.Size; j++) {
|
for (int j = 0; j < chars.Size; j++) {
|
||||||
@ -194,6 +196,34 @@ void FrequencySelect::draw() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
digitHovered = hovered;
|
digitHovered = hovered;
|
||||||
|
|
||||||
|
if (isInArea(mousePos, digitTopMins[0], digitBottomMaxs[11])) {
|
||||||
|
bool shortcutKey = io.ConfigMacOSXBehaviors ? (io.KeyMods == ImGuiKeyModFlags_Super) : (io.KeyMods == ImGuiKeyModFlags_Ctrl);
|
||||||
|
bool ctrlOnly = (io.KeyMods == ImGuiKeyModFlags_Ctrl);
|
||||||
|
bool shiftOnly = (io.KeyMods == ImGuiKeyModFlags_Shift);
|
||||||
|
bool copy = ((shortcutKey && ImGui::IsKeyPressed(ImGuiKey_C)) || (ctrlOnly && ImGui::IsKeyPressed(ImGuiKey_Insert)));
|
||||||
|
bool paste = ((shortcutKey && ImGui::IsKeyPressed(ImGuiKey_V)) || (shiftOnly && ImGui::IsKeyPressed(ImGuiKey_Insert)));
|
||||||
|
if (copy) {
|
||||||
|
// Convert the freqency to a string
|
||||||
|
std::string freqStr = hrfreq::toString(frequency);
|
||||||
|
|
||||||
|
// Write it to the clipboard
|
||||||
|
ImGui::SetClipboardText(freqStr.c_str());
|
||||||
|
}
|
||||||
|
if (paste) {
|
||||||
|
// Attempt to parse the clipboard as a number
|
||||||
|
const char* clip = ImGui::GetClipboardText();
|
||||||
|
|
||||||
|
// If the clipboard is not empty, attempt to parse it
|
||||||
|
if (clip) {
|
||||||
|
double newFreq;
|
||||||
|
if (hrfreq::fromString(clip, newFreq)) {
|
||||||
|
setFrequency(abs(newFreq));
|
||||||
|
frequencyChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t freq = 0;
|
uint64_t freq = 0;
|
||||||
|
113
core/src/utils/hrfreq.cpp
Normal file
113
core/src/utils/hrfreq.cpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
#include "hrfreq.h"
|
||||||
|
#include <utils/flog.h>
|
||||||
|
|
||||||
|
namespace hrfreq {
|
||||||
|
|
||||||
|
|
||||||
|
std::string toString(double freq) {
|
||||||
|
// Determine the scale
|
||||||
|
int maxDecimals = 0;
|
||||||
|
const char* suffix = "Hz";
|
||||||
|
if (freq >= 1e9) {
|
||||||
|
freq /= 1e9;
|
||||||
|
maxDecimals = 9;
|
||||||
|
suffix = "GHz";
|
||||||
|
}
|
||||||
|
else if (freq >= 1e6) {
|
||||||
|
freq /= 1e6;
|
||||||
|
maxDecimals = 6;
|
||||||
|
suffix = "MHz";
|
||||||
|
}
|
||||||
|
else if (freq >= 1e3) {
|
||||||
|
freq /= 1e3;
|
||||||
|
maxDecimals = 3;
|
||||||
|
suffix = "KHz";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to string (TODO: Not sure if limiting the decimals rounds)
|
||||||
|
char numBuf[128];
|
||||||
|
int numLen = sprintf(numBuf, "%0.*lf", maxDecimals, freq);
|
||||||
|
|
||||||
|
// Remove the useless zeros
|
||||||
|
for (int i = numLen-1; i >= 0; i--) {
|
||||||
|
if (numBuf[i] != '0' && numBuf[i] != '.') { break; }
|
||||||
|
numBuf[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Concat the suffix
|
||||||
|
char finalBuf[128];
|
||||||
|
sprintf(finalBuf, "%s%s", numBuf, suffix);
|
||||||
|
|
||||||
|
// Return the final string
|
||||||
|
return finalBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNumeric(char c) {
|
||||||
|
return std::isdigit(c) || c == '+' || c == '-' || c == '.' || c == ',';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fromString(const std::string& str, double& freq) {
|
||||||
|
// Skip non-numeric characters
|
||||||
|
int i = 0;
|
||||||
|
char c;
|
||||||
|
for (; i < str.size(); i++) {
|
||||||
|
if (isNumeric(str[i])) { break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the numeric part
|
||||||
|
std::string numeric;
|
||||||
|
for (; i < str.size(); i++) {
|
||||||
|
// Get the character
|
||||||
|
c = str[i];
|
||||||
|
|
||||||
|
// If it's a letter, stop
|
||||||
|
if (std::isalpha(c)) { break; }
|
||||||
|
|
||||||
|
// If isn't numeric, skip it
|
||||||
|
if (!isNumeric(c)) { continue; }
|
||||||
|
|
||||||
|
// Add the character to the numeric string
|
||||||
|
numeric += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to parse the numeric part
|
||||||
|
double num;
|
||||||
|
try {
|
||||||
|
num = std::stod(numeric);
|
||||||
|
}
|
||||||
|
catch (const std::exception& e) {
|
||||||
|
flog::error("Failed to parse numeric part: '{}'", numeric);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no more text is available, assume the numeric part gives a frequency in Hz
|
||||||
|
if (i == str.size()) {
|
||||||
|
flog::warn("No unit given, assuming it's Hz");
|
||||||
|
freq = num;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale the numeric value depending on the first scale character
|
||||||
|
char scale = std::toupper(str[i]);
|
||||||
|
switch (scale) {
|
||||||
|
case 'G':
|
||||||
|
num *= 1e9;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
num *= 1e6;
|
||||||
|
break;
|
||||||
|
case 'K':
|
||||||
|
num *= 1e3;
|
||||||
|
break;
|
||||||
|
case 'H':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
flog::warn("Unknown frequency scale: '{}'", scale);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the frequency
|
||||||
|
freq = num;
|
||||||
|
return true; // TODO
|
||||||
|
}
|
||||||
|
}
|
19
core/src/utils/hrfreq.h
Normal file
19
core/src/utils/hrfreq.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace hrfreq {
|
||||||
|
/**
|
||||||
|
* Convert a frequency to a human-readable string.
|
||||||
|
* @param freq Frequency in Hz.
|
||||||
|
* @return Human-readable representation of the frequency.
|
||||||
|
*/
|
||||||
|
std::string toString(double freq);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a human-readable representation of a frequency to a frequency value.
|
||||||
|
* @param str String containing the human-readable frequency.
|
||||||
|
* @param freq Value to write the decoded frequency to.
|
||||||
|
* @return True on success, false otherwise.
|
||||||
|
*/
|
||||||
|
bool fromString(const std::string& str, double& freq);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user