| @@ -43,6 +43,8 @@ extern bool invertZoom; | |||||
| 0 for auto. | 0 for auto. | ||||
| */ | */ | ||||
| extern float pixelRatio; | extern float pixelRatio; | ||||
| /** Name of UI theme, specified in ui::refreshTheme() */ | |||||
| extern std::string uiTheme; | |||||
| /** Opacity of cables in the range [0, 1] */ | /** Opacity of cables in the range [0, 1] */ | ||||
| extern float cableOpacity; | extern float cableOpacity; | ||||
| /** Straightness of cables in the range [0, 1]. Unitless and arbitrary. */ | /** Straightness of cables in the range [0, 1]. Unitless and arbitrary. */ | ||||
| @@ -24,6 +24,8 @@ namespace ui { | |||||
| PRIVATE void init(); | PRIVATE void init(); | ||||
| PRIVATE void destroy(); | PRIVATE void destroy(); | ||||
| void setTheme(NVGcolor bg, NVGcolor fg); | void setTheme(NVGcolor bg, NVGcolor fg); | ||||
| /** Sets theme from settings. */ | |||||
| void refreshTheme(); | |||||
| } // namespace ui | } // namespace ui | ||||
| @@ -422,6 +422,21 @@ struct ViewButton : MenuButton { | |||||
| menu->addChild(new ui::MenuSeparator); | menu->addChild(new ui::MenuSeparator); | ||||
| menu->addChild(createMenuLabel("Appearance")); | menu->addChild(createMenuLabel("Appearance")); | ||||
| static const std::vector<std::string> uiThemes = {"default", "light", "dark"}; | |||||
| static const std::vector<std::string> 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)); | menu->addChild(createBoolPtrMenuItem("Show tooltips", "", &settings::tooltips)); | ||||
| ZoomSlider* zoomSlider = new ZoomSlider; | ZoomSlider* zoomSlider = new ZoomSlider; | ||||
| @@ -472,7 +487,7 @@ struct ViewButton : MenuButton { | |||||
| menu->addChild(knobScrollSensitivitySlider); | menu->addChild(knobScrollSensitivitySlider); | ||||
| menu->addChild(new ui::MenuSeparator); | menu->addChild(new ui::MenuSeparator); | ||||
| menu->addChild(createMenuLabel("Module dragging")); | |||||
| menu->addChild(createMenuLabel("Module")); | |||||
| menu->addChild(createBoolPtrMenuItem("Lock positions", "", &settings::lockModules)); | menu->addChild(createBoolPtrMenuItem("Lock positions", "", &settings::lockModules)); | ||||
| @@ -26,6 +26,7 @@ math::Vec windowSize = math::Vec(1024, 720); | |||||
| math::Vec windowPos = math::Vec(NAN, NAN); | math::Vec windowPos = math::Vec(NAN, NAN); | ||||
| bool invertZoom = false; | bool invertZoom = false; | ||||
| float pixelRatio = 0.0; | float pixelRatio = 0.0; | ||||
| std::string uiTheme = "default"; | |||||
| float cableOpacity = 0.5; | float cableOpacity = 0.5; | ||||
| float cableTension = 1.0; | float cableTension = 1.0; | ||||
| float rackBrightness = 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, "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, "cableOpacity", json_real(cableOpacity)); | ||||
| json_object_set_new(rootJ, "cableTension", json_real(cableTension)); | json_object_set_new(rootJ, "cableTension", json_real(cableTension)); | ||||
| @@ -287,6 +290,10 @@ void fromJson(json_t* rootJ) { | |||||
| if (pixelRatioJ) | if (pixelRatioJ) | ||||
| pixelRatio = json_number_value(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"); | json_t* cableOpacityJ = json_object_get(rootJ, "cableOpacity"); | ||||
| if (cableOpacityJ) | if (cableOpacityJ) | ||||
| cableOpacity = json_number_value(cableOpacityJ); | cableOpacity = json_number_value(cableOpacityJ); | ||||
| @@ -1,4 +1,5 @@ | |||||
| #include <ui/common.hpp> | #include <ui/common.hpp> | ||||
| #include <settings.hpp> | |||||
| namespace rack { | namespace rack { | ||||
| @@ -6,17 +7,14 @@ namespace ui { | |||||
| void init() { | 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 destroy() { | ||||
| } | } | ||||
| void setTheme(NVGcolor bg, NVGcolor fg) { | void setTheme(NVGcolor bg, NVGcolor fg) { | ||||
| BNDwidgetTheme w; | BNDwidgetTheme w; | ||||
| w.outlineColor = color::lerp(bg, fg, 0.1); | 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 ui | ||||
| } // namespace rack | } // namespace rack | ||||