From 69161253e8d8467215adbb45399f70ed602381e6 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Thu, 7 Nov 2024 14:03:32 +0100 Subject: [PATCH 1/3] source menu upgrade --- core/src/core.cpp | 16 +- core/src/gui/menus/source.cpp | 302 ++++++++++++++++++++++------------ core/src/version.h | 2 +- 3 files changed, 216 insertions(+), 104 deletions(-) diff --git a/core/src/core.cpp b/core/src/core.cpp index 4ebe3280..5478f0f2 100644 --- a/core/src/core.cpp +++ b/core/src/core.cpp @@ -232,12 +232,26 @@ int sdrpp_main(int argc, char* argv[]) { defConfig["modules"] = json::array(); + defConfig["offsets"] = json::array(); + defConfig["offsets"][0]["name"] = "SpyVerter"; + defConfig["offsets"][0]["offset"] = 120000000; + defConfig["offsets"][1]["name"] = "Ham-It-Up"; + defConfig["offsets"][1]["offset"] = 125000000; + defConfig["offsets"][2]["name"] = "MMDS S-band (1998MHz)"; + defConfig["offsets"][2]["offset"] = -1998000000; + defConfig["offsets"][3]["name"] = "DK5AV X-Band"; + defConfig["offsets"][3]["offset"] = -6800000000; + defConfig["offsets"][4]["name"] = "Ku LNB (9750MHz)"; + defConfig["offsets"][4]["offset"] = -9750000000; + defConfig["offsets"][5]["name"] = "Ku LNB (10700MHz)"; + defConfig["offsets"][5]["offset"] = -10700000000; + defConfig["offsetMode"] = (int)0; // Off defConfig["offset"] = 0.0; defConfig["showMenu"] = true; defConfig["showWaterfall"] = true; defConfig["source"] = ""; - defConfig["decimationPower"] = 0; + defConfig["decimation"] = 1; defConfig["iqCorrection"] = false; defConfig["invertIQ"] = false; diff --git a/core/src/gui/menus/source.cpp b/core/src/gui/menus/source.cpp index da8285ac..77cd5c03 100644 --- a/core/src/gui/menus/source.cpp +++ b/core/src/gui/menus/source.cpp @@ -5,113 +5,97 @@ #include #include #include +#include +#include namespace sourcemenu { int offsetMode = 0; int sourceId = 0; double customOffset = 0.0; double effectiveOffset = 0.0; - int decimationPower = 0; + int decimId = 0; bool iqCorrection = false; bool invertIQ = false; - EventHandler sourceRegisteredHandler; + EventHandler sourcesChangedHandler; EventHandler sourceUnregisterHandler; - EventHandler sourceUnregisteredHandler; - std::vector sourceNames; - std::string sourceNamesTxt; + OptionList sources; std::string selectedSource; + OptionList offsets; + std::vector customOffsets; + OptionList decimations; + + bool showAddOffsetDialog = false; + char newOffsetName[1024]; + double newOffset = 0.0; + + bool showDelOffsetDialog = false; + std::string delOffsetName = ""; enum { OFFSET_MODE_NONE, - OFFSET_MODE_CUSTOM, - OFFSET_MODE_SPYVERTER, - OFFSET_MODE_HAM_IT_UP, - OFFSET_MODE_MMDS_SB_1998, - OFFSET_MODE_DK5AV_XB, - OFFSET_MODE_KU_LNB_9750, - OFFSET_MODE_KU_LNB_10700, - _OFFSET_MODE_COUNT + OFFSET_MODE_MANUAL, + OFFSET_MODE_CUSTOM_BASE }; - const char* offsetModesTxt = "None\0" - "Custom\0" - "SpyVerter\0" - "Ham-It-Up\0" - "MMDS S-band (1998MHz)\0" - "DK5AV X-Band\0" - "Ku LNB (9750MHz)\0" - "Ku LNB (10700MHz)\0"; - - const char* decimationStages = "None\0" - "2\0" - "4\0" - "8\0" - "16\0" - "32\0" - "64\0"; - void updateOffset() { - if (offsetMode == OFFSET_MODE_CUSTOM) { effectiveOffset = customOffset; } - else if (offsetMode == OFFSET_MODE_SPYVERTER) { - effectiveOffset = 120000000; - } // 120MHz Up-conversion - else if (offsetMode == OFFSET_MODE_HAM_IT_UP) { - effectiveOffset = 125000000; - } // 125MHz Up-conversion - else if (offsetMode == OFFSET_MODE_MMDS_SB_1998) { - effectiveOffset = -1998000000; - } // 1.998GHz Down-conversion - else if (offsetMode == OFFSET_MODE_DK5AV_XB) { - effectiveOffset = -6800000000; - } // 6.8GHz Down-conversion - else if (offsetMode == OFFSET_MODE_KU_LNB_9750) { - effectiveOffset = -9750000000; - } // 9.750GHz Down-conversion - else if (offsetMode == OFFSET_MODE_KU_LNB_10700) { - effectiveOffset = -10700000000; - } // 10.7GHz Down-conversion - else { + // Compute the effective offset + switch (offsetMode) { + case OFFSET_MODE_NONE: effectiveOffset = 0; + break; + case OFFSET_MODE_MANUAL: + effectiveOffset = customOffset; + break; + default: + effectiveOffset = customOffsets[offsetMode - OFFSET_MODE_CUSTOM_BASE]; + break; } + + // Apply it sigpath::sourceManager.setTuningOffset(effectiveOffset); } void refreshSources() { - sourceNames = sigpath::sourceManager.getSourceNames(); - sourceNamesTxt.clear(); + // Get sources + auto sourceNames = sigpath::sourceManager.getSourceNames(); + + // Define source options + sources.clear(); for (auto name : sourceNames) { - sourceNamesTxt += name; - sourceNamesTxt += '\0'; + sources.define(name, name, name); } } void selectSource(std::string name) { - if (sourceNames.empty()) { + // If there is no source, give up + if (sources.empty()) { + sourceId = 0; selectedSource.clear(); return; } - auto it = std::find(sourceNames.begin(), sourceNames.end(), name); - if (it == sourceNames.end()) { - selectSource(sourceNames[0]); + + // If a source with the given name doesn't exist, select the first source instead + if (!sources.valueExists(name)) { + selectSource(sources.value(0)); return; } - sourceId = std::distance(sourceNames.begin(), it); - selectedSource = sourceNames[sourceId]; - sigpath::sourceManager.selectSource(sourceNames[sourceId]); + + // Update the GUI variables + sourceId = sources.valueExists(name); + selectedSource = name; + + // Select the source module + sigpath::sourceManager.selectSource(name); } - void onSourceRegistered(std::string name, void* ctx) { + void onSourcesChanged(std::string name, void* ctx) { + // Update the source list refreshSources(); - if (selectedSource.empty()) { - sourceId = 0; - selectSource(sourceNames[0]); - return; - } - - sourceId = std::distance(sourceNames.begin(), std::find(sourceNames.begin(), sourceNames.end(), selectedSource)); + // Reselect the current source + selectSource(selectedSource); } void onSourceUnregister(std::string name, void* ctx) { @@ -120,60 +104,150 @@ namespace sourcemenu { // TODO: Stop everything } - void onSourceUnregistered(std::string name, void* ctx) { - refreshSources(); + void loadOffsets() { + // Clear list + offsets.clear(); + customOffsets.clear(); - if (sourceNames.empty()) { - selectedSource = ""; - return; + // Define special offset modes + offsets.define("None", 0); + offsets.define("Manual", 1); + + // Acquire the config file + core::configManager.acquire(); + + // Load custom offsets + std::vector offsetList = core::configManager.conf["offsets"]; + for (auto& o : offsetList) { + customOffsets.push_back(o["offset"]); + offsets.define(o["name"], offsets.size()); } - if (name == selectedSource) { - sourceId = std::clamp(sourceId, 0, sourceNames.size() - 1); - selectSource(sourceNames[sourceId]); - return; - } - - sourceId = std::distance(sourceNames.begin(), std::find(sourceNames.begin(), sourceNames.end(), selectedSource)); + // Release the config file + core::configManager.release(); } void init() { + // Load offset modes + loadOffsets(); + + // Define decimation values + decimations.define(1, "None", 1); + decimations.define(2, "2x", 2); + decimations.define(4, "4x", 4); + decimations.define(8, "8x", 8); + decimations.define(16, "16x", 16); + decimations.define(32, "32x", 32); + decimations.define(64, "64x", 64); + + // Acquire the config file core::configManager.acquire(); + + // Load other settings std::string selected = core::configManager.conf["source"]; customOffset = core::configManager.conf["offset"]; offsetMode = core::configManager.conf["offsetMode"]; - decimationPower = core::configManager.conf["decimationPower"]; iqCorrection = core::configManager.conf["iqCorrection"]; invertIQ = core::configManager.conf["invertIQ"]; + int decimation = core::configManager.conf["decimation"]; + if (decimations.keyExists(decimation)) { + decimId = decimations.keyId(decimation); + } + + // Release the config file + core::configManager.release(); + + // Select the source module + refreshSources(); + selectSource(selected); + + // Update frontend settings sigpath::iqFrontEnd.setDCBlocking(iqCorrection); sigpath::iqFrontEnd.setInvertIQ(invertIQ); updateOffset(); + sigpath::iqFrontEnd.setDecimation(decimations.value(decimId)); - refreshSources(); - selectSource(selected); - sigpath::iqFrontEnd.setDecimation(1 << decimationPower); - - sourceRegisteredHandler.handler = onSourceRegistered; + // Register handlers + sourcesChangedHandler.handler = onSourcesChanged; sourceUnregisterHandler.handler = onSourceUnregister; - sourceUnregisteredHandler.handler = onSourceUnregistered; - sigpath::sourceManager.onSourceRegistered.bindHandler(&sourceRegisteredHandler); + sigpath::sourceManager.onSourceRegistered.bindHandler(&sourcesChangedHandler); sigpath::sourceManager.onSourceUnregister.bindHandler(&sourceUnregisterHandler); - sigpath::sourceManager.onSourceUnregistered.bindHandler(&sourceUnregisteredHandler); + sigpath::sourceManager.onSourceUnregistered.bindHandler(&sourcesChangedHandler); + } - core::configManager.release(); + void addOffset(const std::string& name, double offset) { + // Acquire the config file + core::configManager.acquire(); + + // Define a new offset + auto newOffsetObj = json::object(); + newOffsetObj["name"] = newOffsetName; + newOffsetObj["offset"] = newOffset; + core::configManager.conf["offsets"].push_back(newOffsetObj); + + // Acquire the config file + core::configManager.release(true); + + // Reload the offsets + loadOffsets(); + + // Re-select the same one + // TODO: Switch from an array to a map, because two can't have the same name anyway and it'll just make things easier...+ + } + + void delOffset(const std::string& name) { + + } + + bool addOffsetDialog() { + bool open = true; + gui::mainWindow.lockWaterfallControls = true; + + float menuWidth = ImGui::GetContentRegionAvail().x; + + const char* id = "Add offset##sdrpp_add_offset_dialog_"; + ImGui::OpenPopup(id); + + if (ImGui::BeginPopup(id, ImGuiWindowFlags_NoResize)) { + ImGui::LeftLabel("Name"); + ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX()); + ImGui::InputText("##sdrpp_add_offset_name", newOffsetName, 1023); + + ImGui::LeftLabel("Offset"); + ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX()); + ImGui::InputDouble("##sdrpp_add_offset_offset", &newOffset); + + bool denyApply = !newOffsetName[0] || offsets.nameExists(newOffsetName); + + if (denyApply) { style::beginDisabled(); } + if (ImGui::Button("Apply")) { + addOffset(newOffsetName, newOffset); + open = false; + } + if (denyApply) { style::endDisabled(); } + ImGui::SameLine(); + if (ImGui::Button("Cancel")) { + open = false; + } + ImGui::EndPopup(); + } + return open; } void draw(void* ctx) { float itemWidth = ImGui::GetContentRegionAvail().x; + float lineHeight = ImGui::GetTextLineHeightWithSpacing(); + float spacing = lineHeight - ImGui::GetTextLineHeight(); bool running = gui::mainWindow.sdrIsRunning(); if (running) { style::beginDisabled(); } ImGui::SetNextItemWidth(itemWidth); - if (ImGui::Combo("##source", &sourceId, sourceNamesTxt.c_str())) { - selectSource(sourceNames[sourceId]); + if (ImGui::Combo("##source", &sourceId, sources.txt)) { + std::string newSource = sources.value(sourceId); + selectSource(newSource); core::configManager.acquire(); - core::configManager.conf["source"] = sourceNames[sourceId]; + core::configManager.conf["source"] = newSource; core::configManager.release(true); } @@ -196,17 +270,41 @@ namespace sourcemenu { } ImGui::LeftLabel("Offset mode"); - ImGui::SetNextItemWidth(itemWidth - ImGui::GetCursorPosX()); - if (ImGui::Combo("##_sdrpp_offset_mode", &offsetMode, offsetModesTxt)) { + ImGui::SetNextItemWidth(itemWidth - ImGui::GetCursorPosX() - 2.0f*(lineHeight + 1.5f*spacing)); + if (ImGui::Combo("##_sdrpp_offset_mode", &offsetMode, offsets.txt)) { updateOffset(); core::configManager.acquire(); core::configManager.conf["offsetMode"] = offsetMode; core::configManager.release(true); } + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - spacing); + if (offsetMode < OFFSET_MODE_CUSTOM_BASE) { ImGui::BeginDisabled(); } + if (ImGui::Button("-##_sdrpp_offset_del_", ImVec2(lineHeight + 0.5f*spacing, 0))) { + delOffsetName = "TEST"; + showDelOffsetDialog = true; + } + if (offsetMode < OFFSET_MODE_CUSTOM_BASE) { ImGui::EndDisabled(); } + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - spacing); + if (ImGui::Button("+##_sdrpp_offset_add_", ImVec2(lineHeight + 0.5f*spacing, 0))) { + strcpy(newOffsetName, "New Offset"); + showAddOffsetDialog = true; + } + + // Offset delete confirmation + if (ImGui::GenericDialog("sdrpp_del_offset_confirm", showDelOffsetDialog, GENERIC_DIALOG_BUTTONS_YES_NO, []() { + ImGui::Text("Deleting offset named \"%s\". Are you sure?", delOffsetName); + }) == GENERIC_DIALOG_BUTTON_YES) { + delOffset(delOffsetName); + } + + // Offset add diaglog + if (showAddOffsetDialog) { showAddOffsetDialog = addOffsetDialog(); } ImGui::LeftLabel("Offset"); - ImGui::SetNextItemWidth(itemWidth - ImGui::GetCursorPosX()); - if (offsetMode == OFFSET_MODE_CUSTOM) { + ImGui::FillWidth(); + if (offsetMode == OFFSET_MODE_MANUAL) { if (ImGui::InputDouble("##freq_offset", &customOffset, 1.0, 100.0)) { updateOffset(); core::configManager.acquire(); @@ -222,11 +320,11 @@ namespace sourcemenu { if (running) { style::beginDisabled(); } ImGui::LeftLabel("Decimation"); - ImGui::SetNextItemWidth(itemWidth - ImGui::GetCursorPosX()); - if (ImGui::Combo("##source_decim", &decimationPower, decimationStages)) { - sigpath::iqFrontEnd.setDecimation(1 << decimationPower); + ImGui::FillWidth(); + if (ImGui::Combo("##source_decim", &decimId, decimations.txt)) { + sigpath::iqFrontEnd.setDecimation(decimations.value(decimId)); core::configManager.acquire(); - core::configManager.conf["decimationPower"] = decimationPower; + core::configManager.conf["decimation"] = decimations.key(decimId); core::configManager.release(true); } if (running) { style::endDisabled(); } diff --git a/core/src/version.h b/core/src/version.h index 3e0b37f5..2e14cb6d 100644 --- a/core/src/version.h +++ b/core/src/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_STR "1.2.0" \ No newline at end of file +#define VERSION_STR "1.2.1" \ No newline at end of file From b835d07573bf30355dbe8c9f4f4daf4c0c13e9cb Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Thu, 7 Nov 2024 17:39:52 +0100 Subject: [PATCH 2/3] finish custom offset definitions and fix bug in source selection --- core/src/core.cpp | 31 ++++--- core/src/gui/menus/source.cpp | 147 ++++++++++++++++++++++------------ 2 files changed, 109 insertions(+), 69 deletions(-) diff --git a/core/src/core.cpp b/core/src/core.cpp index 5478f0f2..73c1ccbe 100644 --- a/core/src/core.cpp +++ b/core/src/core.cpp @@ -232,22 +232,15 @@ int sdrpp_main(int argc, char* argv[]) { defConfig["modules"] = json::array(); - defConfig["offsets"] = json::array(); - defConfig["offsets"][0]["name"] = "SpyVerter"; - defConfig["offsets"][0]["offset"] = 120000000; - defConfig["offsets"][1]["name"] = "Ham-It-Up"; - defConfig["offsets"][1]["offset"] = 125000000; - defConfig["offsets"][2]["name"] = "MMDS S-band (1998MHz)"; - defConfig["offsets"][2]["offset"] = -1998000000; - defConfig["offsets"][3]["name"] = "DK5AV X-Band"; - defConfig["offsets"][3]["offset"] = -6800000000; - defConfig["offsets"][4]["name"] = "Ku LNB (9750MHz)"; - defConfig["offsets"][4]["offset"] = -9750000000; - defConfig["offsets"][5]["name"] = "Ku LNB (10700MHz)"; - defConfig["offsets"][5]["offset"] = -10700000000; + defConfig["offsets"]["SpyVerter"] = 120000000.0; + defConfig["offsets"]["Ham-It-Up"] = 125000000.0; + defConfig["offsets"]["MMDS S-band (1998MHz)"] = -1998000000.0; + defConfig["offsets"]["DK5AV X-Band"] = -6800000000.0; + defConfig["offsets"]["Ku LNB (9750MHz)"] = -9750000000.0; + defConfig["offsets"]["Ku LNB (10700MHz)"] = -10700000000.0; - defConfig["offsetMode"] = (int)0; // Off - defConfig["offset"] = 0.0; + defConfig["selectedOffset"] = "None"; + defConfig["manualOffset"] = 0.0; defConfig["showMenu"] = true; defConfig["showWaterfall"] = true; defConfig["source"] = ""; @@ -332,12 +325,18 @@ int sdrpp_main(int argc, char* argv[]) { // Remove unused elements auto items = core::configManager.conf.items(); + auto newConf = core::configManager.conf; + bool configCorrected = false; for (auto const& item : items) { if (!defConfig.contains(item.key())) { flog::info("Unused key in config {0}, repairing", item.key()); - core::configManager.conf.erase(item.key()); + newConf.erase(item.key()); + configCorrected = true; } } + if (configCorrected) { + core::configManager.conf = newConf; + } // Update to new module representation in config if needed for (auto [_name, inst] : core::configManager.conf["moduleInstances"].items()) { diff --git a/core/src/gui/menus/source.cpp b/core/src/gui/menus/source.cpp index 77cd5c03..ac2f2cb7 100644 --- a/core/src/gui/menus/source.cpp +++ b/core/src/gui/menus/source.cpp @@ -9,22 +9,24 @@ #include namespace sourcemenu { - int offsetMode = 0; int sourceId = 0; - double customOffset = 0.0; - double effectiveOffset = 0.0; + EventHandler sourcesChangedHandler; + EventHandler sourceUnregisterHandler; + OptionList sources; + std::string selectedSource; + int decimId = 0; + OptionList decimations; + bool iqCorrection = false; bool invertIQ = false; - EventHandler sourcesChangedHandler; - EventHandler sourceUnregisterHandler; - - OptionList sources; - std::string selectedSource; - OptionList offsets; - std::vector customOffsets; - OptionList decimations; + int offsetId = 0; + double manualOffset = 0.0; + std::string selectedOffset; + double effectiveOffset = 0.0; + OptionList offsets; + std::map namedOffsets; bool showAddOffsetDialog = false; char newOffsetName[1024]; @@ -33,23 +35,24 @@ namespace sourcemenu { bool showDelOffsetDialog = false; std::string delOffsetName = ""; + // Offset IDs enum { - OFFSET_MODE_NONE, - OFFSET_MODE_MANUAL, - OFFSET_MODE_CUSTOM_BASE + OFFSET_ID_NONE, + OFFSET_ID_MANUAL, + OFFSET_ID_CUSTOM_BASE }; void updateOffset() { // Compute the effective offset - switch (offsetMode) { - case OFFSET_MODE_NONE: + switch (offsetId) { + case OFFSET_ID_NONE: effectiveOffset = 0; break; - case OFFSET_MODE_MANUAL: - effectiveOffset = customOffset; + case OFFSET_ID_MANUAL: + effectiveOffset = manualOffset; break; default: - effectiveOffset = customOffsets[offsetMode - OFFSET_MODE_CUSTOM_BASE]; + effectiveOffset = namedOffsets[offsets.name(offsetId)]; break; } @@ -57,6 +60,26 @@ namespace sourcemenu { sigpath::sourceManager.setTuningOffset(effectiveOffset); } + void selectOffsetById(int id) { + // Update the offset mode + offsetId = id; + selectedOffset = offsets.name(id); + + // Update the offset + updateOffset(); + } + + void selectOffsetByName(const std::string& name) { + // If the name doesn't exist, select 'None' + if (!offsets.nameExists(name)) { + selectOffsetById(OFFSET_ID_NONE); + return; + } + + // Select using the ID associated with the name + selectOffsetById(offsets.nameId(name)); + } + void refreshSources() { // Get sources auto sourceNames = sigpath::sourceManager.getSourceNames(); @@ -83,7 +106,7 @@ namespace sourcemenu { } // Update the GUI variables - sourceId = sources.valueExists(name); + sourceId = sources.valueId(name); selectedSource = name; // Select the source module @@ -104,23 +127,22 @@ namespace sourcemenu { // TODO: Stop everything } - void loadOffsets() { + void reloadOffsets() { // Clear list offsets.clear(); - customOffsets.clear(); + namedOffsets.clear(); // Define special offset modes - offsets.define("None", 0); - offsets.define("Manual", 1); + offsets.define("None", OFFSET_ID_NONE); + offsets.define("Manual", OFFSET_ID_MANUAL); // Acquire the config file core::configManager.acquire(); // Load custom offsets - std::vector offsetList = core::configManager.conf["offsets"]; - for (auto& o : offsetList) { - customOffsets.push_back(o["offset"]); - offsets.define(o["name"], offsets.size()); + namedOffsets = (std::map)core::configManager.conf["offsets"]; + for (auto& [name, offset] : namedOffsets) { + offsets.define(name, offsets.size()); } // Release the config file @@ -129,7 +151,7 @@ namespace sourcemenu { void init() { // Load offset modes - loadOffsets(); + reloadOffsets(); // Define decimation values decimations.define(1, "None", 1); @@ -144,9 +166,9 @@ namespace sourcemenu { core::configManager.acquire(); // Load other settings - std::string selected = core::configManager.conf["source"]; - customOffset = core::configManager.conf["offset"]; - offsetMode = core::configManager.conf["offsetMode"]; + std::string selectedSource = core::configManager.conf["source"]; + manualOffset = core::configManager.conf["manualOffset"]; + std::string selectedOffset = core::configManager.conf["selectedOffset"]; iqCorrection = core::configManager.conf["iqCorrection"]; invertIQ = core::configManager.conf["invertIQ"]; int decimation = core::configManager.conf["decimation"]; @@ -159,13 +181,13 @@ namespace sourcemenu { // Select the source module refreshSources(); - selectSource(selected); + selectSource(selectedSource); // Update frontend settings sigpath::iqFrontEnd.setDCBlocking(iqCorrection); sigpath::iqFrontEnd.setInvertIQ(invertIQ); - updateOffset(); sigpath::iqFrontEnd.setDecimation(decimations.value(decimId)); + selectOffsetByName(selectedOffset); // Register handlers sourcesChangedHandler.handler = onSourcesChanged; @@ -180,23 +202,33 @@ namespace sourcemenu { core::configManager.acquire(); // Define a new offset - auto newOffsetObj = json::object(); - newOffsetObj["name"] = newOffsetName; - newOffsetObj["offset"] = newOffset; - core::configManager.conf["offsets"].push_back(newOffsetObj); + core::configManager.conf["offsets"][name] = offset; // Acquire the config file core::configManager.release(true); // Reload the offsets - loadOffsets(); + reloadOffsets(); - // Re-select the same one - // TODO: Switch from an array to a map, because two can't have the same name anyway and it'll just make things easier...+ + // Attempt to re-select the same one + selectOffsetByName(selectedOffset); } void delOffset(const std::string& name) { - + // Acquire the config file + core::configManager.acquire(); + + // Define a new offset + core::configManager.conf["offsets"].erase(name); + + // Acquire the config file + core::configManager.release(true); + + // Reload the offsets + reloadOffsets(); + + // Attempt to re-select the same one + selectOffsetByName(selectedOffset); } bool addOffsetDialog() { @@ -217,7 +249,16 @@ namespace sourcemenu { ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX()); ImGui::InputDouble("##sdrpp_add_offset_offset", &newOffset); - bool denyApply = !newOffsetName[0] || offsets.nameExists(newOffsetName); + bool nameExists = offsets.nameExists(newOffsetName); + bool reservedName = !strcmp(newOffsetName, "None") || !strcmp(newOffsetName, "Manual"); + bool denyApply = !newOffsetName[0] || nameExists || reservedName; + + if (nameExists) { + ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "An offset with the given name already exists."); + } + else if (reservedName) { + ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "The given name is reserved."); + } if (denyApply) { style::beginDisabled(); } if (ImGui::Button("Apply")) { @@ -271,20 +312,20 @@ namespace sourcemenu { ImGui::LeftLabel("Offset mode"); ImGui::SetNextItemWidth(itemWidth - ImGui::GetCursorPosX() - 2.0f*(lineHeight + 1.5f*spacing)); - if (ImGui::Combo("##_sdrpp_offset_mode", &offsetMode, offsets.txt)) { - updateOffset(); + if (ImGui::Combo("##_sdrpp_offset", &offsetId, offsets.txt)) { + selectOffsetById(offsetId); core::configManager.acquire(); - core::configManager.conf["offsetMode"] = offsetMode; + core::configManager.conf["selectedOffset"] = offsets.key(offsetId); core::configManager.release(true); } ImGui::SameLine(); ImGui::SetCursorPosX(ImGui::GetCursorPosX() - spacing); - if (offsetMode < OFFSET_MODE_CUSTOM_BASE) { ImGui::BeginDisabled(); } + if (offsetId < OFFSET_ID_CUSTOM_BASE) { ImGui::BeginDisabled(); } if (ImGui::Button("-##_sdrpp_offset_del_", ImVec2(lineHeight + 0.5f*spacing, 0))) { - delOffsetName = "TEST"; + delOffsetName = selectedOffset; showDelOffsetDialog = true; } - if (offsetMode < OFFSET_MODE_CUSTOM_BASE) { ImGui::EndDisabled(); } + if (offsetId < OFFSET_ID_CUSTOM_BASE) { ImGui::EndDisabled(); } ImGui::SameLine(); ImGui::SetCursorPosX(ImGui::GetCursorPosX() - spacing); if (ImGui::Button("+##_sdrpp_offset_add_", ImVec2(lineHeight + 0.5f*spacing, 0))) { @@ -294,7 +335,7 @@ namespace sourcemenu { // Offset delete confirmation if (ImGui::GenericDialog("sdrpp_del_offset_confirm", showDelOffsetDialog, GENERIC_DIALOG_BUTTONS_YES_NO, []() { - ImGui::Text("Deleting offset named \"%s\". Are you sure?", delOffsetName); + ImGui::Text("Deleting offset named \"%s\". Are you sure?", delOffsetName.c_str()); }) == GENERIC_DIALOG_BUTTON_YES) { delOffset(delOffsetName); } @@ -304,11 +345,11 @@ namespace sourcemenu { ImGui::LeftLabel("Offset"); ImGui::FillWidth(); - if (offsetMode == OFFSET_MODE_MANUAL) { - if (ImGui::InputDouble("##freq_offset", &customOffset, 1.0, 100.0)) { + if (offsetId == OFFSET_ID_MANUAL) { + if (ImGui::InputDouble("##freq_offset", &manualOffset, 1.0, 100.0)) { updateOffset(); core::configManager.acquire(); - core::configManager.conf["offset"] = customOffset; + core::configManager.conf["offset"] = manualOffset; core::configManager.release(true); } } From 6891d0bb0f78c744d6709f59f58ccb0b757bbdb2 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Thu, 7 Nov 2024 23:49:15 +0100 Subject: [PATCH 3/3] final bugfixes to the new source menu --- core/src/gui/menus/source.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/core/src/gui/menus/source.cpp b/core/src/gui/menus/source.cpp index ac2f2cb7..d7132320 100644 --- a/core/src/gui/menus/source.cpp +++ b/core/src/gui/menus/source.cpp @@ -140,7 +140,12 @@ namespace sourcemenu { core::configManager.acquire(); // Load custom offsets - namedOffsets = (std::map)core::configManager.conf["offsets"]; + auto ofs = core::configManager.conf["offsets"].items(); + for (auto& o : ofs) { + namedOffsets[o.key()] = (double)o.value(); + } + + // Define custom offsets for (auto& [name, offset] : namedOffsets) { offsets.define(name, offsets.size()); } @@ -349,7 +354,7 @@ namespace sourcemenu { if (ImGui::InputDouble("##freq_offset", &manualOffset, 1.0, 100.0)) { updateOffset(); core::configManager.acquire(); - core::configManager.conf["offset"] = manualOffset; + core::configManager.conf["manualOffset"] = manualOffset; core::configManager.release(true); } }