diff --git a/core/src/gui/widgets/waterfall.cpp b/core/src/gui/widgets/waterfall.cpp index 07013487..bb6da738 100644 --- a/core/src/gui/widgets/waterfall.cpp +++ b/core/src/gui/widgets/waterfall.cpp @@ -43,13 +43,17 @@ inline void doZoom(int offset, int width, int outWidth, float* data, float* out, } else { float sFactor = ceilf(factor); + float uFactor; float id = offset; float val, maxVal; + int sId; uint32_t maxId; for (int i = 0; i < outWidth; i++) { maxVal = -INFINITY; - for (int j = 0; j < sFactor; j++) { - if (data[(int)id + j] > maxVal) { maxVal = data[(int)id + j]; } + sId = (int)id; + uFactor = (sId + sFactor > width) ? sFactor - ((sId + sFactor) - width) : sFactor; + for (int j = 0; j < uFactor; j++) { + if (data[sId + j] > maxVal) { maxVal = data[sId + j]; } } out[i] = maxVal; id += factor; diff --git a/macos/set_library_path.sh b/macos/set_library_path.sh new file mode 100644 index 00000000..d245d529 --- /dev/null +++ b/macos/set_library_path.sh @@ -0,0 +1,14 @@ +#!/bin/sh +set -e + +WANTED_LIB=$1 +NEW_PATH=$2 +EXEC=$3 + +get_first_arg() { + echo $1 +} + +CURRENT_RPATH=$(get_first_arg $(otool -L $EXEC | grep $WANTED_LIB)) + +echo $CURRENT_RPATH \ No newline at end of file diff --git a/misc_modules/scheduler/src/actions/start_recorder.h b/misc_modules/scheduler/src/actions/start_recorder.h index ddf8d189..9680b543 100644 --- a/misc_modules/scheduler/src/actions/start_recorder.h +++ b/misc_modules/scheduler/src/actions/start_recorder.h @@ -11,12 +11,18 @@ namespace sched_action { } - void showEditMenu() { - + void prepareEditMenu() { + + } + + bool showEditMenu(bool& valid) { + valid = false; + return false; } void loadFromConfig(json config) { if (config.contains("recorder")) { recorderName = config["recorder"]; } + name = "Start \"" + recorderName + "\""; } json saveToConfig() { @@ -27,16 +33,13 @@ namespace sched_action { std::string getName() { - return "Start \"" + recorderName + "\""; - } - - bool isValid() { - return valid; + return name; } private: std::string recorderName; - bool valid = false; + + std::string name = "Start \"\""; }; diff --git a/misc_modules/scheduler/src/actions/tune_vfo.h b/misc_modules/scheduler/src/actions/tune_vfo.h index 48ed61e5..223235bc 100644 --- a/misc_modules/scheduler/src/actions/tune_vfo.h +++ b/misc_modules/scheduler/src/actions/tune_vfo.h @@ -1,49 +1,143 @@ #pragma once #include #include +#include +#include namespace sched_action { + + const int tuningModes[] = { + tuner::TUNER_MODE_NORMAL, + tuner::TUNER_MODE_CENTER + }; + + const int tuningModeCount = sizeof(tuningModes) / sizeof(int); + + const char* tuningModesStr[] = { + "Normal", + "Center" + }; + class TuneVFOClass : public ActionClass { public: - TuneVFOClass() {} + TuneVFOClass() { + for (auto& mode : tuningModesStr) { + tuningModesTxt += mode; + tuningModesTxt += '\0'; + } + } + ~TuneVFOClass() {} void trigger() { - + if (vfoName.empty()) { return; } + tuner::tune(tuningMode, vfoName, frequency); } - void prepareEditMenu() {} + void prepareEditMenu() { + tmpFrequency = frequency; - void validateEditMenu() {} + // TODO: Find tuning mode + tuningModeId = 0; - void showEditMenu() { - + // Generate text list + vfoNameId = -1; + vfoNames.clear(); + vfoNamesTxt.clear(); + int id = 0; + for (auto& [name, vfo] : gui::waterfall.vfos) { + vfoNames.push_back(name); + vfoNamesTxt += name; + vfoNamesTxt += '\0'; + if (name == vfoName) { + vfoNameId = id; + } + id++; + } + + // If VFO not found, reset the name + if (id < 0 && !vfoNames.empty()) { + vfoNameId = 0; + } + + // Search ID of the tuning mode + tuningModeId = -1; + for (int i = 0; i < tuningModeCount; i++) { + if (tuningModes[i] == tuningMode) { + tuningModeId = i; + break; + } + } + + if (tuningModeId < 0) { + tuningModeId = 0; + } + } + + bool showEditMenu(bool& valid) { + ImGui::LeftLabel("VFO"); + ImGui::SetNextItemWidth(250 - ImGui::GetCursorPosX()); + ImGui::Combo("##scheduler_action_tunevfo_edit_vfo", &vfoNameId, vfoNamesTxt.c_str()); + + ImGui::LeftLabel("Frequency"); + ImGui::SetNextItemWidth(250 - ImGui::GetCursorPosX()); + ImGui::InputDouble("Hz##scheduler_action_tunevfo_edit_freq", &tmpFrequency); + + ImGui::LeftLabel("Tuning Mode"); + ImGui::SetNextItemWidth(250 - ImGui::GetCursorPosX()); + ImGui::Combo("##scheduler_action_tunevfo_edit_tmode", &tuningModeId, tuningModesTxt.c_str()); + + if (ImGui::Button("Apply")) { + vfoName = vfoNames[vfoNameId]; + frequency = tmpFrequency; + tuningMode = tuningModes[tuningModeId]; + valid = true; + return false; + } + ImGui::SameLine(); + if (ImGui::Button("Cancel")) { + valid = false; + return false; + } + + return true; } void loadFromConfig(json config) { if (config.contains("vfo")) { vfoName = config["vfo"]; } if (config.contains("frequency")) { frequency = config["frequency"]; } + if (config.contains("tuningMode")) { tuningMode = config["tuningMode"]; } + + name = "Tune \"" + vfoName + "\" to " + utils::formatFreq(frequency); } json saveToConfig() { json config; config["vfo"] = vfoName; config["frequency"] = frequency; + config["tuningMode"] = tuningMode; return config; } std::string getName() { - return "Tune \"" + vfoName + "\" to " + utils::formatFreq(frequency); - } - - bool isValid() { - return valid; + return name; } private: - std::string vfoName; - double frequency; - bool valid = false; + std::string tuningModesTxt; + std::vector vfoNames; + std::string vfoNamesTxt; + + std::string vfoName = ""; + double frequency = 0; + int tuningMode = 0; + + double tmpFrequency; + int tuningModeId; + + int vfoNameId = -1; + + std::string name; }; diff --git a/misc_modules/scheduler/src/main.cpp b/misc_modules/scheduler/src/main.cpp index 8d860496..5337e3c6 100644 --- a/misc_modules/scheduler/src/main.cpp +++ b/misc_modules/scheduler/src/main.cpp @@ -66,7 +66,7 @@ private: // If editing, show menu if (!_this->editedTask.empty()) { gui::mainWindow.lockWaterfallControls = true; - std::string id = "Edit##scheduler_edit_task_" + _this->name; + std::string id = "Edit Task##scheduler_edit_task_" + _this->name; ImGui::OpenPopup(id.c_str()); if (ImGui::BeginPopup(id.c_str(), ImGuiWindowFlags_NoResize)) { bool valid = false; @@ -97,7 +97,6 @@ private: for (auto& [name, bm] : _this->tasks) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); - ImVec2 min = ImGui::GetCursorPos(); if (ImGui::Selectable((name + "##_freq_mgr_bkm_name_" + _this->name).c_str(), &bm.selected, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_SelectOnClick)) { // if shift or control isn't pressed, deselect all others diff --git a/misc_modules/scheduler/src/sched_action.h b/misc_modules/scheduler/src/sched_action.h index 1f53c8b0..34a06667 100644 --- a/misc_modules/scheduler/src/sched_action.h +++ b/misc_modules/scheduler/src/sched_action.h @@ -8,17 +8,22 @@ using namespace nlohmann; namespace sched_action { class ActionClass { public: - virtual ~ActionClass() { - spdlog::warn("Base destructor"); - }; + virtual ~ActionClass() {}; virtual void trigger() = 0; virtual void prepareEditMenu() = 0; - virtual void validateEditMenu() = 0; - virtual void showEditMenu() = 0; + virtual bool showEditMenu(bool& valid) = 0; virtual void loadFromConfig(json config) = 0; virtual json saveToConfig() = 0; virtual std::string getName() = 0; - virtual bool isValid() = 0; + + virtual bool isValid() { + return valid; + } + + bool selected = false; + + private: + bool valid = false; }; typedef std::shared_ptr Action; diff --git a/misc_modules/scheduler/src/sched_task.h b/misc_modules/scheduler/src/sched_task.h index afd83bcb..3faf7383 100644 --- a/misc_modules/scheduler/src/sched_task.h +++ b/misc_modules/scheduler/src/sched_task.h @@ -23,10 +23,35 @@ public: return true; } + void prepareEditMenu() { + for (auto& act : actions) { + act->selected = false; + } + } + bool showEditMenu(char* name, bool& valid) { ImGui::LeftLabel("Name"); ImGui::InputText("##scheduler_task_edit_name", name, 1023); + if (editedAction >= 0) { + bool valid = false; + + std::string id = "Edit Action##scheduler_edit_action"; + ImGui::OpenPopup(id.c_str()); + if (ImGui::BeginPopup(id.c_str(), ImGuiWindowFlags_NoResize)) { + bool valid = false; + bool open = actions[editedAction]->showEditMenu(valid); + + // Stop editing of closed + if (!open) { + // TODO: Do something if valid I think + editedAction = -1; + } + + ImGui::EndPopup(); + } + } + if (ImGui::BeginTable("scheduler_task_triggers", 1, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImVec2(0, 100))) { ImGui::TableSetupColumn("Triggers"); ImGui::TableSetupScrollFreeze(1, 1); @@ -45,10 +70,31 @@ public: ImGui::TableSetupScrollFreeze(1, 1); ImGui::TableHeadersRow(); + int id = 0; for (auto& act : actions) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); - ImGui::Text(act->getName().c_str()); + + if (ImGui::Selectable((act->getName() + "##scheduler_task_actions_entry").c_str(), &act->selected, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_SelectOnClick)) { + // if shift or control isn't pressed, deselect all others + if (!ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT) && !ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT) && + !ImGui::IsKeyDown(GLFW_KEY_LEFT_CONTROL) && !ImGui::IsKeyDown(GLFW_KEY_RIGHT_CONTROL)) { + int _id = 0; + for (auto& _act : actions) { + if (_id == id) { continue; } + _act->selected = false; + _id++; + } + } + } + + // Open edit menu on double click + if (ImGui::TableGetHoveredColumn() >= 0 && ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && editedAction < 0) { + editedAction = id; + act->prepareEditMenu(); + } + + id++; } ImGui::EndTable(); @@ -72,4 +118,6 @@ public: private: std::vector actions; + int editedAction = -1; + }; \ No newline at end of file