@@ -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 |