diff --git a/core/src/core.cpp b/core/src/core.cpp index d8f65f1e..b77c4b7d 100644 --- a/core/src/core.cpp +++ b/core/src/core.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #define STB_IMAGE_RESIZE_IMPLEMENTATION #include @@ -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()); diff --git a/core/src/credits.cpp b/core/src/credits.cpp index 29fab2e4..0f3448ac 100644 --- a/core/src/credits.cpp +++ b/core/src/credits.cpp @@ -9,7 +9,7 @@ namespace sdrpp_credits { "Benjamin Kyd", "Benjamin Vernoux", "Cropinghigh", - "Fred F4EED" + "Fred F4EED", "Howard0su", "Joshua Kimsey", "Martin Hauke", diff --git a/core/src/gui/dialogs/loading_screen.cpp b/core/src/gui/dialogs/loading_screen.cpp index 3a69b6f4..87ac8e48 100644 --- a/core/src/gui/dialogs/loading_screen.cpp +++ b/core/src/gui/dialogs/loading_screen.cpp @@ -7,6 +7,7 @@ #include #include #include +#include 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()); diff --git a/core/src/gui/gui.cpp b/core/src/gui/gui.cpp index 290b6c28..2eb3e624 100644 --- a/core/src/gui/gui.cpp +++ b/core/src/gui/gui.cpp @@ -4,5 +4,6 @@ namespace gui { MainWindow mainWindow; ImGui::WaterFall waterfall; FrequencySelect freqSelect; + ThemeManager themeManager; Menu menu; }; \ No newline at end of file diff --git a/core/src/gui/gui.h b/core/src/gui/gui.h index dea039e0..94cd9b95 100644 --- a/core/src/gui/gui.h +++ b/core/src/gui/gui.h @@ -5,12 +5,13 @@ #include #include #include +#include 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); diff --git a/core/src/gui/main_window.cpp b/core/src/gui/main_window.cpp index ff86e171..cdde138f 100644 --- a/core/src/gui/main_window.cpp +++ b/core/src/gui/main_window.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -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(); diff --git a/core/src/gui/main_window.h b/core/src/gui/main_window.h index 31cdc915..33a3cff4 100644 --- a/core/src/gui/main_window.h +++ b/core/src/gui/main_window.h @@ -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); diff --git a/core/src/gui/menus/theme.cpp b/core/src/gui/menus/theme.cpp new file mode 100644 index 00000000..0df3213f --- /dev/null +++ b/core/src/gui/menus/theme.cpp @@ -0,0 +1,47 @@ +#include +#include +#include +#include > + +namespace thememenu { + int themeId; + std::vector 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); + } + } +} \ No newline at end of file diff --git a/core/src/gui/menus/theme.h b/core/src/gui/menus/theme.h new file mode 100644 index 00000000..b41357cf --- /dev/null +++ b/core/src/gui/menus/theme.h @@ -0,0 +1,7 @@ +#pragma once +#include + +namespace thememenu { + void init(std::string resDir); + void draw(void* ctx); +} \ No newline at end of file diff --git a/core/src/gui/style.cpp b/core/src/gui/style.cpp index 5bc7e207..16787fd2 100644 --- a/core/src/gui/style.cpp +++ b/core/src/gui/style.cpp @@ -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() { diff --git a/core/src/gui/style.h b/core/src/gui/style.h index 28a82f67..244e6a77 100644 --- a/core/src/gui/style.h +++ b/core/src/gui/style.h @@ -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(); diff --git a/core/src/gui/theme_manager.cpp b/core/src/gui/theme_manager.cpp index df35ed25..bbce7433 100644 --- a/core/src/gui/theme_manager.cpp +++ b/core/src/gui/theme_manager.cpp @@ -6,6 +6,22 @@ #include 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 ThemeManager::getThemeNames() { + std::vector names; + for (auto [name, theme] : themes) { names.push_back(name); } + return names; +} + std::map ThemeManager::IMGUI_COL_IDS = { {"Text", ImGuiCol_Text}, {"TextDisabled", ImGuiCol_TextDisabled}, diff --git a/core/src/gui/theme_manager.h b/core/src/gui/theme_manager.h index d3d46c03..74646002 100644 --- a/core/src/gui/theme_manager.h +++ b/core/src/gui/theme_manager.h @@ -20,6 +20,9 @@ public: std::vector 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]); diff --git a/core/src/gui/widgets/frequency_select.cpp b/core/src/gui/widgets/frequency_select.cpp index bc7a8589..069e806c 100644 --- a/core/src/gui/widgets/frequency_select.cpp +++ b/core/src/gui/widgets/frequency_select.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -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); diff --git a/core/src/gui/widgets/snr_meter.cpp b/core/src/gui/widgets/snr_meter.cpp index c244d5c7..c9126797 100644 --- a/core/src/gui/widgets/snr_meter.cpp +++ b/core/src/gui/widgets/snr_meter.cpp @@ -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); } } } \ No newline at end of file diff --git a/core/src/gui/widgets/volume_meter.cpp b/core/src/gui/widgets/volume_meter.cpp index 1ac6b55d..4032f640 100644 --- a/core/src/gui/widgets/volume_meter.cpp +++ b/core/src/gui/widgets/volume_meter.cpp @@ -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); diff --git a/core/src/gui/widgets/waterfall.cpp b/core/src/gui/widgets/waterfall.cpp index 19382e09..e9c73520 100644 --- a/core/src/gui/widgets/waterfall.cpp +++ b/core/src/gui/widgets/waterfall.cpp @@ -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(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(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); } + } } }; diff --git a/frequency_manager/src/main.cpp b/frequency_manager/src/main.cpp index b5f96c19..d024df76 100644 --- a/frequency_manager/src/main.cpp +++ b/frequency_manager/src/main.cpp @@ -5,9 +5,11 @@ #include #include #include +#include #include #include #include +#include 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 bookmarks; std::string editedBookmarkName = ""; + std::string firstEeditedBookmarkName = ""; FrequencyBookmark editedBookmark; + std::vector 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) { diff --git a/radio/src/radio_interface.h b/radio/src/radio_interface.h index 91a23da1..2e95c8f3 100644 --- a/radio/src/radio_interface.h +++ b/radio/src/radio_interface.h @@ -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 { diff --git a/root/res/themes/dark.json b/root/res/themes/dark.json new file mode 100644 index 00000000..db7c1727 --- /dev/null +++ b/root/res/themes/dark.json @@ -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" +} \ No newline at end of file diff --git a/root/res/themes/light.json b/root/res/themes/light.json new file mode 100644 index 00000000..4d85d1a0 --- /dev/null +++ b/root/res/themes/light.json @@ -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" +} \ No newline at end of file