diff --git a/include/settings.hpp b/include/settings.hpp index d94a7f37..a7086bbb 100644 --- a/include/settings.hpp +++ b/include/settings.hpp @@ -43,6 +43,8 @@ extern bool invertZoom; 0 for auto. */ extern float pixelRatio; +/** Name of UI theme, specified in ui::refreshTheme() */ +extern std::string uiTheme; /** Opacity of cables in the range [0, 1] */ extern float cableOpacity; /** Straightness of cables in the range [0, 1]. Unitless and arbitrary. */ diff --git a/include/ui/common.hpp b/include/ui/common.hpp index fc601e07..fb159c52 100644 --- a/include/ui/common.hpp +++ b/include/ui/common.hpp @@ -24,6 +24,8 @@ namespace ui { PRIVATE void init(); PRIVATE void destroy(); void setTheme(NVGcolor bg, NVGcolor fg); +/** Sets theme from settings. */ +void refreshTheme(); } // namespace ui diff --git a/src/app/MenuBar.cpp b/src/app/MenuBar.cpp index 4d86a454..449ab589 100644 --- a/src/app/MenuBar.cpp +++ b/src/app/MenuBar.cpp @@ -422,6 +422,21 @@ struct ViewButton : MenuButton { menu->addChild(new ui::MenuSeparator); menu->addChild(createMenuLabel("Appearance")); + static const std::vector uiThemes = {"default", "light", "dark"}; + static const std::vector uiThemeLabels = {"Default", "Light", "Dark"}; + menu->addChild(createIndexSubmenuItem("Theme", uiThemeLabels, + [=]() -> size_t { + auto it = std::find(uiThemes.begin(), uiThemes.end(), settings::uiTheme); + if (it == uiThemes.end()) + return -1; + return it - uiThemes.begin(); + }, + [=](size_t i) { + settings::uiTheme = uiThemes[i]; + ui::refreshTheme(); + } + )); + menu->addChild(createBoolPtrMenuItem("Show tooltips", "", &settings::tooltips)); ZoomSlider* zoomSlider = new ZoomSlider; @@ -472,7 +487,7 @@ struct ViewButton : MenuButton { menu->addChild(knobScrollSensitivitySlider); menu->addChild(new ui::MenuSeparator); - menu->addChild(createMenuLabel("Module dragging")); + menu->addChild(createMenuLabel("Module")); menu->addChild(createBoolPtrMenuItem("Lock positions", "", &settings::lockModules)); diff --git a/src/settings.cpp b/src/settings.cpp index 621a395a..eb445125 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -26,6 +26,7 @@ math::Vec windowSize = math::Vec(1024, 720); math::Vec windowPos = math::Vec(NAN, NAN); bool invertZoom = false; float pixelRatio = 0.0; +std::string uiTheme = "default"; float cableOpacity = 0.5; float cableTension = 1.0; float rackBrightness = 1.0; @@ -128,6 +129,8 @@ json_t* toJson() { json_object_set_new(rootJ, "pixelRatio", json_real(pixelRatio)); + json_object_set_new(rootJ, "uiTheme", json_string(uiTheme.c_str())); + json_object_set_new(rootJ, "cableOpacity", json_real(cableOpacity)); json_object_set_new(rootJ, "cableTension", json_real(cableTension)); @@ -287,6 +290,10 @@ void fromJson(json_t* rootJ) { if (pixelRatioJ) pixelRatio = json_number_value(pixelRatioJ); + json_t* uiThemeJ = json_object_get(rootJ, "uiTheme"); + if (uiThemeJ) + uiTheme = json_string_value(uiThemeJ); + json_t* cableOpacityJ = json_object_get(rootJ, "cableOpacity"); if (cableOpacityJ) cableOpacity = json_number_value(cableOpacityJ); diff --git a/src/ui/common.cpp b/src/ui/common.cpp index 998ebc32..1a5b805b 100644 --- a/src/ui/common.cpp +++ b/src/ui/common.cpp @@ -1,4 +1,5 @@ #include +#include namespace rack { @@ -6,17 +7,14 @@ namespace ui { void init() { - // Default - setTheme(nvgRGB(0x20, 0x20, 0x20), nvgRGB(0xf0, 0xf0, 0xf0)); - // Dark - // setTheme(nvgRGB(0x00, 0x00, 0x00), nvgRGB(0xff, 0xff, 0xff)); - // Light - // setTheme(nvgRGB(0xe8, 0xe8, 0xe8), nvgRGB(0x00, 0x00, 0x00)); + refreshTheme(); } + void destroy() { } + void setTheme(NVGcolor bg, NVGcolor fg) { BNDwidgetTheme w; w.outlineColor = color::lerp(bg, fg, 0.1); @@ -74,5 +72,19 @@ void setTheme(NVGcolor bg, NVGcolor fg) { } +void refreshTheme() { + if (settings::uiTheme == "light") { + setTheme(nvgRGB(0xe8, 0xe8, 0xe8), nvgRGB(0x00, 0x00, 0x00)); + } + else if (settings::uiTheme == "dark") { + setTheme(nvgRGB(0x00, 0x00, 0x00), nvgRGB(0xff, 0xff, 0xff)); + } + else { + // Default + setTheme(nvgRGB(0x20, 0x20, 0x20), nvgRGB(0xf0, 0xf0, 0xf0)); + } +} + + } // namespace ui } // namespace rack