mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-03-30 20:15:38 +02:00
Fixed bugs + added option to show bookmarks on FFT
This commit is contained in:
parent
4dc0df74cf
commit
6db8251e46
@ -37,6 +37,14 @@ option(OPT_BUILD_DISCORD_PRESENCE "Build the Discord Rich Presence module" ON)
|
|||||||
option(OPT_BUILD_FREQUENCY_MANAGER "Build the Frequency Manager module" ON)
|
option(OPT_BUILD_FREQUENCY_MANAGER "Build the Frequency Manager module" ON)
|
||||||
option(OPT_BUILD_RECORDER "Audio and baseband recorder" ON)
|
option(OPT_BUILD_RECORDER "Audio and baseband recorder" ON)
|
||||||
|
|
||||||
|
# Compiler arguments for each platform
|
||||||
|
if (MSVC)
|
||||||
|
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
|
||||||
|
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -Wno-unused-command-line-argument -undefined dynamic_lookup")
|
||||||
|
else ()
|
||||||
|
set(CMAKE_CXX_FLAGS "-O3 -std=c++17")
|
||||||
|
endif ()
|
||||||
|
|
||||||
# Core of SDR++
|
# Core of SDR++
|
||||||
add_subdirectory("core")
|
add_subdirectory("core")
|
||||||
@ -137,15 +145,6 @@ if (OPT_BUILD_RECORDER)
|
|||||||
add_subdirectory("recorder")
|
add_subdirectory("recorder")
|
||||||
endif (OPT_BUILD_RECORDER)
|
endif (OPT_BUILD_RECORDER)
|
||||||
|
|
||||||
|
|
||||||
if (MSVC)
|
|
||||||
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
|
|
||||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
||||||
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -Wno-unused-command-line-argument -undefined dynamic_lookup")
|
|
||||||
else ()
|
|
||||||
set(CMAKE_CXX_FLAGS "-O3 -std=c++17")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
add_executable(sdrpp "src/main.cpp" "win32/resources.rc")
|
add_executable(sdrpp "src/main.cpp" "win32/resources.rc")
|
||||||
target_link_libraries(sdrpp PRIVATE sdrpp_core)
|
target_link_libraries(sdrpp PRIVATE sdrpp_core)
|
||||||
|
|
||||||
|
@ -205,6 +205,7 @@ namespace ImGui {
|
|||||||
if (IS_IN_AREA(mPos, wfMin, wfMax) && !gui::mainWindow.lockWaterfallControls) {
|
if (IS_IN_AREA(mPos, wfMin, wfMax) && !gui::mainWindow.lockWaterfallControls) {
|
||||||
for (auto const& [name, vfo] : vfos) {
|
for (auto const& [name, vfo] : vfos) {
|
||||||
window->DrawList->AddRectFilled(vfo->wfRectMin, vfo->wfRectMax, vfo->color);
|
window->DrawList->AddRectFilled(vfo->wfRectMin, vfo->wfRectMax, vfo->color);
|
||||||
|
if (!vfo->lineVisible) { continue; }
|
||||||
window->DrawList->AddLine(vfo->wfLineMin, vfo->wfLineMax, (name == selectedVFO) ? IM_COL32(255, 0, 0, 255) : IM_COL32(255, 255, 0, 255));
|
window->DrawList->AddLine(vfo->wfLineMin, vfo->wfLineMax, (name == selectedVFO) ? IM_COL32(255, 0, 0, 255) : IM_COL32(255, 255, 0, 255));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -714,7 +715,22 @@ namespace ImGui {
|
|||||||
window->DrawList->AddRect(widgetPos, widgetEndPos, IM_COL32( 50, 50, 50, 255 ));
|
window->DrawList->AddRect(widgetPos, widgetEndPos, IM_COL32( 50, 50, 50, 255 ));
|
||||||
window->DrawList->AddLine(ImVec2(widgetPos.x, widgetPos.y + fftHeight + 50), ImVec2(widgetPos.x + widgetSize.x, widgetPos.y + fftHeight + 50), IM_COL32(50, 50, 50, 255), 1.0);
|
window->DrawList->AddLine(ImVec2(widgetPos.x, widgetPos.y + fftHeight + 50), ImVec2(widgetPos.x + widgetSize.x, widgetPos.y + fftHeight + 50), IM_COL32(50, 50, 50, 255), 1.0);
|
||||||
|
|
||||||
if (!gui::mainWindow.lockWaterfallControls) { processInputs(); }
|
if (!gui::mainWindow.lockWaterfallControls) {
|
||||||
|
inputHandled = false;
|
||||||
|
InputHandlerArgs args;
|
||||||
|
args.fftRectMin = fftAreaMin;
|
||||||
|
args.fftRectMax = fftAreaMax;
|
||||||
|
args.freqScaleRectMin = freqAreaMin;
|
||||||
|
args.freqScaleRectMax = freqAreaMax;
|
||||||
|
args.waterfallRectMin = wfMin;
|
||||||
|
args.waterfallRectMax = wfMax;
|
||||||
|
args.lowFreq = lowerFreq;
|
||||||
|
args.highFreq = upperFreq;
|
||||||
|
args.freqToPixelRatio = (double)dataWidth / viewBandwidth;
|
||||||
|
args.pixelToFreqRatio = viewBandwidth / (double)dataWidth;
|
||||||
|
onInputProcess.emit(args);
|
||||||
|
if (!inputHandled) { processInputs(); }
|
||||||
|
}
|
||||||
|
|
||||||
updateAllVFOs(true);
|
updateAllVFOs(true);
|
||||||
|
|
||||||
@ -1001,6 +1017,7 @@ namespace ImGui {
|
|||||||
vfo->wfLbwSelMax = ImVec2(vfo->wfRectMin.x + 2, vfo->wfRectMax.y);
|
vfo->wfLbwSelMax = ImVec2(vfo->wfRectMin.x + 2, vfo->wfRectMax.y);
|
||||||
vfo->wfRbwSelMin = ImVec2(vfo->wfRectMax.x - 2, vfo->wfRectMin.y);
|
vfo->wfRbwSelMin = ImVec2(vfo->wfRectMax.x - 2, vfo->wfRectMin.y);
|
||||||
vfo->wfRbwSelMax = ImVec2(vfo->wfRectMax.x + 2, vfo->wfRectMax.y);
|
vfo->wfRbwSelMax = ImVec2(vfo->wfRectMax.x + 2, vfo->wfRectMax.y);
|
||||||
|
vfo->redrawRequired = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1102,27 +1119,40 @@ namespace ImGui {
|
|||||||
int left = roundf((((lowerOffset - viewOffset) / (viewBandwidth / 2.0)) + 1.0) * ((double)dataWidth / 2.0));
|
int left = roundf((((lowerOffset - viewOffset) / (viewBandwidth / 2.0)) + 1.0) * ((double)dataWidth / 2.0));
|
||||||
int right = roundf((((upperOffset - viewOffset) / (viewBandwidth / 2.0)) + 1.0) * ((double)dataWidth / 2.0));
|
int right = roundf((((upperOffset - viewOffset) / (viewBandwidth / 2.0)) + 1.0) * ((double)dataWidth / 2.0));
|
||||||
|
|
||||||
|
// Check weather the line is visible
|
||||||
if (left >= 0 && left < dataWidth && reference == REF_LOWER) {
|
if (left >= 0 && left < dataWidth && reference == REF_LOWER) {
|
||||||
lineMin = ImVec2(widgetPos.x + 50 + left, widgetPos.y + 9);
|
|
||||||
lineMax = ImVec2(widgetPos.x + 50 + left, widgetPos.y + fftHeight + 9);
|
|
||||||
lineVisible = true;
|
lineVisible = true;
|
||||||
}
|
}
|
||||||
else if (center >= 0 && center < dataWidth && reference == REF_CENTER) {
|
else if (center >= 0 && center < dataWidth && reference == REF_CENTER) {
|
||||||
lineMin = ImVec2(widgetPos.x + 50 + center, widgetPos.y + 9);
|
|
||||||
lineMax = ImVec2(widgetPos.x + 50 + center, widgetPos.y + fftHeight + 9);
|
|
||||||
lineVisible = true;
|
lineVisible = true;
|
||||||
}
|
}
|
||||||
else if (right >= 0 && right < dataWidth && reference == REF_UPPER) {
|
else if (right >= 0 && right < dataWidth && reference == REF_UPPER) {
|
||||||
lineMin = ImVec2(widgetPos.x + 50 + right, widgetPos.y + 9);
|
|
||||||
lineMax = ImVec2(widgetPos.x + 50 + right, widgetPos.y + fftHeight + 9);
|
|
||||||
lineVisible = true;
|
lineVisible = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lineVisible = false;
|
lineVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate the position of the line
|
||||||
|
if (reference == REF_LOWER) {
|
||||||
|
lineMin = ImVec2(widgetPos.x + 50 + left, widgetPos.y + 9);
|
||||||
|
lineMax = ImVec2(widgetPos.x + 50 + left, widgetPos.y + fftHeight + 9);
|
||||||
|
}
|
||||||
|
else if (reference == REF_CENTER) {
|
||||||
|
lineMin = ImVec2(widgetPos.x + 50 + center, widgetPos.y + 9);
|
||||||
|
lineMax = ImVec2(widgetPos.x + 50 + center, widgetPos.y + fftHeight + 9);
|
||||||
|
}
|
||||||
|
else if (reference == REF_UPPER) {
|
||||||
|
lineMin = ImVec2(widgetPos.x + 50 + right, widgetPos.y + 9);
|
||||||
|
lineMax = ImVec2(widgetPos.x + 50 + right, widgetPos.y + fftHeight + 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _left = left;
|
||||||
|
int _right = right;
|
||||||
left = std::clamp<int>(left, 0, dataWidth - 1);
|
left = std::clamp<int>(left, 0, dataWidth - 1);
|
||||||
right = std::clamp<int>(right, 0, dataWidth - 1);
|
right = std::clamp<int>(right, 0, dataWidth - 1);
|
||||||
|
if (left != _left) { leftClamped = true; }
|
||||||
|
if (right != _right) { rightClamped = true; }
|
||||||
|
|
||||||
rectMin = ImVec2(widgetPos.x + 50 + left, widgetPos.y + 10);
|
rectMin = ImVec2(widgetPos.x + 50 + left, widgetPos.y + 10);
|
||||||
rectMax = ImVec2(widgetPos.x + 51 + right, widgetPos.y + fftHeight + 10);
|
rectMax = ImVec2(widgetPos.x + 51 + right, widgetPos.y + fftHeight + 10);
|
||||||
@ -1141,11 +1171,11 @@ namespace ImGui {
|
|||||||
|
|
||||||
if (!gui::mainWindow.lockWaterfallControls) {
|
if (!gui::mainWindow.lockWaterfallControls) {
|
||||||
ImVec2 mousePos = ImGui::GetMousePos();
|
ImVec2 mousePos = ImGui::GetMousePos();
|
||||||
if (reference != REF_LOWER && !bandwidthLocked) {
|
if (reference != REF_LOWER && !bandwidthLocked && !leftClamped) {
|
||||||
if (IS_IN_AREA(mousePos, lbwSelMin, lbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
if (IS_IN_AREA(mousePos, lbwSelMin, lbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
||||||
else if (IS_IN_AREA(mousePos, wfLbwSelMin, wfLbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
else if (IS_IN_AREA(mousePos, wfLbwSelMin, wfLbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
||||||
}
|
}
|
||||||
if (reference != REF_UPPER && !bandwidthLocked) {
|
if (reference != REF_UPPER && !bandwidthLocked && !rightClamped) {
|
||||||
if (IS_IN_AREA(mousePos, rbwSelMin, rbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
if (IS_IN_AREA(mousePos, rbwSelMin, rbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
||||||
else if (IS_IN_AREA(mousePos, wfRbwSelMin, wfRbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
else if (IS_IN_AREA(mousePos, wfRbwSelMin, wfRbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,9 @@ namespace ImGui {
|
|||||||
double snapInterval = 5000;
|
double snapInterval = 5000;
|
||||||
int reference = REF_CENTER;
|
int reference = REF_CENTER;
|
||||||
|
|
||||||
|
bool leftClamped;
|
||||||
|
bool rightClamped;
|
||||||
|
|
||||||
ImVec2 rectMin;
|
ImVec2 rectMin;
|
||||||
ImVec2 rectMax;
|
ImVec2 rectMax;
|
||||||
ImVec2 lineMin;
|
ImVec2 lineMin;
|
||||||
@ -154,6 +157,22 @@ namespace ImGui {
|
|||||||
|
|
||||||
Event<FFTRedrawArgs> onFFTRedraw;
|
Event<FFTRedrawArgs> onFFTRedraw;
|
||||||
|
|
||||||
|
struct InputHandlerArgs {
|
||||||
|
ImVec2 fftRectMin;
|
||||||
|
ImVec2 fftRectMax;
|
||||||
|
ImVec2 freqScaleRectMin;
|
||||||
|
ImVec2 freqScaleRectMax;
|
||||||
|
ImVec2 waterfallRectMin;
|
||||||
|
ImVec2 waterfallRectMax;
|
||||||
|
double lowFreq;
|
||||||
|
double highFreq;
|
||||||
|
double freqToPixelRatio;
|
||||||
|
double pixelToFreqRatio;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool inputHandled = false;
|
||||||
|
Event<InputHandlerArgs> onInputProcess;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
REF_LOWER,
|
REF_LOWER,
|
||||||
REF_CENTER,
|
REF_CENTER,
|
||||||
|
@ -57,14 +57,18 @@ public:
|
|||||||
|
|
||||||
fftRedrawHandler.ctx = this;
|
fftRedrawHandler.ctx = this;
|
||||||
fftRedrawHandler.handler = fftRedraw;
|
fftRedrawHandler.handler = fftRedraw;
|
||||||
|
inputHandler.ctx = this;
|
||||||
|
inputHandler.handler = fftInput;
|
||||||
|
|
||||||
gui::menu.registerEntry(name, menuHandler, this, NULL);
|
gui::menu.registerEntry(name, menuHandler, this, NULL);
|
||||||
gui::waterfall.onFFTRedraw.bindHandler(&fftRedrawHandler);
|
gui::waterfall.onFFTRedraw.bindHandler(&fftRedrawHandler);
|
||||||
|
gui::waterfall.onInputProcess.bindHandler(&inputHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
~FrequencyManagerModule() {
|
~FrequencyManagerModule() {
|
||||||
gui::menu.removeEntry(name);
|
gui::menu.removeEntry(name);
|
||||||
gui::waterfall.onFFTRedraw.unbindHandler(&fftRedrawHandler);
|
gui::waterfall.onFFTRedraw.unbindHandler(&fftRedrawHandler);
|
||||||
|
gui::waterfall.onInputProcess.unbindHandler(&inputHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable() {
|
void enable() {
|
||||||
@ -85,19 +89,28 @@ private:
|
|||||||
if (freq >= 1000000.0) {
|
if (freq >= 1000000.0) {
|
||||||
sprintf(str, "%.06lf", freq / 1000000.0);
|
sprintf(str, "%.06lf", freq / 1000000.0);
|
||||||
int len = strlen(str) - 1;
|
int len = strlen(str) - 1;
|
||||||
while ((str[len] == '0' || str[len] == '.') && len > 0) { len--; }
|
while ((str[len] == '0' || str[len] == '.') && len > 0) {
|
||||||
|
len--;
|
||||||
|
if (str[len] == '.') { len--; break; }
|
||||||
|
}
|
||||||
return std::string(str).substr(0, len + 1) + "MHz";
|
return std::string(str).substr(0, len + 1) + "MHz";
|
||||||
}
|
}
|
||||||
else if (freq >= 1000.0) {
|
else if (freq >= 1000.0) {
|
||||||
sprintf(str, "%.06lf", freq / 1000.0);
|
sprintf(str, "%.06lf", freq / 1000.0);
|
||||||
int len = strlen(str) - 1;
|
int len = strlen(str) - 1;
|
||||||
while ((str[len] == '0' || str[len] == '.') && len > 0) { len--; }
|
while ((str[len] == '0' || str[len] == '.') && len > 0) {
|
||||||
|
len--;
|
||||||
|
if (str[len] == '.') { len--; break; }
|
||||||
|
}
|
||||||
return std::string(str).substr(0, len + 1) + "KHz";
|
return std::string(str).substr(0, len + 1) + "KHz";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sprintf(str, "%.06lf", freq);
|
sprintf(str, "%.06lf", freq);
|
||||||
int len = strlen(str) - 1;
|
int len = strlen(str) - 1;
|
||||||
while ((str[len] == '0' || str[len] == '.') && len > 0) { len--; }
|
while ((str[len] == '0' || str[len] == '.') && len > 0) {
|
||||||
|
len--;
|
||||||
|
if (str[len] == '.') { len--; break; }
|
||||||
|
}
|
||||||
return std::string(str).substr(0, len + 1) + "Hz";
|
return std::string(str).substr(0, len + 1) + "Hz";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,7 +122,6 @@ private:
|
|||||||
gui::waterfall.centerFreqMoved = true;
|
gui::waterfall.centerFreqMoved = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tuner::tune(tuner::TUNER_MODE_NORMAL, vfoName, bm.frequency);
|
|
||||||
if (core::modComManager.interfaceExists(vfoName)) {
|
if (core::modComManager.interfaceExists(vfoName)) {
|
||||||
if (core::modComManager.getModuleName(vfoName) == "radio") {
|
if (core::modComManager.getModuleName(vfoName) == "radio") {
|
||||||
int mode = bm.mode;
|
int mode = bm.mode;
|
||||||
@ -117,6 +129,7 @@ private:
|
|||||||
// TODO: Set bandwidth as well
|
// TODO: Set bandwidth as well
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tuner::tune(tuner::TUNER_MODE_NORMAL, vfoName, bm.frequency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,6 +544,61 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mouseAlreadyDown = false;
|
||||||
|
static void fftInput(ImGui::WaterFall::InputHandlerArgs args, void* ctx) {
|
||||||
|
FrequencyManagerModule* _this = (FrequencyManagerModule*)ctx;
|
||||||
|
if (!_this->showBookmarksOnFFT) { return; }
|
||||||
|
|
||||||
|
// First check that the mouse clicked outside of any label. Also get the bookmark that's hovered
|
||||||
|
bool inALabel = false;
|
||||||
|
FrequencyBookmark hoveredBookmark;
|
||||||
|
std::string hoveredBookmarkName;
|
||||||
|
for (auto const [_name, bm] : _this->bookmarks) {
|
||||||
|
double centerXpos = args.fftRectMin.x + std::round((bm.frequency - args.lowFreq) * args.freqToPixelRatio);
|
||||||
|
ImVec2 nameSize = ImGui::CalcTextSize(_name.c_str());
|
||||||
|
ImVec2 rectMin = ImVec2(centerXpos-(nameSize.x/2)-5, args.fftRectMin.y);
|
||||||
|
ImVec2 rectMax = ImVec2(centerXpos+(nameSize.x/2)+5, args.fftRectMin.y+nameSize.y);
|
||||||
|
ImVec2 clampedRectMin = ImVec2(std::clamp<double>(rectMin.x, args.fftRectMin.x, args.fftRectMax.x), rectMin.y);
|
||||||
|
ImVec2 clampedRectMax = ImVec2(std::clamp<double>(rectMax.x, args.fftRectMin.x, args.fftRectMax.x), rectMax.y);
|
||||||
|
|
||||||
|
if (ImGui::IsMouseHoveringRect(clampedRectMin, clampedRectMax)) {
|
||||||
|
inALabel = true;
|
||||||
|
hoveredBookmark = bm;
|
||||||
|
hoveredBookmarkName = _name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if mouse was already down
|
||||||
|
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !inALabel) {
|
||||||
|
_this->mouseAlreadyDown = true;
|
||||||
|
}
|
||||||
|
if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
|
||||||
|
_this->mouseAlreadyDown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If yes, cancel
|
||||||
|
if (_this->mouseAlreadyDown || !inALabel) { return; }
|
||||||
|
|
||||||
|
gui::waterfall.inputHandled = true;
|
||||||
|
|
||||||
|
double centerXpos = args.fftRectMin.x + std::round((hoveredBookmark.frequency - args.lowFreq) * args.freqToPixelRatio);
|
||||||
|
ImVec2 nameSize = ImGui::CalcTextSize(hoveredBookmarkName.c_str());
|
||||||
|
ImVec2 rectMin = ImVec2(centerXpos-(nameSize.x/2)-5, args.fftRectMin.y);
|
||||||
|
ImVec2 rectMax = ImVec2(centerXpos+(nameSize.x/2)+5, args.fftRectMin.y+nameSize.y);
|
||||||
|
ImVec2 clampedRectMin = ImVec2(std::clamp<double>(rectMin.x, args.fftRectMin.x, args.fftRectMax.x), rectMin.y);
|
||||||
|
ImVec2 clampedRectMax = ImVec2(std::clamp<double>(rectMax.x, args.fftRectMin.x, args.fftRectMax.x), rectMax.y);
|
||||||
|
|
||||||
|
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
||||||
|
applyBookmark(hoveredBookmark, gui::waterfall.selectedVFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Bandwidth: %s", freqToStr(hoveredBookmark.bandwidth).c_str());
|
||||||
|
ImGui::Text("Mode: %s", demodModeList[hoveredBookmark.mode]);
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
json exportedBookmarks;
|
json exportedBookmarks;
|
||||||
bool importOpen = false;
|
bool importOpen = false;
|
||||||
bool exportOpen = false;
|
bool exportOpen = false;
|
||||||
@ -586,6 +654,7 @@ private:
|
|||||||
bool showBookmarksOnFFT = false;
|
bool showBookmarksOnFFT = false;
|
||||||
|
|
||||||
EventHandler<ImGui::WaterFall::FFTRedrawArgs> fftRedrawHandler;
|
EventHandler<ImGui::WaterFall::FFTRedrawArgs> fftRedrawHandler;
|
||||||
|
EventHandler<ImGui::WaterFall::InputHandlerArgs> inputHandler;
|
||||||
|
|
||||||
std::map<std::string, FrequencyBookmark> bookmarks;
|
std::map<std::string, FrequencyBookmark> bookmarks;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user