mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2024-12-25 02:18:30 +01:00
Added theme system
This commit is contained in:
parent
94fae2135d
commit
26079dba0a
@ -19,6 +19,7 @@
|
||||
#include <duktape/duktape.h>
|
||||
#include <duktape/duk_console.h>
|
||||
#include <filesystem>
|
||||
#include <gui/menus/theme.h>
|
||||
|
||||
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||
#include <stb_image_resize.h>
|
||||
@ -166,6 +167,9 @@ int sdrpp_main(int argc, char *argv[]) {
|
||||
defConfig["moduleInstances"]["SDRplay Source"] = "sdrplay_source";
|
||||
defConfig["moduleInstances"]["Audio Sink"] = "audio_sink";
|
||||
|
||||
// Themes
|
||||
defConfig["theme"] = "Dark";
|
||||
|
||||
defConfig["modules"] = json::array();
|
||||
defConfig["offset"] = 0.0;
|
||||
defConfig["showMenu"] = true;
|
||||
@ -322,7 +326,8 @@ int sdrpp_main(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!style::setDarkStyle(resDir)) { return -1; }
|
||||
if (!style::loadFonts(resDir)) { return -1; }
|
||||
thememenu::init(resDir);
|
||||
|
||||
LoadingScreen::setWindow(core::window);
|
||||
|
||||
@ -405,8 +410,8 @@ int sdrpp_main(int argc, char *argv[]) {
|
||||
int display_w, display_h;
|
||||
glfwGetFramebufferSize(core::window, &display_w, &display_h);
|
||||
glViewport(0, 0, display_w, display_h);
|
||||
glClearColor(0.0666f, 0.0666f, 0.0666f, 1.0f);
|
||||
//glClearColor(0.9f, 0.9f, 0.9f, 1.0f);
|
||||
//glClearColor(0.0666f, 0.0666f, 0.0666f, 1.0f);
|
||||
glClearColor(gui::themeManager.clearColor.x, gui::themeManager.clearColor.y, gui::themeManager.clearColor.z, gui::themeManager.clearColor.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
|
@ -9,7 +9,7 @@ namespace sdrpp_credits {
|
||||
"Benjamin Kyd",
|
||||
"Benjamin Vernoux",
|
||||
"Cropinghigh",
|
||||
"Fred F4EED"
|
||||
"Fred F4EED",
|
||||
"Howard0su",
|
||||
"Joshua Kimsey",
|
||||
"Martin Hauke",
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <gui/icons.h>
|
||||
#include <gui/style.h>
|
||||
#include <credits.h>
|
||||
#include <gui/gui.h>
|
||||
|
||||
namespace LoadingScreen {
|
||||
GLFWwindow* _win;
|
||||
@ -76,7 +77,7 @@ namespace LoadingScreen {
|
||||
int display_w, display_h;
|
||||
glfwGetFramebufferSize(_win, &display_w, &display_h);
|
||||
glViewport(0, 0, display_w, display_h);
|
||||
glClearColor(0.0666f, 0.0666f, 0.0666f, 1.0f);
|
||||
glClearColor(gui::themeManager.clearColor.x, gui::themeManager.clearColor.y, gui::themeManager.clearColor.z, gui::themeManager.clearColor.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
|
@ -4,5 +4,6 @@ namespace gui {
|
||||
MainWindow mainWindow;
|
||||
ImGui::WaterFall waterfall;
|
||||
FrequencySelect freqSelect;
|
||||
ThemeManager themeManager;
|
||||
Menu menu;
|
||||
};
|
@ -5,12 +5,13 @@
|
||||
#include <gui/dialogs/loading_screen.h>
|
||||
#include <module.h>
|
||||
#include <gui/main_window.h>
|
||||
#include <gui/theme_manager.h>
|
||||
|
||||
namespace gui {
|
||||
SDRPP_EXPORT ImGui::WaterFall waterfall;
|
||||
SDRPP_EXPORT FrequencySelect freqSelect;
|
||||
SDRPP_EXPORT Menu menu;
|
||||
|
||||
SDRPP_EXPORT ThemeManager themeManager;
|
||||
SDRPP_EXPORT MainWindow mainWindow;
|
||||
|
||||
void selectSource(std::string name);
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <gui/menus/scripting.h>
|
||||
#include <gui/menus/vfo_color.h>
|
||||
#include <gui/menus/module_manager.h>
|
||||
#include <gui/menus/theme.h>
|
||||
#include <gui/dialogs/credits.h>
|
||||
#include <filesystem>
|
||||
#include <signal_path/source.h>
|
||||
@ -68,6 +69,7 @@ void MainWindow::init() {
|
||||
gui::menu.registerEntry("Scripting", scriptingmenu::draw, NULL);
|
||||
gui::menu.registerEntry("Band Plan", bandplanmenu::draw, NULL);
|
||||
gui::menu.registerEntry("Display", displaymenu::draw, NULL);
|
||||
gui::menu.registerEntry("Theme", thememenu::draw, NULL);
|
||||
gui::menu.registerEntry("VFO Color", vfo_color_menu::draw, NULL);
|
||||
gui::menu.registerEntry("Module Manager", module_manager_menu::draw, NULL);
|
||||
|
||||
@ -423,7 +425,7 @@ void MainWindow::draw() {
|
||||
}
|
||||
|
||||
// Left Column
|
||||
|
||||
lockWaterfallControls = false;
|
||||
if (showMenu) {
|
||||
ImGui::Columns(3, "WindowColumns", false);
|
||||
ImGui::SetColumnWidth(0, menuWidth);
|
||||
@ -490,45 +492,47 @@ void MainWindow::draw() {
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
// Handle arrow keys
|
||||
if (vfo != NULL && (gui::waterfall.mouseInFFT || gui::waterfall.mouseInWaterfall)) {
|
||||
if (ImGui::IsKeyPressed(GLFW_KEY_LEFT) && !gui::freqSelect.digitHovered) {
|
||||
double nfreq = gui::waterfall.getCenterFrequency() + vfo->generalOffset - vfo->snapInterval;
|
||||
nfreq = roundl(nfreq / vfo->snapInterval) * vfo->snapInterval;
|
||||
tuner::tune(tuningMode, gui::waterfall.selectedVFO, nfreq);
|
||||
if (!lockWaterfallControls) {
|
||||
// Handle arrow keys
|
||||
if (vfo != NULL && (gui::waterfall.mouseInFFT || gui::waterfall.mouseInWaterfall)) {
|
||||
if (ImGui::IsKeyPressed(GLFW_KEY_LEFT) && !gui::freqSelect.digitHovered) {
|
||||
double nfreq = gui::waterfall.getCenterFrequency() + vfo->generalOffset - vfo->snapInterval;
|
||||
nfreq = roundl(nfreq / vfo->snapInterval) * vfo->snapInterval;
|
||||
tuner::tune(tuningMode, gui::waterfall.selectedVFO, nfreq);
|
||||
}
|
||||
if (ImGui::IsKeyPressed(GLFW_KEY_RIGHT) && !gui::freqSelect.digitHovered) {
|
||||
double nfreq = gui::waterfall.getCenterFrequency() + vfo->generalOffset + vfo->snapInterval;
|
||||
nfreq = roundl(nfreq / vfo->snapInterval) * vfo->snapInterval;
|
||||
tuner::tune(tuningMode, gui::waterfall.selectedVFO, nfreq);
|
||||
}
|
||||
core::configManager.aquire();
|
||||
core::configManager.conf["frequency"] = gui::waterfall.getCenterFrequency();
|
||||
if (vfo != NULL) {
|
||||
core::configManager.conf["vfoOffsets"][gui::waterfall.selectedVFO] = vfo->generalOffset;
|
||||
}
|
||||
core::configManager.release(true);
|
||||
}
|
||||
if (ImGui::IsKeyPressed(GLFW_KEY_RIGHT) && !gui::freqSelect.digitHovered) {
|
||||
double nfreq = gui::waterfall.getCenterFrequency() + vfo->generalOffset + vfo->snapInterval;
|
||||
nfreq = roundl(nfreq / vfo->snapInterval) * vfo->snapInterval;
|
||||
tuner::tune(tuningMode, gui::waterfall.selectedVFO, nfreq);
|
||||
}
|
||||
core::configManager.aquire();
|
||||
core::configManager.conf["frequency"] = gui::waterfall.getCenterFrequency();
|
||||
if (vfo != NULL) {
|
||||
core::configManager.conf["vfoOffsets"][gui::waterfall.selectedVFO] = vfo->generalOffset;
|
||||
}
|
||||
core::configManager.release(true);
|
||||
}
|
||||
|
||||
// Handle scrollwheel
|
||||
int wheel = ImGui::GetIO().MouseWheel;
|
||||
if (wheel != 0 && (gui::waterfall.mouseInFFT || gui::waterfall.mouseInWaterfall)) {
|
||||
double nfreq;
|
||||
if (vfo != NULL) {
|
||||
nfreq = gui::waterfall.getCenterFrequency() + vfo->generalOffset + (vfo->snapInterval * wheel);
|
||||
nfreq = roundl(nfreq / vfo->snapInterval) * vfo->snapInterval;
|
||||
// Handle scrollwheel
|
||||
int wheel = ImGui::GetIO().MouseWheel;
|
||||
if (wheel != 0 && (gui::waterfall.mouseInFFT || gui::waterfall.mouseInWaterfall)) {
|
||||
double nfreq;
|
||||
if (vfo != NULL) {
|
||||
nfreq = gui::waterfall.getCenterFrequency() + vfo->generalOffset + (vfo->snapInterval * wheel);
|
||||
nfreq = roundl(nfreq / vfo->snapInterval) * vfo->snapInterval;
|
||||
}
|
||||
else {
|
||||
nfreq = gui::waterfall.getCenterFrequency() - (gui::waterfall.getViewBandwidth() * wheel / 20.0);
|
||||
}
|
||||
tuner::tune(tuningMode, gui::waterfall.selectedVFO, nfreq);
|
||||
gui::freqSelect.setFrequency(nfreq);
|
||||
core::configManager.aquire();
|
||||
core::configManager.conf["frequency"] = gui::waterfall.getCenterFrequency();
|
||||
if (vfo != NULL) {
|
||||
core::configManager.conf["vfoOffsets"][gui::waterfall.selectedVFO] = vfo->generalOffset;
|
||||
}
|
||||
core::configManager.release(true);
|
||||
}
|
||||
else {
|
||||
nfreq = gui::waterfall.getCenterFrequency() - (gui::waterfall.getViewBandwidth() * wheel / 20.0);
|
||||
}
|
||||
tuner::tune(tuningMode, gui::waterfall.selectedVFO, nfreq);
|
||||
gui::freqSelect.setFrequency(nfreq);
|
||||
core::configManager.aquire();
|
||||
core::configManager.conf["frequency"] = gui::waterfall.getCenterFrequency();
|
||||
if (vfo != NULL) {
|
||||
core::configManager.conf["vfoOffsets"][gui::waterfall.selectedVFO] = vfo->generalOffset;
|
||||
}
|
||||
core::configManager.release(true);
|
||||
}
|
||||
|
||||
ImGui::NextColumn();
|
||||
|
@ -22,6 +22,8 @@ public:
|
||||
// TODO: Replace with it's own class
|
||||
void setVFO(double freq);
|
||||
|
||||
bool lockWaterfallControls = false;
|
||||
|
||||
private:
|
||||
static void fftHandler(dsp::complex_t* samples, int count, void* ctx);
|
||||
static void vfoAddedHandler(VFOManager::VFO* vfo, void* ctx);
|
||||
|
47
core/src/gui/menus/theme.cpp
Normal file
47
core/src/gui/menus/theme.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include <gui/menus/theme.h>
|
||||
#include <gui/gui.h>
|
||||
#include <options.h>
|
||||
#include <core.h>>
|
||||
|
||||
namespace thememenu {
|
||||
int themeId;
|
||||
std::vector<std::string> themeNames;
|
||||
std::string themeNamesTxt;
|
||||
|
||||
void init(std::string resDir) {
|
||||
// TODO: Not hardcode theme directory
|
||||
gui::themeManager.loadThemesFromDir(resDir + "/themes/");
|
||||
core::configManager.aquire();
|
||||
std::string selectedThemeName = core::configManager.conf["theme"];
|
||||
core::configManager.release();
|
||||
|
||||
// Select theme by name, if not available, apply Dark theme
|
||||
themeNames = gui::themeManager.getThemeNames();
|
||||
auto it = std::find(themeNames.begin(), themeNames.end(), selectedThemeName);
|
||||
if (it == themeNames.end()) {
|
||||
it = std::find(themeNames.begin(), themeNames.end(), "Dark");
|
||||
selectedThemeName = "Dark";
|
||||
}
|
||||
gui::themeManager.applyTheme(selectedThemeName);
|
||||
themeId = std::distance(themeNames.begin(), it);
|
||||
|
||||
themeNamesTxt = "";
|
||||
for (auto name : themeNames) {
|
||||
themeNamesTxt += name;
|
||||
themeNamesTxt += '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void draw(void* ctx) {
|
||||
float menuWidth = ImGui::GetContentRegionAvailWidth();
|
||||
ImGui::Text("Theme");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||
if (ImGui::Combo("##theme_select_combo", &themeId, themeNamesTxt.c_str())) {
|
||||
gui::themeManager.applyTheme(themeNames[themeId]);
|
||||
core::configManager.aquire();
|
||||
core::configManager.conf["theme"] = themeNames[themeId];
|
||||
core::configManager.release(true);
|
||||
}
|
||||
}
|
||||
}
|
7
core/src/gui/menus/theme.h
Normal file
7
core/src/gui/menus/theme.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace thememenu {
|
||||
void init(std::string resDir);
|
||||
void draw(void* ctx);
|
||||
}
|
@ -11,107 +11,32 @@ namespace style {
|
||||
ImFont* bigFont;
|
||||
ImFont* hugeFont;
|
||||
|
||||
bool setDefaultStyle(std::string resDir) {
|
||||
bool loadFonts(std::string resDir) {
|
||||
if (!std::filesystem::is_directory(resDir)) {
|
||||
spdlog::error("Inavlid resource directory: {0}", resDir);
|
||||
return false;
|
||||
}
|
||||
|
||||
ImGui::GetStyle().WindowRounding = 0.0f;
|
||||
ImGui::GetStyle().ChildRounding = 0.0f;
|
||||
ImGui::GetStyle().FrameRounding = 0.0f;
|
||||
ImGui::GetStyle().GrabRounding = 0.0f;
|
||||
ImGui::GetStyle().PopupRounding = 0.0f;
|
||||
ImGui::GetStyle().ScrollbarRounding = 0.0f;
|
||||
|
||||
baseFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 16.0f);
|
||||
bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 45.0f);
|
||||
hugeFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 128.0f);
|
||||
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void testtt() {
|
||||
ImGui::StyleColorsLight();
|
||||
}
|
||||
|
||||
bool setDarkStyle(std::string resDir) {
|
||||
if (!std::filesystem::is_directory(resDir)) {
|
||||
spdlog::error("Inavlid resource directory: {0}", resDir);
|
||||
return false;
|
||||
}
|
||||
|
||||
ImGui::GetStyle().WindowRounding = 0.0f;
|
||||
ImGui::GetStyle().ChildRounding = 0.0f;
|
||||
ImGui::GetStyle().FrameRounding = 0.0f;
|
||||
ImGui::GetStyle().GrabRounding = 0.0f;
|
||||
ImGui::GetStyle().PopupRounding = 0.0f;
|
||||
ImGui::GetStyle().ScrollbarRounding = 0.0f;
|
||||
|
||||
baseFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 16.0f);
|
||||
bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 45.0f);
|
||||
hugeFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 128.0f);
|
||||
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
auto& style = ImGui::GetStyle();
|
||||
|
||||
ImVec4* colors = style.Colors;
|
||||
|
||||
colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
|
||||
colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f);
|
||||
colors[ImGuiCol_ChildBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.00f);
|
||||
colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f);
|
||||
colors[ImGuiCol_Border] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f);
|
||||
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||
colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.21f, 0.22f, 0.54f);
|
||||
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.20f, 0.21f, 0.22f, 0.54f);
|
||||
colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.21f, 0.22f, 0.54f);
|
||||
colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f);
|
||||
colors[ImGuiCol_TitleBgActive] = ImVec4(0.29f, 0.29f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f);
|
||||
colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f);
|
||||
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f);
|
||||
colors[ImGuiCol_CheckMark] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f);
|
||||
colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f);
|
||||
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
|
||||
colors[ImGuiCol_Button] = ImVec4(0.44f, 0.44f, 0.44f, 0.40f);
|
||||
colors[ImGuiCol_ButtonHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.45f);
|
||||
colors[ImGuiCol_ButtonActive] = ImVec4(0.44f, 0.44f, 0.44f, 0.40f);
|
||||
colors[ImGuiCol_Header] = ImVec4(0.63f, 0.63f, 0.70f, 0.31f);
|
||||
colors[ImGuiCol_HeaderHovered] = ImVec4(0.63f, 0.63f, 0.70f, 0.40f);
|
||||
colors[ImGuiCol_HeaderActive] = ImVec4(0.63f, 0.63f, 0.70f, 0.31f);
|
||||
colors[ImGuiCol_Separator] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f);
|
||||
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.72f, 0.72f, 0.72f, 0.78f);
|
||||
colors[ImGuiCol_SeparatorActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f);
|
||||
colors[ImGuiCol_ResizeGrip] = ImVec4(0.91f, 0.91f, 0.91f, 0.25f);
|
||||
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.81f, 0.81f, 0.81f, 0.67f);
|
||||
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.46f, 0.46f, 0.46f, 0.95f);
|
||||
colors[ImGuiCol_PlotLines] = ImVec4(0.4f, 0.9f, 1.0f, 1.00f);
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.73f, 0.60f, 0.15f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.87f, 0.87f, 0.87f, 0.35f);
|
||||
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
|
||||
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
|
||||
colors[ImGuiCol_NavHighlight] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
|
||||
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void beginDisabled() {
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.44f, 0.44f, 0.44f, 0.15f));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.20f, 0.21f, 0.22f, 0.30f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.00f, 1.00f, 1.00f, 0.65f));
|
||||
auto& style = ImGui::GetStyle();
|
||||
ImVec4* colors = style.Colors;
|
||||
ImVec4 btnCol = colors[ImGuiCol_Button];
|
||||
ImVec4 frameCol = colors[ImGuiCol_Button];
|
||||
ImVec4 textCol = colors[ImGuiCol_Button];
|
||||
btnCol.w = 0.15f;
|
||||
frameCol.w = 0.30f;
|
||||
textCol.w = 0.65f;
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, btnCol);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, frameCol);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, textCol);
|
||||
}
|
||||
|
||||
void endDisabled() {
|
||||
|
@ -8,7 +8,7 @@ namespace style {
|
||||
extern ImFont* hugeFont;
|
||||
|
||||
bool setDefaultStyle(std::string resDir);
|
||||
bool setDarkStyle(std::string resDir);
|
||||
bool loadFonts(std::string resDir);
|
||||
void beginDisabled();
|
||||
void endDisabled();
|
||||
void testtt();
|
||||
|
@ -6,6 +6,22 @@
|
||||
#include <fstream>
|
||||
|
||||
bool ThemeManager::loadThemesFromDir(std::string path) {
|
||||
// TEST JUST TO DUMP THE ORIGINAL THEME
|
||||
auto& style = ImGui::GetStyle();
|
||||
ImVec4* colors = style.Colors;
|
||||
|
||||
printf("\n\n");
|
||||
for (auto [name, id] : IMGUI_COL_IDS) {
|
||||
ImVec4 col = colors[id];
|
||||
uint8_t r = 255 - (col.x * 255.0f);
|
||||
uint8_t g = 255 - (col.y * 255.0f);
|
||||
uint8_t b = 255 - (col.z * 255.0f);
|
||||
uint8_t a = col.w * 255.0f;
|
||||
printf("\"%s\": \"#%02X%02X%02X%02X\",\n", name.c_str(), r, g, b, a);
|
||||
}
|
||||
printf("\n\n");
|
||||
|
||||
|
||||
if (!std::filesystem::is_directory(path)) {
|
||||
spdlog::error("Theme directory doesn't exist: {0}", path);
|
||||
return false;
|
||||
@ -48,6 +64,11 @@ bool ThemeManager::loadTheme(std::string path) {
|
||||
}
|
||||
std::string name = data["name"];
|
||||
|
||||
if (themes.find(name) != themes.end()) {
|
||||
spdlog::error("A theme named '{0}' already exists", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load theme author if available
|
||||
if (data.contains("author")) {
|
||||
if (!data["author"].is_string()) {
|
||||
@ -62,6 +83,15 @@ bool ThemeManager::loadTheme(std::string path) {
|
||||
for (auto const& [param, val] : params) {
|
||||
if (param == "name" || param == "author") { continue; }
|
||||
|
||||
// Exception for non-imgu colors
|
||||
if (param == "WaterfallBackground" || param == "ClearColor") {
|
||||
if (val[0] != '#' || !std::all_of(val.begin() + 1, val.end(), ::isxdigit) || val.length() != 9) {
|
||||
spdlog::error("Theme {0} contains invalid {1} field. Expected hex RGBA color", path, param);
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isValid = false;
|
||||
|
||||
// If param is a color, check that it's a valid RGBA hex value
|
||||
@ -110,6 +140,18 @@ bool ThemeManager::applyTheme(std::string name) {
|
||||
for (auto const& [param, val] : params) {
|
||||
if (param == "name" || param == "author") { continue; }
|
||||
|
||||
if (param == "WaterfallBackground") {
|
||||
decodeRGBA(val, ret);
|
||||
waterfallBg = ImVec4((float)ret[0]/255.0f, (float)ret[1]/255.0f, (float)ret[2]/255.0f, (float)ret[3]/255.0f);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param == "ClearColor") {
|
||||
decodeRGBA(val, ret);
|
||||
clearColor = ImVec4((float)ret[0]/255.0f, (float)ret[1]/255.0f, (float)ret[2]/255.0f, (float)ret[3]/255.0f);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If param is a color, check that it's a valid RGBA hex value
|
||||
if (IMGUI_COL_IDS.find(param) != IMGUI_COL_IDS.end()) {
|
||||
decodeRGBA(val, ret);
|
||||
@ -132,6 +174,12 @@ bool ThemeManager::decodeRGBA(std::string str, uint8_t out[4]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> ThemeManager::getThemeNames() {
|
||||
std::vector<std::string> names;
|
||||
for (auto [name, theme] : themes) { names.push_back(name); }
|
||||
return names;
|
||||
}
|
||||
|
||||
std::map<std::string, int> ThemeManager::IMGUI_COL_IDS = {
|
||||
{"Text", ImGuiCol_Text},
|
||||
{"TextDisabled", ImGuiCol_TextDisabled},
|
||||
|
@ -20,6 +20,9 @@ public:
|
||||
|
||||
std::vector<std::string> getThemeNames();
|
||||
|
||||
ImVec4 waterfallBg = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);;
|
||||
ImVec4 clearColor = ImVec4(0.0666f, 0.0666f, 0.0666f, 1.0f);
|
||||
|
||||
private:
|
||||
static bool decodeRGBA(std::string str, uint8_t out[4]);
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <gui/widgets/frequency_select.h>
|
||||
#include <config.h>
|
||||
#include <gui/style.h>
|
||||
#include <gui/gui.h>
|
||||
#include <glfw_window.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
@ -142,72 +143,73 @@ void FrequencySelect::draw() {
|
||||
}
|
||||
}
|
||||
|
||||
ImVec2 mousePos = ImGui::GetMousePos();
|
||||
bool leftClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
||||
bool rightClick = ImGui::IsMouseClicked(ImGuiMouseButton_Right);
|
||||
int mw = ImGui::GetIO().MouseWheel;
|
||||
bool onDigit = false;
|
||||
bool hovered = false;
|
||||
if (!gui::mainWindow.lockWaterfallControls) {
|
||||
ImVec2 mousePos = ImGui::GetMousePos();
|
||||
bool leftClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
||||
bool rightClick = ImGui::IsMouseClicked(ImGuiMouseButton_Right);
|
||||
int mw = ImGui::GetIO().MouseWheel;
|
||||
bool onDigit = false;
|
||||
bool hovered = false;
|
||||
|
||||
for (int i = 0; i < 12; i++) {
|
||||
onDigit = false;
|
||||
if (isInArea(mousePos, digitTopMins[i], digitTopMaxs[i])) {
|
||||
window->DrawList->AddRectFilled(digitTopMins[i], digitTopMaxs[i], IM_COL32(255, 0, 0, 75));
|
||||
if (leftClick) {
|
||||
incrementDigit(i);
|
||||
}
|
||||
onDigit = true;
|
||||
}
|
||||
if (isInArea(mousePos, digitBottomMins[i], digitBottomMaxs[i])) {
|
||||
window->DrawList->AddRectFilled(digitBottomMins[i], digitBottomMaxs[i], IM_COL32(0, 0, 255, 75));
|
||||
if (leftClick) {
|
||||
decrementDigit(i);
|
||||
}
|
||||
onDigit = true;
|
||||
}
|
||||
if (onDigit) {
|
||||
hovered = true;
|
||||
if (rightClick || (ImGui::IsKeyPressed(GLFW_KEY_DELETE) || ImGui::IsKeyPressed(GLFW_KEY_ENTER) || ImGui::IsKeyPressed(GLFW_KEY_KP_ENTER))) {
|
||||
for (int j = i; j < 12; j++) {
|
||||
digits[j] = 0;
|
||||
for (int i = 0; i < 12; i++) {
|
||||
onDigit = false;
|
||||
if (isInArea(mousePos, digitTopMins[i], digitTopMaxs[i])) {
|
||||
window->DrawList->AddRectFilled(digitTopMins[i], digitTopMaxs[i], IM_COL32(255, 0, 0, 75));
|
||||
if (leftClick) {
|
||||
incrementDigit(i);
|
||||
}
|
||||
frequencyChanged = true;
|
||||
onDigit = true;
|
||||
}
|
||||
if (ImGui::IsKeyPressed(GLFW_KEY_UP)) {
|
||||
incrementDigit(i);
|
||||
if (isInArea(mousePos, digitBottomMins[i], digitBottomMaxs[i])) {
|
||||
window->DrawList->AddRectFilled(digitBottomMins[i], digitBottomMaxs[i], IM_COL32(0, 0, 255, 75));
|
||||
if (leftClick) {
|
||||
decrementDigit(i);
|
||||
}
|
||||
onDigit = true;
|
||||
}
|
||||
if (ImGui::IsKeyPressed(GLFW_KEY_DOWN)) {
|
||||
decrementDigit(i);
|
||||
}
|
||||
if ((ImGui::IsKeyPressed(GLFW_KEY_LEFT) || ImGui::IsKeyPressed(GLFW_KEY_BACKSPACE)) && i > 0) {
|
||||
moveCursorToDigit(i - 1);
|
||||
}
|
||||
if (ImGui::IsKeyPressed(GLFW_KEY_RIGHT) && i < 11) {
|
||||
moveCursorToDigit(i + 1);
|
||||
}
|
||||
|
||||
auto chars = ImGui::GetIO().InputQueueCharacters;
|
||||
|
||||
// For each keyboard characters, type it
|
||||
for (int j = 0; j < chars.Size; j++) {
|
||||
if (chars[j] >= '0' && chars[j] <= '9') {
|
||||
digits[i + j] = chars[j] - '0';
|
||||
if ((i + j) < 11) { moveCursorToDigit(i + j + 1); }
|
||||
if (onDigit) {
|
||||
hovered = true;
|
||||
if (rightClick || (ImGui::IsKeyPressed(GLFW_KEY_DELETE) || ImGui::IsKeyPressed(GLFW_KEY_ENTER) || ImGui::IsKeyPressed(GLFW_KEY_KP_ENTER))) {
|
||||
for (int j = i; j < 12; j++) {
|
||||
digits[j] = 0;
|
||||
}
|
||||
frequencyChanged = true;
|
||||
}
|
||||
}
|
||||
if (ImGui::IsKeyPressed(GLFW_KEY_UP)) {
|
||||
incrementDigit(i);
|
||||
}
|
||||
if (ImGui::IsKeyPressed(GLFW_KEY_DOWN)) {
|
||||
decrementDigit(i);
|
||||
}
|
||||
if ((ImGui::IsKeyPressed(GLFW_KEY_LEFT) || ImGui::IsKeyPressed(GLFW_KEY_BACKSPACE)) && i > 0) {
|
||||
moveCursorToDigit(i - 1);
|
||||
}
|
||||
if (ImGui::IsKeyPressed(GLFW_KEY_RIGHT) && i < 11) {
|
||||
moveCursorToDigit(i + 1);
|
||||
}
|
||||
|
||||
if (mw != 0) {
|
||||
int count = abs(mw);
|
||||
for (int j = 0; j < count; j++) {
|
||||
mw > 0 ? incrementDigit(i) : decrementDigit(i);
|
||||
auto chars = ImGui::GetIO().InputQueueCharacters;
|
||||
|
||||
// For each keyboard characters, type it
|
||||
for (int j = 0; j < chars.Size; j++) {
|
||||
if (chars[j] >= '0' && chars[j] <= '9') {
|
||||
digits[i + j] = chars[j] - '0';
|
||||
if ((i + j) < 11) { moveCursorToDigit(i + j + 1); }
|
||||
frequencyChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mw != 0) {
|
||||
int count = abs(mw);
|
||||
for (int j = 0; j < count; j++) {
|
||||
mw > 0 ? incrementDigit(i) : decrementDigit(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
digitHovered = hovered;
|
||||
}
|
||||
|
||||
digitHovered = hovered;
|
||||
|
||||
uint64_t freq = 0;
|
||||
for (int i = 0; i < 12; i++) {
|
||||
freq += digits[i] * pow(10, 11 - i);
|
||||
|
@ -17,6 +17,8 @@ namespace ImGui {
|
||||
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), 26);
|
||||
ImRect bb(min, min + size);
|
||||
|
||||
ImU32 text = ImGui::GetColorU32(ImGuiCol_Text);
|
||||
|
||||
float lineHeight = size.y;
|
||||
|
||||
ItemSize(size, style.FramePadding.y);
|
||||
@ -30,14 +32,14 @@ namespace ImGui {
|
||||
char buf[32];
|
||||
|
||||
window->DrawList->AddRectFilled(min + ImVec2(0, 1), min + ImVec2(roundf((float)val * ratio), 10), IM_COL32(0, 136, 255, 255));
|
||||
window->DrawList->AddLine(min, min + ImVec2(0, 9), IM_COL32(255, 255, 255, 255));
|
||||
window->DrawList->AddLine(min + ImVec2(0, 9), min + ImVec2(size.x + 1, 9), IM_COL32(255, 255, 255, 255));
|
||||
window->DrawList->AddLine(min, min + ImVec2(0, 9), text);
|
||||
window->DrawList->AddLine(min + ImVec2(0, 9), min + ImVec2(size.x + 1, 9), text);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
window->DrawList->AddLine(min + ImVec2(roundf((float)i * it), 9), min + ImVec2(roundf((float)i * it), 14), IM_COL32(255, 255, 255, 255));
|
||||
window->DrawList->AddLine(min + ImVec2(roundf((float)i * it), 9), min + ImVec2(roundf((float)i * it), 14), text);
|
||||
sprintf(buf, "%d", i * 10);
|
||||
ImVec2 sz = ImGui::CalcTextSize(buf);
|
||||
window->DrawList->AddText(min + ImVec2(roundf(((float)i * it) - (sz.x/2.0)) + 1, 16), IM_COL32(255, 255, 255, 255), buf);
|
||||
window->DrawList->AddText(min + ImVec2(roundf(((float)i * it) - (sz.x/2.0)) + 1, 16), text, buf);
|
||||
}
|
||||
}
|
||||
}
|
@ -29,8 +29,8 @@ namespace ImGui {
|
||||
|
||||
float zeroDb = roundf(((-val_min) / (val_max - val_min)) * size.x);
|
||||
|
||||
window->DrawList->AddRectFilled(min, min + ImVec2(zeroDb, lineHeight), IM_COL32( 0, 255, 0, 127 ));
|
||||
window->DrawList->AddRectFilled(min + ImVec2(zeroDb, 0), min + ImVec2(size.x, lineHeight), IM_COL32( 255, 0, 0, 127 ));
|
||||
window->DrawList->AddRectFilled(min, min + ImVec2(zeroDb, lineHeight), IM_COL32( 9, 136, 9, 255 ));
|
||||
window->DrawList->AddRectFilled(min + ImVec2(zeroDb, 0), min + ImVec2(size.x, lineHeight), IM_COL32( 136, 9, 9, 255 ));
|
||||
|
||||
float end = roundf(((avg - val_min) / (val_max - val_min)) * size.x);
|
||||
float endP = roundf(((peak - val_min) / (val_max - val_min)) * size.x);
|
||||
|
@ -131,6 +131,7 @@ namespace ImGui {
|
||||
|
||||
ImU32 trace = ImGui::GetColorU32(ImGuiCol_PlotLines);
|
||||
ImU32 shadow = ImGui::GetColorU32(ImGuiCol_PlotLines, 0.2);
|
||||
ImU32 text = ImGui::GetColorU32(ImGuiCol_Text);
|
||||
|
||||
// Vertical scale
|
||||
for (float line = startLine; line > fftMin; line -= vRange) {
|
||||
@ -140,7 +141,7 @@ namespace ImGui {
|
||||
IM_COL32(50, 50, 50, 255), 1.0);
|
||||
sprintf(buf, "%d", (int)line);
|
||||
ImVec2 txtSz = ImGui::CalcTextSize(buf);
|
||||
window->DrawList->AddText(ImVec2(widgetPos.x + 40 - txtSz.x, roundf(yPos - (txtSz.y / 2.0))), IM_COL32( 255, 255, 255, 255 ), buf);
|
||||
window->DrawList->AddText(ImVec2(widgetPos.x + 40 - txtSz.x, roundf(yPos - (txtSz.y / 2.0))), text, buf);
|
||||
}
|
||||
|
||||
// Horizontal scale
|
||||
@ -153,10 +154,10 @@ namespace ImGui {
|
||||
IM_COL32(50, 50, 50, 255), 1.0);
|
||||
window->DrawList->AddLine(ImVec2(roundf(xPos), widgetPos.y + fftHeight + 10),
|
||||
ImVec2(roundf(xPos), widgetPos.y + fftHeight + 17),
|
||||
IM_COL32(255, 255, 255, 255), 1.0);
|
||||
text, 1.0);
|
||||
printAndScale(freq, buf);
|
||||
ImVec2 txtSz = ImGui::CalcTextSize(buf);
|
||||
window->DrawList->AddText(ImVec2(roundf(xPos - (txtSz.x / 2.0)), widgetPos.y + fftHeight + 10 + txtSz.y), IM_COL32( 255, 255, 255, 255 ), buf);
|
||||
window->DrawList->AddText(ImVec2(roundf(xPos - (txtSz.x / 2.0)), widgetPos.y + fftHeight + 10 + txtSz.y), text, buf);
|
||||
}
|
||||
|
||||
// Data
|
||||
@ -176,11 +177,11 @@ namespace ImGui {
|
||||
// X Axis
|
||||
window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 10),
|
||||
ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 10),
|
||||
IM_COL32(255, 255, 255, 255), 1.0);
|
||||
text, 1.0);
|
||||
// Y Axis
|
||||
window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + 9),
|
||||
ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 9),
|
||||
IM_COL32(255, 255, 255, 255), 1.0);
|
||||
text, 1.0);
|
||||
|
||||
|
||||
}
|
||||
@ -193,7 +194,7 @@ namespace ImGui {
|
||||
window->DrawList->AddImage((void*)(intptr_t)textureId, wfMin, wfMax);
|
||||
ImVec2 mPos = ImGui::GetMousePos();
|
||||
|
||||
if (IS_IN_AREA(mPos, wfMin, wfMax)) {
|
||||
if (IS_IN_AREA(mPos, wfMin, wfMax) && !gui::mainWindow.lockWaterfallControls) {
|
||||
for (auto const& [name, vfo] : vfos) {
|
||||
window->DrawList->AddRectFilled(vfo->wfRectMin, vfo->wfRectMax, vfo->color);
|
||||
window->DrawList->AddLine(vfo->wfLineMin, vfo->wfLineMax, (name == selectedVFO) ? IM_COL32(255, 0, 0, 255) : IM_COL32(255, 255, 0, 255));
|
||||
@ -701,11 +702,13 @@ namespace ImGui {
|
||||
onResize();
|
||||
}
|
||||
|
||||
window->DrawList->AddRectFilled(widgetPos, widgetEndPos, IM_COL32( 0, 0, 0, 255 ));
|
||||
//window->DrawList->AddRectFilled(widgetPos, widgetEndPos, IM_COL32( 0, 0, 0, 255 ));
|
||||
ImU32 bg = ImGui::ColorConvertFloat4ToU32(gui::themeManager.waterfallBg);
|
||||
window->DrawList->AddRectFilled(widgetPos, widgetEndPos, bg);
|
||||
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);
|
||||
|
||||
processInputs();
|
||||
if (!gui::mainWindow.lockWaterfallControls) { processInputs(); }
|
||||
|
||||
updateAllVFOs(true);
|
||||
|
||||
@ -724,28 +727,30 @@ namespace ImGui {
|
||||
}
|
||||
|
||||
// Handle fft resize
|
||||
ImVec2 winSize = ImGui::GetWindowSize();
|
||||
ImVec2 mousePos = ImGui::GetMousePos();
|
||||
mousePos.x -= widgetPos.x;
|
||||
mousePos.y -= widgetPos.y;
|
||||
bool click = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
||||
bool down = ImGui::IsMouseDown(ImGuiMouseButton_Left);
|
||||
if (draggingFW) {
|
||||
newFFTAreaHeight = mousePos.y;
|
||||
newFFTAreaHeight = std::clamp<float>(newFFTAreaHeight, 150, widgetSize.y - 50);
|
||||
ImGui::GetForegroundDrawList()->AddLine(ImVec2(widgetPos.x, newFFTAreaHeight + widgetPos.y), ImVec2(widgetEndPos.x, newFFTAreaHeight + widgetPos.y),
|
||||
ImGui::GetColorU32(ImGuiCol_SeparatorActive));
|
||||
}
|
||||
if (mousePos.y >= newFFTAreaHeight - 2 && mousePos.y <= newFFTAreaHeight + 2 && mousePos.x > 0 && mousePos.x < widgetSize.x) {
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
|
||||
if (click) {
|
||||
draggingFW = true;
|
||||
if (!gui::mainWindow.lockWaterfallControls) {
|
||||
ImVec2 winSize = ImGui::GetWindowSize();
|
||||
ImVec2 mousePos = ImGui::GetMousePos();
|
||||
mousePos.x -= widgetPos.x;
|
||||
mousePos.y -= widgetPos.y;
|
||||
bool click = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
||||
bool down = ImGui::IsMouseDown(ImGuiMouseButton_Left);
|
||||
if (draggingFW) {
|
||||
newFFTAreaHeight = mousePos.y;
|
||||
newFFTAreaHeight = std::clamp<float>(newFFTAreaHeight, 150, widgetSize.y - 50);
|
||||
ImGui::GetForegroundDrawList()->AddLine(ImVec2(widgetPos.x, newFFTAreaHeight + widgetPos.y), ImVec2(widgetEndPos.x, newFFTAreaHeight + widgetPos.y),
|
||||
ImGui::GetColorU32(ImGuiCol_SeparatorActive));
|
||||
}
|
||||
if (mousePos.y >= newFFTAreaHeight - 2 && mousePos.y <= newFFTAreaHeight + 2 && mousePos.x > 0 && mousePos.x < widgetSize.x) {
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
|
||||
if (click) {
|
||||
draggingFW = true;
|
||||
}
|
||||
}
|
||||
if(!down && draggingFW) {
|
||||
draggingFW = false;
|
||||
FFTAreaHeight = newFFTAreaHeight;
|
||||
onResize();
|
||||
}
|
||||
}
|
||||
if(!down && draggingFW) {
|
||||
draggingFW = false;
|
||||
FFTAreaHeight = newFFTAreaHeight;
|
||||
onResize();
|
||||
}
|
||||
|
||||
buf_mtx.unlock();
|
||||
@ -1128,14 +1133,16 @@ namespace ImGui {
|
||||
window->DrawList->AddLine(lineMin, lineMax, selected ? IM_COL32(255, 0, 0, 255) : IM_COL32(255, 255, 0, 255));
|
||||
}
|
||||
|
||||
ImVec2 mousePos = ImGui::GetMousePos();
|
||||
if (reference != REF_LOWER && !bandwidthLocked) {
|
||||
if (IS_IN_AREA(mousePos, lbwSelMin, lbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
||||
else if (IS_IN_AREA(mousePos, wfLbwSelMin, wfLbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
||||
}
|
||||
if (reference != REF_UPPER && !bandwidthLocked) {
|
||||
if (IS_IN_AREA(mousePos, rbwSelMin, rbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
||||
else if (IS_IN_AREA(mousePos, wfRbwSelMin, wfRbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
||||
if (!gui::mainWindow.lockWaterfallControls) {
|
||||
ImVec2 mousePos = ImGui::GetMousePos();
|
||||
if (reference != REF_LOWER && !bandwidthLocked) {
|
||||
if (IS_IN_AREA(mousePos, lbwSelMin, lbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
||||
else if (IS_IN_AREA(mousePos, wfLbwSelMin, wfLbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
||||
}
|
||||
if (reference != REF_UPPER && !bandwidthLocked) {
|
||||
if (IS_IN_AREA(mousePos, rbwSelMin, rbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
||||
else if (IS_IN_AREA(mousePos, wfRbwSelMin, wfRbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5,9 +5,11 @@
|
||||
#include <gui/style.h>
|
||||
#include <core.h>
|
||||
#include <thread>
|
||||
#include <options.h>
|
||||
#include <radio_interface.h>
|
||||
#include <signal_path/signal_path.h>
|
||||
#include <vector>
|
||||
#include <gui/tuner.h>
|
||||
|
||||
SDRPP_MOD_INFO {
|
||||
/* Name: */ "frequency_manager",
|
||||
@ -24,6 +26,8 @@ struct FrequencyBookmark {
|
||||
bool selected;
|
||||
};
|
||||
|
||||
ConfigManager config;
|
||||
|
||||
class FrequencyManagerModule : public ModuleManager::Instance {
|
||||
public:
|
||||
FrequencyManagerModule(std::string name) {
|
||||
@ -78,12 +82,20 @@ private:
|
||||
gui::waterfall.centerFreqMoved = true;
|
||||
}
|
||||
else {
|
||||
|
||||
tuner::tune(tuner::TUNER_MODE_NORMAL, vfoName, bm.frequency);
|
||||
if (core::modComManager.interfaceExists(vfoName)) {
|
||||
if (core::modComManager.getModuleName(vfoName) == "radio") {
|
||||
int mode = bm.mode;
|
||||
core::modComManager.callInterface(vfoName, RADIO_IFACE_CMD_SET_MODE, &mode, NULL);
|
||||
// TODO: Set bandwidth as well
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool bookmarkEditDialog() {
|
||||
bool open = true;
|
||||
gui::mainWindow.lockWaterfallControls = true;
|
||||
|
||||
std::string id = "Edit##freq_manager_edit_popup_" + name;
|
||||
ImGui::OpenPopup(id.c_str());
|
||||
@ -131,7 +143,13 @@ private:
|
||||
if (strlen(nameBuf) == 0) { style::beginDisabled(); }
|
||||
if (ImGui::Button("Apply")) {
|
||||
open = false;
|
||||
|
||||
// If editing, delete the original one
|
||||
if (editOpen) {
|
||||
bookmarks.erase(firstEeditedBookmarkName);
|
||||
}
|
||||
bookmarks[nameBuf] = editedBookmark;
|
||||
|
||||
}
|
||||
if (strlen(nameBuf) == 0) { style::endDisabled(); }
|
||||
ImGui::SameLine();
|
||||
@ -143,6 +161,32 @@ private:
|
||||
return open;
|
||||
}
|
||||
|
||||
void loadByName(std::string listName) {
|
||||
if (std::find(listNames.begin(), listNames.end(), listName) == listNames.end()) { return; }
|
||||
bookmarks.clear();
|
||||
config.aquire();
|
||||
for (auto [bmName, bm] : config.conf["lists"][listName].items()) {
|
||||
FrequencyBookmark fbm;
|
||||
fbm.frequency = bm["frequency"];
|
||||
fbm.bandwidth = bm["bandwidth"];
|
||||
fbm.mode = bm["mode"];
|
||||
fbm.selected = false;
|
||||
bookmarks[bmName] = fbm;
|
||||
}
|
||||
config.release();
|
||||
}
|
||||
|
||||
void saveByName(std::string listName) {
|
||||
config.aquire();
|
||||
config.conf["lists"][listName] = json::object();
|
||||
for (auto [bmName, bm] : bookmarks) {
|
||||
config.conf["lists"][listName][bmName]["frequency"] = bm.frequency;
|
||||
config.conf["lists"][listName][bmName]["bandwidth"] = bm.bandwidth;
|
||||
config.conf["lists"][listName][bmName]["mode"] = bm.mode;
|
||||
}
|
||||
config.release(true);
|
||||
}
|
||||
|
||||
static void menuHandler(void* ctx) {
|
||||
FrequencyManagerModule* _this = (FrequencyManagerModule*)ctx;
|
||||
float menuWidth = ImGui::GetContentRegionAvailWidth();
|
||||
@ -211,13 +255,14 @@ private:
|
||||
_this->editOpen = true;
|
||||
_this->editedBookmark = _this->bookmarks[selectedNames[0]];
|
||||
_this->editedBookmarkName = selectedNames[0];
|
||||
_this->firstEeditedBookmarkName = selectedNames[0];
|
||||
}
|
||||
if (selectedNames.size() != 1) { style::endDisabled(); }
|
||||
|
||||
ImGui::EndTable();
|
||||
|
||||
// Bookmark list
|
||||
ImGui::BeginTable(("freq_manager_bkm_table"+_this->name).c_str(), 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(0, 300));
|
||||
ImGui::BeginTable(("freq_manager_bkm_table"+_this->name).c_str(), 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(0, 200));
|
||||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("Bookmark", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableHeadersRow();
|
||||
@ -235,8 +280,6 @@ private:
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text(freqToStr(bm.frequency).c_str());
|
||||
ImVec2 max = ImGui::GetCursorPos();
|
||||
|
||||
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
@ -249,6 +292,10 @@ private:
|
||||
}
|
||||
if (selectedNames.size() != 1) { style::endDisabled(); }
|
||||
|
||||
if (_this->createOpen) {
|
||||
_this->createOpen = _this->bookmarkEditDialog();
|
||||
}
|
||||
|
||||
if (_this->editOpen) {
|
||||
_this->editOpen = _this->bookmarkEditDialog();
|
||||
}
|
||||
@ -256,19 +303,30 @@ private:
|
||||
|
||||
std::string name;
|
||||
bool enabled = true;
|
||||
bool createOpen = false;
|
||||
bool editOpen = false;
|
||||
|
||||
std::map<std::string, FrequencyBookmark> bookmarks;
|
||||
|
||||
std::string editedBookmarkName = "";
|
||||
std::string firstEeditedBookmarkName = "";
|
||||
FrequencyBookmark editedBookmark;
|
||||
|
||||
std::vector<std::string> listNames;
|
||||
std::string selectedListName;
|
||||
int selectedListId = 0;
|
||||
|
||||
int testN = 0;
|
||||
|
||||
};
|
||||
|
||||
MOD_EXPORT void _INIT_() {
|
||||
// Nothing here (testing)
|
||||
json def = json({});
|
||||
def["selectedList"] = "General";
|
||||
def["lists"]["General"] = json::array();
|
||||
config.setPath(options::opts.root + "/frequency_manager_config.json");
|
||||
config.load(def);
|
||||
config.enableAutoSave();
|
||||
}
|
||||
|
||||
MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) {
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
enum {
|
||||
RADIO_IFACE_CMD_GET_MODE,
|
||||
RADIO_IFACE_CMD_SET_MODE
|
||||
RADIO_IFACE_CMD_SET_MODE,
|
||||
RADIO_IFACE_CMD_SET_BANDWIDTH,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
59
root/res/themes/dark.json
Normal file
59
root/res/themes/dark.json
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "Dark",
|
||||
"author": "Ryzerth",
|
||||
"Border": "#6D6D7F7F",
|
||||
"BorderShadow": "#00000000",
|
||||
"Button": "#70707066",
|
||||
"ButtonActive": "#70707066",
|
||||
"ButtonHovered": "#70707072",
|
||||
"CheckMark": "#3D84E0FF",
|
||||
"ChildBg": "#FFFFFF00",
|
||||
"DragDropTarget": "#FFFF00E5",
|
||||
"FrameBg": "#33353889",
|
||||
"FrameBgActive": "#33353889",
|
||||
"FrameBgHovered": "#33353889",
|
||||
"Header": "#A0A0B24F",
|
||||
"HeaderActive": "#A0A0B24F",
|
||||
"HeaderHovered": "#A0A0B266",
|
||||
"MenuBarBg": "#232323FF",
|
||||
"ModalWindowDimBg": "#CCCCCC59",
|
||||
"NavHighlight": "#999999FF",
|
||||
"NavWindowingDimBg": "#CCCCCC33",
|
||||
"NavWindowingHighlight": "#FFFFFFB2",
|
||||
"PlotHistogram": "#BA9926FF",
|
||||
"PlotHistogramHovered": "#FF9900FF",
|
||||
"PlotLines": "#66E5FFFF",
|
||||
"PlotLinesHovered": "#FF6D59FF",
|
||||
"PopupBg": "#141414EF",
|
||||
"ResizeGrip": "#E8E8E83F",
|
||||
"ResizeGripActive": "#757575F2",
|
||||
"ResizeGripHovered": "#CECECEAA",
|
||||
"ScrollbarBg": "#05050587",
|
||||
"ScrollbarGrab": "#4F4F4FFF",
|
||||
"ScrollbarGrabActive": "#828282FF",
|
||||
"ScrollbarGrabHovered": "#686868FF",
|
||||
"Separator": "#6D6D7F7F",
|
||||
"SeparatorActive": "#828282FF",
|
||||
"SeparatorHovered": "#B7B7B7C6",
|
||||
"SliderGrab": "#3D84E0FF",
|
||||
"SliderGrabActive": "#4296F9FF",
|
||||
"Tab": "#2D5993DB",
|
||||
"TabActive": "#3268ADFF",
|
||||
"TabHovered": "#4296F9CC",
|
||||
"TabUnfocused": "#111A25F7",
|
||||
"TabUnfocusedActive": "#22426CFF",
|
||||
"TableBorderLight": "#3A3A3FFF",
|
||||
"TableBorderStrong": "#4F4F59FF",
|
||||
"TableHeaderBg": "#303033FF",
|
||||
"TableRowBg": "#00000000",
|
||||
"TableRowBgAlt": "#FFFFFF0F",
|
||||
"Text": "#FFFFFFFF",
|
||||
"TextDisabled": "#7F7F7FFF",
|
||||
"TextSelectedBg": "#DDDDDD59",
|
||||
"TitleBg": "#0A0A0AFF",
|
||||
"TitleBgActive": "#494949FF",
|
||||
"TitleBgCollapsed": "#00000082",
|
||||
"WindowBg": "#0F0F0FEF",
|
||||
"ClearColor": "#111111FF",
|
||||
"WaterfallBackground": "#000000FF"
|
||||
}
|
59
root/res/themes/light.json
Normal file
59
root/res/themes/light.json
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "Light",
|
||||
"author": "Ryzerth",
|
||||
"Border": "#91917F7F",
|
||||
"BorderShadow": "#FFFFFF00",
|
||||
"Button": "#8E8E8E66",
|
||||
"ButtonActive": "#8E8E8E66",
|
||||
"ButtonHovered": "#8E8E8E72",
|
||||
"CheckMark": "#C17A1EFF",
|
||||
"ChildBg": "#00000000",
|
||||
"DragDropTarget": "#0000FFE5",
|
||||
"FrameBg": "#ACA7A389",
|
||||
"FrameBgActive": "#ACA7A389",
|
||||
"FrameBgHovered": "#ACA7A389",
|
||||
"Header": "#5E5E4C4F",
|
||||
"HeaderActive": "#5E5E4C4F",
|
||||
"HeaderHovered": "#5E5E4C66",
|
||||
"MenuBarBg": "#DBDBDBFF",
|
||||
"ModalWindowDimBg": "#33333359",
|
||||
"NavHighlight": "#666666FF",
|
||||
"NavWindowingDimBg": "#33333333",
|
||||
"NavWindowingHighlight": "#000000B2",
|
||||
"PlotHistogram": "#4466D8FF",
|
||||
"PlotHistogramHovered": "#0066FFFF",
|
||||
"PlotLines": "#991900FF",
|
||||
"PlotLinesHovered": "#0091A5FF",
|
||||
"PopupBg": "#EAEAEAEF",
|
||||
"ResizeGrip": "#1616163F",
|
||||
"ResizeGripActive": "#898989F2",
|
||||
"ResizeGripHovered": "#303030AA",
|
||||
"ScrollbarBg": "#F9F9F987",
|
||||
"ScrollbarGrab": "#AFAFAFFF",
|
||||
"ScrollbarGrabActive": "#7C7C7CFF",
|
||||
"ScrollbarGrabHovered": "#969696FF",
|
||||
"Separator": "#91917F7F",
|
||||
"SeparatorActive": "#7C7C7CFF",
|
||||
"SeparatorHovered": "#474747C6",
|
||||
"SliderGrab": "#C17A1EFF",
|
||||
"SliderGrabActive": "#BC6805FF",
|
||||
"Tab": "#D1A56BDB",
|
||||
"TabActive": "#CC9651FF",
|
||||
"TabHovered": "#BC6805CC",
|
||||
"TabUnfocused": "#EDE4D9F7",
|
||||
"TabUnfocusedActive": "#DCBC92FF",
|
||||
"TableBorderLight": "#C4C4BFFF",
|
||||
"TableBorderStrong": "#AFAFA5FF",
|
||||
"TableHeaderBg": "#CECECCFF",
|
||||
"TableRowBg": "#FFFFFF00",
|
||||
"TableRowBgAlt": "#0000000F",
|
||||
"Text": "#000000FF",
|
||||
"TextDisabled": "#7F7F7FFF",
|
||||
"TextSelectedBg": "#21212159",
|
||||
"TitleBg": "#F4F4F4FF",
|
||||
"TitleBgActive": "#B5B5B5FF",
|
||||
"TitleBgCollapsed": "#FFFFFF82",
|
||||
"WindowBg": "#EFEFEFEF",
|
||||
"ClearColor": "#E6E6E6FF",
|
||||
"WaterfallBackground": "#FFFFFFFF"
|
||||
}
|
Loading…
Reference in New Issue
Block a user