diff --git a/lib/libimhex/include/hex/api/theme_manager.hpp b/lib/libimhex/include/hex/api/theme_manager.hpp index 2c0681cf0..84ea1bee4 100644 --- a/lib/libimhex/include/hex/api/theme_manager.hpp +++ b/lib/libimhex/include/hex/api/theme_manager.hpp @@ -67,6 +67,7 @@ namespace hex { static void reset(); + static void setAccentColor(const ImColor &color); public: struct ThemeHandler { @@ -82,6 +83,7 @@ namespace hex { static const std::map& getThemeHandlers(); static const std::map& getStyleHandlers(); + private: ThemeManager() = default; }; diff --git a/lib/libimhex/source/api/theme_manager.cpp b/lib/libimhex/source/api/theme_manager.cpp index c3a8be59f..1b030e827 100644 --- a/lib/libimhex/source/api/theme_manager.cpp +++ b/lib/libimhex/source/api/theme_manager.cpp @@ -16,6 +16,7 @@ namespace hex { AutoReset> s_styleHandlers; AutoReset s_imageTheme; AutoReset s_currTheme; + AutoReset> s_accentColor; std::recursive_mutex s_themeMutex; } @@ -155,12 +156,28 @@ namespace hex { continue; } - auto color = parseColorString(value.get()); + auto colorString = value.get(); + bool accentableColor = false; + if (colorString.starts_with("*")) { + colorString = colorString.substr(1); + accentableColor = true; + } + auto color = parseColorString(colorString); + if (!color.has_value()) { - log::warn("Invalid color '{}' for '{}.{}'", value.get(), type, key); + log::warn("Invalid color '{}' for '{}.{}'", colorString, type, key); continue; } + if (accentableColor && s_accentColor->has_value()) { + float h, s, v; + ImGui::ColorConvertRGBtoHSV(color->Value.x, color->Value.y, color->Value.z, h, s, v); + + h = s_accentColor->value(); + + ImGui::ColorConvertHSVtoRGB(h, s, v, color->Value.x, color->Value.y, color->Value.z); + } + (*s_themeHandlers)[type].setFunction((*s_themeHandlers)[type].colorMap.at(key), color.value()); } } @@ -236,6 +253,14 @@ namespace hex { s_currTheme->clear(); } + void ThemeManager::setAccentColor(const ImColor &color) { + float h, s, v; + ImGui::ColorConvertRGBtoHSV(color.Value.x, color.Value.y, color.Value.z, h, s, v); + + s_accentColor = h; + reapplyCurrentTheme(); + } + const std::map &ThemeManager::getThemeHandlers() { return s_themeHandlers; diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index ef3a738df..b2586f2e3 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -501,6 +501,7 @@ "hex.builtin.setting.interface": "Interface", "hex.builtin.setting.interface.always_show_provider_tabs": "Always show Provider Tabs", "hex.builtin.setting.interface.native_window_decorations": "Use OS Window decorations", + "hex.builtin.setting.interface.accent": "Accent color ", "hex.builtin.setting.interface.color": "Color theme", "hex.builtin.setting.interface.crisp_scaling": "Enable crisp scaling", "hex.builtin.setting.interface.display_shortcut_highlights": "Highlight menu when using shortcuts", diff --git a/plugins/builtin/romfs/themes/classic.json b/plugins/builtin/romfs/themes/classic.json index 6c7d49be7..e986fc939 100644 --- a/plugins/builtin/romfs/themes/classic.json +++ b/plugins/builtin/romfs/themes/classic.json @@ -4,23 +4,23 @@ "imgui": { "border": "#7F7F7F7F", "border-shadow": "#00000000", - "button": "#59669B9E", - "button-active": "#7589CCFF", - "button-hovered": "#667AB5C9", - "check-mark": "#E5E5E57F", + "button": "*#59669B9E", + "button-active": "*#7589CCFF", + "button-hovered": "*#667AB5C9", + "check-mark": "*#E5E5E57F", "child-background": "#00000000", "docking-empty-background": "#000000D8", - "docking-preview": "#6666E550", + "docking-preview": "*#6666E550", "drag-drop-target": "#FFFF00E5", - "frame-background": "#6D6D6D63", - "frame-background-active": "#6B68A3AF", - "frame-background-hovered": "#7777AF66", - "header": "#6666E572", - "header-active": "#8787DDCC", - "header-hovered": "#7272E5CC", + "frame-background": "*#6D6D6D63", + "frame-background-active": "*#6B68A3AF", + "frame-background-hovered": "*#7777AF66", + "header": "*#6666E572", + "header-active": "*#8787DDCC", + "header-hovered": "*#7272E5CC", "menu-bar-background": "#535371FF", "modal-window-dim-background": "#33333359", - "nav-highlight": "#7272E5CC", + "nav-highlight": "*#7272E5CC", "nav-windowing-background": "#CCCCCC33", "nav-windowing-highlight": "#FFFFFFB2", "plot-histogram": "#E5B200FF", @@ -29,22 +29,22 @@ "plot-lines-hovered": "#E5B200FF", "popup-background": "#1C1C23FF", "resize-grip": "#FFFFFF19", - "resize-grip-active": "#C6D1FFE5", - "resize-grip-hovered": "#C6D1FF99", + "resize-grip-active": "*#C6D1FFE5", + "resize-grip-hovered": "*#C6D1FF99", "scrollbar-background": "#333F4C99", "scrollbar-grab": "#6666CC4C", "scrollbar-grab-active": "#6863CC99", "scrollbar-grab-hovered": "#6666CC66", - "separator": "#7F7F7F99", - "separator-active": "#B2B2E5FF", - "separator-hovered": "#9999B2FF", + "separator": "*#7F7F7F99", + "separator-active": "*#B2B2E5FF", + "separator-hovered": "*#9999B2FF", "slider-grab": "#FFFFFF4C", - "slider-grab-active": "#6863CC99", - "tab": "#5555AEC8", - "tab-active": "#6767B9D6", - "tab-hovered": "#7272E5CC", - "tab-unfocused": "#484891D1", - "tab-unfocused-active": "#5959A6D5", + "slider-grab-active": "*#6863CC99", + "tab": "*#5555AEC8", + "tab-active": "*#6767B9D6", + "tab-hovered": "*#7272E5CC", + "tab-unfocused": "*#484891D1", + "tab-unfocused-active": "*#5959A6D5", "table-border-light": "#424247FF", "table-border-strong": "#4F4F72FF", "table-header-background": "#444460FF", @@ -52,7 +52,7 @@ "table-row-background-alt": "#FFFFFF11", "text": "#E5E5E5FF", "text-disabled": "#999999FF", - "text-selected-background": "#0000FF59", + "text-selected-background": "*#0000FF59", "title-background": "#535371FF", "title-background-active": "#535371FF", "title-background-collapse": "#535371FF", @@ -93,21 +93,21 @@ "pattern-selected": "#06539BFF" }, "imnodes": { - "box-selector": "#5252A164", - "box-selector-outline": "#5252A1FF", + "box-selector": "*#5252A164", + "box-selector-outline": "*#5252A1FF", "grid-background": "#282832C8", "grid-line": "#C8C8C828", "grid-line-primary": "#F0F0F03C", "link": "#FFFFFF64", - "link-hovered": "#6963CC99", - "link-selected": "#6963CC99", + "link-hovered": "*#6963CC99", + "link-selected": "*#6963CC99", "mini-map-background": "#19191964", "mini-map-background-hovered": "#191919C8", "mini-map-canvas": "#C8C8C819", "mini-map-canvas-outline": "#C8C8C8C8", "mini-map-link": "#FFFFFF64", - "mini-map-link-selected": "#6963CC99", - "mini-map-node-background": "#C8C8C864", + "mini-map-link-selected": "*#6963CC99", + "mini-map-node-background": "*#C8C8C864", "mini-map-node-background-hovered": "#C8C8C8FF", "mini-map-node-background-selected": "#C8C8F0FF", "mini-map-node-outline": "#C8C8C864", @@ -119,9 +119,9 @@ "node-outline": "#646464FF", "pin": "#F5CB25FF", "pin-hovered": "#FA8335FF", - "title-bar": "#45458AFF", - "title-bar-hovered": "#5252A1FF", - "title-bar-selected": "#5252A1FF" + "title-bar": "*#45458AFF", + "title-bar-hovered": "*#5252A1FF", + "title-bar-selected": "*#5252A1FF" }, "implot": { "axis-bg": "auto", @@ -166,7 +166,7 @@ "preproc-identifier": "#FF00FFFF", "preprocessor": "#008000FF", "punctuation": "#FFFFFFFF", - "selection": "#00FFFF80", + "selection": "*#00FFFF80", "string": "#008080FF" } }, diff --git a/plugins/builtin/romfs/themes/dark.json b/plugins/builtin/romfs/themes/dark.json index 637670fa2..726d11bc2 100644 --- a/plugins/builtin/romfs/themes/dark.json +++ b/plugins/builtin/romfs/themes/dark.json @@ -4,23 +4,23 @@ "imgui": { "border": "#6D6D7F7F", "border-shadow": "#00000000", - "button": "#4296F966", - "button-active": "#0F87F9FF", - "button-hovered": "#4296F9FF", - "check-mark": "#4296F9FF", + "button": "*#4296F966", + "button-active": "*#0F87F9FF", + "button-hovered": "*#4296F9FF", + "check-mark": "*#4296F9FF", "child-background": "#00000000", "docking-empty-background": "#0F0F0FEF", - "docking-preview": "#4296F9B2", + "docking-preview": "*#4296F9B2", "drag-drop-target": "#FFFF00E5", - "frame-background": "#28497A89", - "frame-background-active": "#4296F9AA", - "frame-background-hovered": "#4296F966", - "header": "#4296F94F", - "header-active": "#4296F9FF", - "header-hovered": "#4296F9CC", + "frame-background": "*#28497A89", + "frame-background-active": "*#4296F9AA", + "frame-background-hovered": "*#4296F966", + "header": "*#4296F94F", + "header-active": "*#4296F9FF", + "header-hovered": "*#4296F9CC", "menu-bar-background": "#232323FF", "modal-window-dim-background": "#CCCCCC59", - "nav-highlight": "#4296F9FF", + "nav-highlight": "*#4296F9FF", "nav-windowing-background": "#CCCCCC33", "nav-windowing-highlight": "#FFFFFFB2", "plot-histogram": "#E5B200FF", @@ -28,23 +28,23 @@ "plot-lines": "#9B9B9BFF", "plot-lines-hovered": "#FF6D59FF", "popup-background": "#141414FF", - "resize-grip": "#4296F933", - "resize-grip-active": "#4296F9F2", - "resize-grip-hovered": "#4296F9AA", + "resize-grip": "*#4296F933", + "resize-grip-active": "*#4296F9F2", + "resize-grip-hovered": "*#4296F9AA", "scrollbar-background": "#05050587", "scrollbar-grab": "#4F4F4FFF", "scrollbar-grab-active": "#828282FF", "scrollbar-grab-hovered": "#686868FF", "separator": "#6D6D7F7F", - "separator-active": "#1966BFFF", - "separator-hovered": "#1966BFC6", - "slider-grab": "#3D84E0FF", - "slider-grab-active": "#4296F9FF", - "tab": "#2D5993DB", - "tab-active": "#3268ADFF", - "tab-hovered": "#4296F9CC", - "tab-unfocused": "#111A25F7", - "tab-unfocused-active": "#22426CFF", + "separator-active": "*#1966BFFF", + "separator-hovered": "*#1966BFC6", + "slider-grab": "*#3D84E0FF", + "slider-grab-active": "*#4296F9FF", + "tab": "*#2D5993DB", + "tab-active": "*#3268ADFF", + "tab-hovered": "*#4296F9CC", + "tab-unfocused": "*#111A25F7", + "tab-unfocused-active": "*#22426CFF", "table-border-light": "#3A3A3FFF", "table-border-strong": "#4F4F59FF", "table-header-background": "#303033FF", @@ -52,7 +52,7 @@ "table-row-background-alt": "#FFFFFF0F", "text": "#FFFFFFFF", "text-disabled": "#7F7F7FFF", - "text-selected-background": "#4296F959", + "text-selected-background": "*#4296F959", "title-background": "#232323FF", "title-background-active": "#232323FF", "title-background-collapse": "#232323FF", @@ -93,20 +93,20 @@ "pattern-selected": "#3683CBFF" }, "imnodes": { - "box-selector": "#3D85E01E", - "box-selector-outline": "#3D85E096", + "box-selector": "*#3D85E01E", + "box-selector-outline": "*#3D85E096", "grid-background": "#282832C8", "grid-line": "#C8C8C828", "grid-line-primary": "#F0F0F03C", - "link": "#3D85E0C8", - "link-hovered": "#4296FAFF", - "link-selected": "#4296FAFF", + "link": "*#3D85E0C8", + "link-hovered": "*#4296FAFF", + "link-selected": "*#4296FAFF", "mini-map-background": "#19191996", "mini-map-background-hovered": "#191919C8", "mini-map-canvas": "#C8C8C819", "mini-map-canvas-outline": "#C8C8C8C8", - "mini-map-link": "#3D85E0C8", - "mini-map-link-selected": "#4296FAFF", + "mini-map-link": "*#3D85E0C8", + "mini-map-link-selected": "*#4296FAFF", "mini-map-node-background": "#C8C8C864", "mini-map-node-background-hovered": "#C8C8C8FF", "mini-map-node-background-selected": "#C8C8C8FF", @@ -119,9 +119,9 @@ "node-outline": "#646464FF", "pin": "#F5CB25FF", "pin-hovered": "#FA8335FF", - "title-bar": "#294A7AFF", - "title-bar-hovered": "#4296FAFF", - "title-bar-selected": "#4296FAFF" + "title-bar": "*#294A7AFF", + "title-bar-hovered": "*#4296FAFF", + "title-bar-selected": "*#4296FAFF" }, "implot": { "axis-bg": "auto", @@ -166,7 +166,7 @@ "preproc-identifier": "#A040C0FF", "preprocessor": "#808040FF", "punctuation": "#FFFFFFFF", - "selection": "#2060A080", + "selection": "*#2060A080", "string": "#E07070FF" } }, diff --git a/plugins/builtin/romfs/themes/light.json b/plugins/builtin/romfs/themes/light.json index 40965e8be..250350855 100644 --- a/plugins/builtin/romfs/themes/light.json +++ b/plugins/builtin/romfs/themes/light.json @@ -4,23 +4,23 @@ "imgui": { "border": "#0000004C", "border-shadow": "#00000000", - "button": "#4296F966", - "button-active": "#0F87F9FF", - "button-hovered": "#4296F9FF", - "check-mark": "#4296F9FF", + "button": "*#4296F966", + "button-active": "*#0F87F9FF", + "button-hovered": "*#4296F9FF", + "check-mark": "*#4296F9FF", "child-background": "#00000000", "docking-empty-background": "#EFEFEFFF", - "docking-preview": "#4296F937", + "docking-preview": "*#4296F937", "drag-drop-target": "#4296F9F2", "frame-background": "#FFFFFFFF", - "frame-background-active": "#4296F9AA", - "frame-background-hovered": "#4296F966", - "header": "#4296F94F", - "header-active": "#4296F9FF", - "header-hovered": "#4296F9CC", + "frame-background-active": "*#4296F9AA", + "frame-background-hovered": "*#4296F966", + "header": "*#4296F94F", + "header-active": "*#4296F9FF", + "header-hovered": "*#4296F9CC", "menu-bar-background": "#DBDBDBFF", "modal-window-dim-background": "#33333359", - "nav-highlight": "#4296F9CC", + "nav-highlight": "*#4296F9CC", "nav-windowing-background": "#33333333", "nav-windowing-highlight": "#B2B2B2B2", "plot-histogram": "#E5B200FF", @@ -28,23 +28,23 @@ "plot-lines": "#636363FF", "plot-lines-hovered": "#FF6D59FF", "popup-background": "#FFFFFFFF", - "resize-grip": "#5959592B", - "resize-grip-active": "#4296F9F2", - "resize-grip-hovered": "#4296F9AA", + "resize-grip": "*#5959592B", + "resize-grip-active": "*#4296F9F2", + "resize-grip-hovered": "*#4296F9AA", "scrollbar-background": "#F9F9F987", "scrollbar-grab": "#AFAFAFCC", "scrollbar-grab-active": "#7C7C7CFF", "scrollbar-grab-hovered": "#7C7C7CCC", - "separator": "#6363639E", - "separator-active": "#2370CCFF", - "separator-hovered": "#2370CCC6", - "slider-grab": "#4296F9C6", - "slider-grab-active": "#7589CC99", - "tab": "#C2CBD5ED", - "tab-active": "#97B9E1FF", - "tab-hovered": "#4296F9CC", - "tab-unfocused": "#EAECEEFB", - "tab-unfocused-active": "#BDD1E9FF", + "separator": "*#6363639E", + "separator-active": "*#2370CCFF", + "separator-hovered": "*#2370CCC6", + "slider-grab": "*#4296F9C6", + "slider-grab-active": "*#7589CC99", + "tab": "*#C2CBD5ED", + "tab-active": "*#97B9E1FF", + "tab-hovered": "*#4296F9CC", + "tab-unfocused": "*#EAECEEFB", + "tab-unfocused-active": "*#BDD1E9FF", "table-border-light": "#ADADBCFF", "table-border-strong": "#9191A3FF", "table-header-background": "#C6DDF9FF", @@ -52,7 +52,7 @@ "table-row-background-alt": "#4C4C4C16", "text": "#000000FF", "text-disabled": "#999999FF", - "text-selected-background": "#4296F959", + "text-selected-background": "*#4296F959", "title-background": "#DBDBDBFF", "title-background-active": "#DBDBDBFF", "title-background-collapse": "#DBDBDBFF", @@ -93,20 +93,20 @@ "pattern-selected": "#06539BFF" }, "imnodes": { - "box-selector": "#5AAAFA1E", - "box-selector-outline": "#5AAAFA96", + "box-selector": "*#5AAAFA1E", + "box-selector-outline": "*#5AAAFA96", "grid-background": "#E1E1E1FF", "grid-line": "#B4B4B464", "grid-line-primary": "#78787864", - "link": "#4296FA64", - "link-hovered": "#4296FAF2", - "link-selected": "#4296FAF2", + "link": "*#4296FA64", + "link-hovered": "*#4296FAF2", + "link-selected": "*#4296FAF2", "mini-map-background": "#19191964", "mini-map-background-hovered": "#191919C8", "mini-map-canvas": "#C8C8C819", "mini-map-canvas-outline": "#C8C8C8C8", - "mini-map-link": "#4296FA64", - "mini-map-link-selected": "#4296FAF2", + "mini-map-link": "*#4296FA64", + "mini-map-link-selected": "*#4296FAF2", "mini-map-node-background": "#C8C8C864", "mini-map-node-background-hovered": "#C8C8C8FF", "mini-map-node-background-selected": "#C8C8F0FF", @@ -166,7 +166,7 @@ "preproc-identifier": "#A040C0FF", "preprocessor": "#606040FF", "punctuation": "#000000FF", - "selection": "#00006080", + "selection": "*#00006080", "string": "#A02020FF" } }, diff --git a/plugins/builtin/source/content/settings_entries.cpp b/plugins/builtin/source/content/settings_entries.cpp index a96cd942d..12b09cddf 100644 --- a/plugins/builtin/source/content/settings_entries.cpp +++ b/plugins/builtin/source/content/settings_entries.cpp @@ -789,6 +789,12 @@ namespace hex::plugin::builtin { } }); + ContentRegistry::Settings::add("hex.builtin.setting.interface", "hex.builtin.setting.interface.style", "hex.builtin.setting.interface.accent", ImGui::GetStyleColorVec4(ImGuiCol_Button)) + .setChangedCallback([](auto &widget) { + auto colorPicker = static_cast(&widget); + ThemeManager::setAccentColor(colorPicker->getColor()); + }); + ContentRegistry::Settings::add("hex.builtin.setting.interface", "hex.builtin.setting.interface.style", "hex.builtin.setting.interface.scaling_factor") .requiresRestart();