From 71dfde0270045d9d638a37764401b7bca1ebc717 Mon Sep 17 00:00:00 2001 From: thecozies <79979276+thecozies@users.noreply.github.com> Date: Sun, 6 Jul 2025 13:56:28 -0500 Subject: [PATCH] Refactor color usage for full theming support from one source of truth (#1) * Refactor color usage for full theming support from one source of truth * remove unused components * remove old commented out font families * override custom theme in main.cpp --- CMakeLists.txt | 2 + assets/Suplexmentary Comic NC.ttf | Bin 0 -> 118452 bytes assets/components/prompt.rml | 30 - assets/config_menu.rml | 1 - assets/config_menu/controls.rml | 4 +- assets/recomp.rcss | 531 +++++++++--------- assets/scss/styles/components/Button.scss | 28 +- .../scss/styles/components/ControlOption.scss | 8 +- assets/scss/styles/components/IconButton.scss | 28 +- .../scss/styles/components/InputConfig.scss | 2 +- .../scss/styles/components/MenuListItem.scss | 6 +- assets/scss/styles/global.scss | 14 +- assets/scss/styles/globals/_old.scss | 1 - assets/scss/styles/mixins/_typography.scss | 2 +- assets/scss/styles/vars/_colors.scss | 150 ++--- assets/scss/styles/vars/_gradients.scss | 6 +- include/recomp_ui.h | 18 +- src/main/main.cpp | 2 + src/main/theme.cpp | 88 +++ src/main/theme.h | 6 + src/ui/elements/ui_button.cpp | 109 ++-- src/ui/elements/ui_button.h | 11 +- src/ui/elements/ui_label.cpp | 4 +- src/ui/elements/ui_radio.cpp | 12 +- src/ui/elements/ui_slider.cpp | 12 +- src/ui/elements/ui_style.cpp | 39 +- src/ui/elements/ui_style.h | 12 +- src/ui/elements/ui_text_input.cpp | 2 +- src/ui/elements/ui_theme.cpp | 207 +++++++ src/ui/elements/ui_theme.h | 95 ++++ src/ui/elements/ui_toggle.cpp | 36 +- src/ui/elements/ui_types.h | 4 +- src/ui/ui_color_hack.cpp | 9 + src/ui/ui_config.cpp | 8 +- src/ui/ui_mod_details_panel.cpp | 12 +- src/ui/ui_mod_menu.cpp | 33 +- src/ui/ui_prompt.cpp | 100 +--- src/ui/ui_state.cpp | 9 +- src/ui/ui_utils.cpp | 7 +- 39 files changed, 1018 insertions(+), 630 deletions(-) create mode 100644 assets/Suplexmentary Comic NC.ttf delete mode 100644 assets/components/prompt.rml create mode 100644 src/main/theme.cpp create mode 100644 src/main/theme.h create mode 100644 src/ui/elements/ui_theme.cpp create mode 100644 src/ui/elements/ui_theme.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 921cb3a..e0ab362 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,6 +153,7 @@ set (SOURCES ${CMAKE_SOURCE_DIR}/src/main/register_overlays.cpp ${CMAKE_SOURCE_DIR}/src/main/register_patches.cpp ${CMAKE_SOURCE_DIR}/src/main/rt64_render_context.cpp + ${CMAKE_SOURCE_DIR}/src/main/theme.cpp ${CMAKE_SOURCE_DIR}/src/game/input.cpp ${CMAKE_SOURCE_DIR}/src/game/controls.cpp @@ -193,6 +194,7 @@ set (SOURCES ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_span.cpp ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_style.cpp ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_text_input.cpp + ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_theme.cpp ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_toggle.cpp ${CMAKE_SOURCE_DIR}/rsp/n_aspMain.cpp diff --git a/assets/Suplexmentary Comic NC.ttf b/assets/Suplexmentary Comic NC.ttf new file mode 100644 index 0000000000000000000000000000000000000000..65b1e6fe4f800389760d2c20a6eaa76c8a4babd1 GIT binary patch literal 118452 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%0A&@$Sfsv_+$&*1Jma-HXv>3EOVFoI-AZvXg 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 - - - -
-
-
-

{{ promptHeader }}

-

{{ promptContent }}

-
- - -
-
-
- - diff --git a/assets/config_menu.rml b/assets/config_menu.rml index 0666d77..8d582dc 100644 --- a/assets/config_menu.rml +++ b/assets/config_menu.rml @@ -29,7 +29,6 @@ - diff --git a/assets/config_menu/controls.rml b/assets/config_menu/controls.rml index d947ae8..3a8371e 100644 --- a/assets/config_menu/controls.rml +++ b/assets/config_menu/controls.rml @@ -71,7 +71,7 @@ data-event-blur="set_input_row_focus(-1)" data-event-focus="set_input_row_focus(i)" data-event-click="clear_input_bindings(i)" - class="icon-button icon-button--error" + class="icon-button icon-button--danger" data-attr-style="i == 0 ? 'nav-up:#cont_kb_toggle' : 'nav-up:auto'" > @@ -81,7 +81,7 @@ data-event-blur="set_input_row_focus(-1)" data-event-focus="set_input_row_focus(i)" data-event-click="reset_single_input_binding_to_default(i)" - class="icon-button icon-button--error" + class="icon-button icon-button--danger" data-attr-style="i == 0 ? 'nav-up:#cont_kb_toggle' : 'nav-up:auto'" > diff --git a/assets/recomp.rcss b/assets/recomp.rcss index eed389c..488f346 100644 --- a/assets/recomp.rcss +++ b/assets/recomp.rcss @@ -57,7 +57,7 @@ h3, .tab { font-weight: 400; } -body, .config-debug__select-wrapper select, .config-debug__select-wrapper input, .config-description__contents, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config__wrapper p { +.config-debug__select-wrapper select, .config-debug__select-wrapper input, .config-description__contents, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config__wrapper p, body { font-size: 20dp; letter-spacing: 0dp; line-height: 20dp; @@ -184,7 +184,7 @@ h3, .tab { font-weight: 400; } -body, .config-debug__select-wrapper select, .config-debug__select-wrapper input, .config-description__contents, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config__wrapper p { +.config-debug__select-wrapper select, .config-debug__select-wrapper input, .config-description__contents, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config__wrapper p, body { font-size: 20dp; letter-spacing: 0dp; line-height: 20dp; @@ -252,6 +252,12 @@ body, .config-debug__select-wrapper select, .config-debug__select-wrapper input, /* @include set-color(COLOR); */ +body { + box-sizing: border-box; + color: Text; + font-family: "Suplexmentary Comic NC"; +} + /* stylelint-disable color-no-hex */ /* stylelint-disable selector-max-id */ * { @@ -261,12 +267,11 @@ body, .config-debug__select-wrapper select, .config-debug__select-wrapper input, hr { display: block; padding: 1.5dp; - background: #08070D; + background: Background1; } body { color: #fff; - font-family: LatoLatin; font-size: 20dp; font-style: normal; font-weight: normal; @@ -281,8 +286,8 @@ div#window { box-sizing: border-box; width: 100%; height: 100%; - border-color: rgba(255, 255, 255, 0.2); - background-color: #121018; + border-color: Border; + background-color: Background2; } div#content { @@ -368,12 +373,12 @@ scrollbarvertical, scrollbarhorizontal { border: 0; } scrollbarvertical slidertrack, scrollbarhorizontal slidertrack { - background: #DABAF7; + background: PrimaryL; opacity: 0.05; } scrollbarvertical sliderbar, scrollbarhorizontal sliderbar { border-radius: 5dp; - background: #DABAF7; + background: PrimaryL; opacity: 0.1; } scrollbarvertical sliderbar:hover:not(:active), scrollbarhorizontal sliderbar:hover:not(:active) { @@ -415,7 +420,7 @@ scrollbarhorizontal sliderbar { bottom: 0; left: 0; padding: 64dp; - background-color: rgba(255, 255, 255, 0.1); + background-color: BorderSoft; } .centered-page__modal { @@ -429,8 +434,8 @@ scrollbarhorizontal sliderbar { margin: auto; border-width: 1.1dp; border-radius: 16dp; - border-color: rgba(255, 255, 255, 0.2); - background: rgba(8, 7, 13, 0.9); + border-color: Border; + background: ModalOverlay; } .centered-page__modal > .tabs { display: flex; @@ -473,7 +478,7 @@ scrollbarhorizontal sliderbar { } .control-option { - color: #CCCCCC; + color: TextDim; transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out; display: flex; position: relative; @@ -487,23 +492,23 @@ scrollbarhorizontal sliderbar { background-color: rgba(0, 0, 0, 0); } .control-option svg { - image-color: #CCCCCC; + image-color: TextDim; } .control-option svg { transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out; } .control-option:focus-visible:not(:disabled, [disabled]), .control-option:hover:not(:disabled, [disabled]) { - color: #F2F2F2; - background-color: rgba(190, 184, 219, 0.1); + color: Text; + background-color: BGOverlay; } .control-option:focus-visible:not(:disabled, [disabled]) svg, .control-option:hover:not(:disabled, [disabled]) svg { - image-color: #F2F2F2; + image-color: Text; } .control-option:disabled, .control-option[disabled] { opacity: 0.5; } [cur-binding-slot="0"] .control-option--active .control-option__binding[bind-slot="0"] { - border-color: #F86039; + border-color: Danger; } [cur-binding-slot="0"] .control-option--active .control-option__binding[bind-slot="0"] .control-option__binding-icon { opacity: 0; @@ -512,7 +517,7 @@ scrollbarhorizontal sliderbar { opacity: 1; } [cur-binding-slot="1"] .control-option--active .control-option__binding[bind-slot="1"] { - border-color: #F86039; + border-color: Danger; } [cur-binding-slot="1"] .control-option--active .control-option__binding[bind-slot="1"] .control-option__binding-icon { opacity: 0; @@ -543,7 +548,7 @@ scrollbarhorizontal sliderbar { } .control-option__binding { - color: #CCCCCC; + color: TextDim; transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out, border-color 0.05s linear-in-out; display: flex; position: relative; @@ -556,35 +561,35 @@ scrollbarhorizontal sliderbar { padding: 8dp; border-width: 1.1dp; border-radius: 8dp; - border-color: rgba(190, 184, 219, 0.1); - background-color: rgba(190, 184, 219, 0.1); + border-color: BGOverlay; + background-color: BGOverlay; } .control-option__binding svg { - image-color: #CCCCCC; + image-color: TextDim; } .control-option__binding svg { transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out; } .control-option__binding:focus, .control-option__binding:hover { - color: #F2F2F2; - border-color: #F2F2F2; - background-color: rgba(255, 255, 255, 0.1); + color: Text; + border-color: Text; + background-color: BorderSoft; } .control-option__binding:focus svg, .control-option__binding:hover svg { - image-color: #F2F2F2; + image-color: Text; } .control-option__binding:active { - color: rgb(244.6, 244.6, 244.6); + color: TextActive; } .control-option__binding:active svg { - image-color: rgb(244.6, 244.6, 244.6); + image-color: TextActive; } .control-option__binding:disabled, .control-option__binding[disabled] { - color: #CCCCCC; + color: TextDim; opacity: 0.5; } .control-option__binding:disabled svg, .control-option__binding[disabled] svg { - image-color: #CCCCCC; + image-color: TextDim; } .control-option__binding:not([disabled]) { cursor: pointer; @@ -623,7 +628,7 @@ scrollbarhorizontal sliderbar { height: 24dp; animation: 1.5s sine-in-out infinite control-option__binding-recording-scale; border-radius: 24dp; - background-color: #F86039; + background-color: Danger; } .control-option__binding-recording .control-option__binding-edge { position: absolute; @@ -636,7 +641,7 @@ scrollbarhorizontal sliderbar { .control-option__binding-recording .control-option__binding-edge > svg.control-option__binding-edge-svg { width: 36dp; height: 36dp; - image-color: #F86039; + image-color: Danger; } /* @@ -661,13 +666,13 @@ scrollbarhorizontal sliderbar { transition: color 0.05s linear-in-out; opacity: 0.9; background-color: rgba(0, 0, 0, 0); - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .tab:selected { - color: #F2F2F2; + color: Text; } .tab:selected .tab__indicator { - background-color: rgba(255, 255, 255, 0.6); + background-color: BorderSolid; } .tab:selected:hover { cursor: default; @@ -681,7 +686,7 @@ scrollbarhorizontal sliderbar { } .tab:focus, .tab:hover { opacity: 1; - color: #F2F2F2; + color: Text; cursor: pointer; } @@ -710,7 +715,7 @@ scrollbarhorizontal sliderbar { .config__form { border-top-width: 1.1dp; - border-top-color: rgba(255, 255, 255, 0.1); + border-top-color: BorderSoft; display: flex; flex: 1 1 100%; flex-direction: column; @@ -729,7 +734,7 @@ scrollbarhorizontal sliderbar { border-radius: 0dp; border-bottom-right-radius: 16dp; border-bottom-left-radius: 16dp; - background-color: rgba(0, 0, 0, 0.35); + background-color: BGShadow; text-align: left; } .config__wrapper p { @@ -738,10 +743,10 @@ scrollbarhorizontal sliderbar { white-space: pre-line; } .config__wrapper p b { - color: #B97DF2; + color: Primary; } .config__wrapper p i { - color: #E9CD35; + color: Warning; font-style: normal; } @@ -760,18 +765,18 @@ scrollbarhorizontal sliderbar { align-items: center; justify-content: space-between; width: 100%; - background-color: rgba(0, 0, 0, 0.35); + background-color: BGShadow; } .config__header { border-bottom-width: 1.1dp; - border-bottom-color: rgba(255, 255, 255, 0.1); + border-bottom-color: BorderSoft; padding: 12dp 20dp; } .config__footer { border-top-width: 1.1dp; - border-top-color: rgba(255, 255, 255, 0.1); + border-top-color: BorderSoft; padding: 20dp 20dp; border-bottom-right-radius: 16dp; border-bottom-left-radius: 16dp; @@ -805,7 +810,7 @@ scrollbarhorizontal sliderbar { overflow-y: auto; } .config-group__title { - color: #B97DF2; + color: Primary; } .config-group__title--hidden { display: none; @@ -872,12 +877,12 @@ scrollbarhorizontal sliderbar { height: auto; margin: 4dp 12dp 0; padding: 8dp 0; - color: rgba(255, 255, 255, 0.6); + color: TextInactive; tab-index: none; } .config-option__radio-tabs .config-option__tab-label:hover, .config-option__list .config-option__tab-label:hover { - color: #F2F2F2; + color: Text; cursor: pointer; } .config-option__radio-tabs .config-option__checkbox-wrapper, @@ -888,7 +893,7 @@ scrollbarhorizontal sliderbar { margin: 4dp 12dp 0; border-radius: 8dp; opacity: 0.5; - background-color: rgba(190, 184, 219, 0.1); + background-color: BGOverlay; cursor: pointer; } .config-option__radio-tabs .config-option__checkbox-wrapper:hover, @@ -897,7 +902,7 @@ scrollbarhorizontal sliderbar { } .config-option__radio-tabs .config-option__checkbox-wrapper[checked], .config-option__list .config-option__checkbox-wrapper[checked] { - background-color: #3333FF; + background-color: A; } .config-option__radio-tabs .config-option__checkbox, .config-option__list .config-option__checkbox { @@ -916,8 +921,8 @@ scrollbarhorizontal sliderbar { .config-option__radio-tabs input.radio:not(:disabled):checked + .config-option__tab-label, .config-option__list input.radio:not(:disabled):checked + .config-option__tab-label { border-bottom: 1dp; - border-color: #F2F2F2; - color: #F2F2F2; + border-color: Text; + color: Text; } .config-option__radio-tabs input.radio:not(:disabled):checked + .config-option__tab-label:hover, .config-option__list input.radio:not(:disabled):checked + .config-option__tab-label:hover { @@ -927,13 +932,13 @@ scrollbarhorizontal sliderbar { .rmlui-window:not([mouse-active]) .config-option__list input.radio:not(:disabled):focus + .config-option__tab-label { transition: none; animation: blue-pulse 0.75s infinite; - border-color: #17D6E8; - color: #17D6E8; + border-color: Secondary; + color: Secondary; } .config-option__radio-tabs input.radio:not(:disabled):focus + .config-option__tab-label, .config-option__radio-tabs input.radio:not(:disabled):hover + .config-option__tab-label, .config-option__list input.radio:not(:disabled):focus + .config-option__tab-label, .config-option__list input.radio:not(:disabled):hover + .config-option__tab-label { - color: #F2F2F2; + color: Text; } .config-option__radio-tabs input.radio:disabled + .config-option__tab-label, .config-option__list input.radio:disabled + .config-option__tab-label { @@ -948,7 +953,7 @@ scrollbarhorizontal sliderbar { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; height: 2dp; margin-top: 8dp; - background-color: rgba(255, 255, 255, 0.2); + background-color: Border; } .config-option__radio-tabs input.range sliderbar, .config-option__list input.range sliderbar { @@ -960,24 +965,24 @@ scrollbarhorizontal sliderbar { margin-left: -8dp; transition: background-color 0.05s linear-in-out; border-radius: 8dp; - background-color: #CCCCCC; + background-color: TextDim; } .rmlui-window:not([mouse-active]) .config-option__radio-tabs input.range sliderbar:focus, .rmlui-window:not([mouse-active]) .config-option__list input.range sliderbar:focus { border-width: 1.1dp; - border-color: #3333FF; + border-color: A; animation: blue-pulse-background 0.75s infinite; } .config-option__radio-tabs input.range sliderbar:hover, .config-option__list input.range sliderbar:hover { - background-color: #F2F2F2; + background-color: Text; cursor: pointer; } .config-option__radio-tabs input.range sliderbar:active, .config-option__radio-tabs input.range slidertrack:active + sliderbar, .config-option__list input.range sliderbar:active, .config-option__list input.range slidertrack:active + sliderbar { - background-color: #17D6E8; + background-color: Secondary; } .config-option__radio-tabs input.range sliderarrowdec, .config-option__radio-tabs input.range sliderarrowinc, @@ -989,7 +994,7 @@ scrollbarhorizontal sliderbar { .config-option__details { height: 18dp; margin: 14dp 12dp 0; - color: #B97DF2; + color: Primary; } .config-option-color { @@ -1012,7 +1017,7 @@ scrollbarhorizontal sliderbar { height: 100%; border-width: 1.1dp; border-radius: 16dp; - border-color: rgba(255, 255, 255, 0.2); + border-color: Border; } .config-option-color__hsv-wrapper { display: flex; @@ -1049,7 +1054,7 @@ scrollbarhorizontal sliderbar { margin: 0 12dp; margin-right: 16dp; padding: 0; - color: #F2F2F2; + color: Text; tab-index: none; } .config-option-range__range-input { @@ -1059,7 +1064,7 @@ scrollbarhorizontal sliderbar { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; height: 2dp; margin-top: 8dp; - background-color: rgba(255, 255, 255, 0.2); + background-color: Border; } .config-option-range__range-input sliderbar { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; @@ -1070,20 +1075,20 @@ scrollbarhorizontal sliderbar { margin-left: -8dp; transition: background-color 0.05s linear-in-out; border-radius: 8dp; - background-color: #CCCCCC; + background-color: TextDim; } .rmlui-window:not([mouse-active]) .config-option-range__range-input sliderbar:focus { border-width: 1.1dp; - border-color: #3333FF; + border-color: A; animation: blue-pulse-background 0.75s infinite; } .config-option-range__range-input sliderbar:hover { - background-color: #F2F2F2; + background-color: Text; cursor: pointer; } .config-option-range__range-input sliderbar:active, .config-option-range__range-input slidertrack:active + sliderbar { - background-color: #17D6E8; + background-color: Secondary; } .config-option-range__range-input sliderarrowdec, .config-option-range__range-input sliderarrowinc { @@ -1101,7 +1106,7 @@ scrollbarhorizontal sliderbar { margin: 0 12dp; margin-right: 16dp; padding: 0; - color: #F2F2F2; + color: Text; tab-index: none; } @@ -1139,21 +1144,21 @@ scrollbarhorizontal sliderbar { .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out, border-color 0.05s linear-in-out; border-width: 1.1dp; - border-color: rgba(255, 255, 255, 0.5); + border-color: WhiteA50; position: relative; box-sizing: border-box; flex: 1 1 100%; width: auto; border-radius: 12dp; - background-color: rgba(255, 255, 255, 0.05); + background-color: WhiteA5; } .config-option-dropdown__select svg, .config-option-dropdown__wrapper svg, .config-option-textfield__select svg, .config-option-textfield__wrapper svg { transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out; } .config-option-dropdown__select:hover, .config-option-dropdown__select:focus, .config-option-dropdown__wrapper:hover, .config-option-dropdown__wrapper:focus, .config-option-textfield__select:hover, .config-option-textfield__select:focus, .config-option-textfield__wrapper:hover, .config-option-textfield__wrapper:focus { border-width: 1.1dp; - border-color: rgba(255, 255, 255, 0.8); - background-color: rgba(255, 255, 255, 0.2); + border-color: WhiteA80; + background-color: WhiteA20; } .config-option-dropdown__select selectvalue, .config-option-dropdown__wrapper selectvalue, .config-option-textfield__select selectvalue, .config-option-textfield__wrapper selectvalue { display: inline; @@ -1162,28 +1167,28 @@ scrollbarhorizontal sliderbar { } .config-option-dropdown__select selectbox, .config-option-dropdown__wrapper selectbox, .config-option-textfield__select selectbox, .config-option-textfield__wrapper selectbox { border-width: 1.1dp; - border-color: rgba(255, 255, 255, 0.2); + border-color: Border; margin-top: 2dp; padding: 4dp 0; border-radius: 12dp; - background-color: #191622; + background-color: Background3; } .config-option-dropdown__select selectbox option, .config-option-dropdown__wrapper selectbox option, .config-option-textfield__select selectbox option, .config-option-textfield__wrapper selectbox option { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; padding: 8dp 12dp; - background-color: rgba(0, 0, 0, 0); - color: #CCCCCC; + background-color: Transparent; + color: TextDim; font-weight: 400; } .config-option-dropdown__select selectbox option:hover, .config-option-dropdown__select selectbox option:focus, .config-option-dropdown__wrapper selectbox option:hover, .config-option-dropdown__wrapper selectbox option:focus, .config-option-textfield__select selectbox option:hover, .config-option-textfield__select selectbox option:focus, .config-option-textfield__wrapper selectbox option:hover, .config-option-textfield__wrapper selectbox option:focus { - background-color: rgba(255, 255, 255, 0.2); + background-color: WhiteA20; } .config-option-dropdown__select selectbox option:hover:not(:checked), .config-option-dropdown__wrapper selectbox option:hover:not(:checked), .config-option-textfield__select selectbox option:hover:not(:checked), .config-option-textfield__wrapper selectbox option:hover:not(:checked) { cursor: pointer; } .config-option-dropdown__select selectbox option:checked, .config-option-dropdown__wrapper selectbox option:checked, .config-option-textfield__select selectbox option:checked, .config-option-textfield__wrapper selectbox option:checked { - background-color: rgba(255, 255, 255, 0.05); - color: #FFFFFF; + background-color: WhiteA5; + color: White; } .config-description { @@ -1194,7 +1199,7 @@ scrollbarhorizontal sliderbar { border-radius: 0dp; border-bottom-right-radius: 16dp; border-bottom-left-radius: 16dp; - background-color: rgba(0, 0, 0, 0.35); + background-color: BGShadow; text-align: left; } .config-description__contents { @@ -1203,10 +1208,10 @@ scrollbarhorizontal sliderbar { white-space: pre-line; } .config-description__contents b { - color: #B97DF2; + color: Primary; } .config-description__contents i { - color: #E9CD35; + color: Warning; font-style: normal; } @@ -1254,7 +1259,7 @@ scrollbarhorizontal sliderbar { width: 100%; margin: auto 0; padding-bottom: 75%; - background-color: rgba(0, 0, 0, 0.35); + background-color: BGShadow; } .input-config__visual { @@ -1266,7 +1271,7 @@ scrollbarhorizontal sliderbar { left: 16dp; flex-direction: column; border-radius: 108dp; - background-color: rgba(255, 255, 255, 0.05); + background-color: WhiteA5; } .input-config__visual-half { @@ -1452,10 +1457,10 @@ scrollbarhorizontal sliderbar { } .input-viz__button { - color: #F2F2F2; + color: Text; } .input-viz__button svg { - image-color: #F2F2F2; + image-color: Text; } .input-viz__button--sm { width: 64dp; @@ -1482,19 +1487,19 @@ scrollbarhorizontal sliderbar { height: 84dp; } .input-viz__button--C svg { - image-color: #E9CD35; + image-color: Warning; } .input-viz__button--A { margin-top: auto; } .input-viz__button--A svg { - image-color: #3333FF; + image-color: A; } .input-viz__button--B svg { - image-color: #45D043; + image-color: Success; } .input-viz__button--Start svg { - image-color: #F86039; + image-color: Danger; } .input-viz__Z { @@ -1502,7 +1507,7 @@ scrollbarhorizontal sliderbar { height: 136dp; } .input-viz__Z svg { - image-color: #E9CD35; + image-color: Warning; } .input-viz__Z > svg { width: 136dp; @@ -1515,7 +1520,7 @@ scrollbarhorizontal sliderbar { position: relative; } .input-viz.input-viz__dpad svg { - image-color: #F2F2F2; + image-color: Text; } .input-viz.input-viz__dpad > svg { width: 192dp; @@ -1530,7 +1535,7 @@ scrollbarhorizontal sliderbar { width: 200dp; height: 200dp; border-radius: 100dp; - background-color: rgba(255, 255, 255, 0.05); + background-color: WhiteA5; } .input-viz__dpad-split, @@ -1605,7 +1610,7 @@ scrollbarhorizontal sliderbar { height: 96dp; } .input-viz__R svg { - image-color: #FFFFFF; + image-color: White; } .input-viz__R > svg { width: 96dp; @@ -1617,7 +1622,7 @@ scrollbarhorizontal sliderbar { height: 136dp; } .input-viz__L svg { - image-color: #17D6E8; + image-color: Secondary; } .input-viz__L > svg { width: 136dp; @@ -1662,9 +1667,9 @@ scrollbarhorizontal sliderbar { } .button { - border-color: rgba(185, 125, 242, 0.8); - background-color: rgba(185, 125, 242, 0.05); - color: #CCCCCC; + border-color: PrimaryA80; + background-color: PrimaryA5; + color: TextDim; transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; display: block; width: auto; @@ -1674,118 +1679,118 @@ scrollbarhorizontal sliderbar { border-radius: 12dp; } .button:focus, .button:hover { - border-color: #B97DF2; - background-color: rgba(185, 125, 242, 0.3); - color: #F2F2F2; + border-color: Primary; + background-color: PrimaryA30; + color: Text; } .button:disabled, .button[disabled] { - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .button:active { - background-color: rgba(185, 125, 242, 0.2); - color: rgb(244.6, 244.6, 244.6); + background-color: PrimaryA20; + color: TextActive; } .button--primary { - border-color: rgba(185, 125, 242, 0.8); - background-color: rgba(185, 125, 242, 0.05); - color: #CCCCCC; + border-color: PrimaryA80; + background-color: PrimaryA5; + color: TextDim; } .button--primary:focus, .button--primary:hover { - border-color: #B97DF2; - background-color: rgba(185, 125, 242, 0.3); - color: #F2F2F2; + border-color: Primary; + background-color: PrimaryA30; + color: Text; } .button--primary:disabled, .button--primary[disabled] { - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .button--primary:active { - background-color: rgba(185, 125, 242, 0.2); - color: rgb(244.6, 244.6, 244.6); + background-color: PrimaryA20; + color: TextActive; } .button--secondary { - border-color: rgba(23, 214, 232, 0.8); - background-color: rgba(23, 214, 232, 0.05); - color: #CCCCCC; + border-color: SecondaryA80; + background-color: SecondaryA5; + color: TextDim; } .button--secondary:focus, .button--secondary:hover { - border-color: #17D6E8; - background-color: rgba(23, 214, 232, 0.3); - color: #F2F2F2; + border-color: Secondary; + background-color: SecondaryA30; + color: Text; } .button--secondary:disabled, .button--secondary[disabled] { - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .button--secondary:active { - background-color: rgba(23, 214, 232, 0.2); - color: rgb(244.6, 244.6, 244.6); + background-color: SecondaryA20; + color: TextActive; } .button--tertiary { - border-color: rgba(242, 242, 242, 0.8); - background-color: rgba(242, 242, 242, 0.05); - color: #CCCCCC; + border-color: TextA80; + background-color: TextA5; + color: TextDim; } .button--tertiary:focus, .button--tertiary:hover { - border-color: #F2F2F2; - background-color: rgba(242, 242, 242, 0.3); - color: #F2F2F2; + border-color: Text; + background-color: TextA30; + color: Text; } .button--tertiary:disabled, .button--tertiary[disabled] { - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .button--tertiary:active { - background-color: rgba(242, 242, 242, 0.2); - color: rgb(244.6, 244.6, 244.6); + background-color: TextA20; + color: TextActive; } .button--success { - border-color: rgba(69, 208, 67, 0.8); - background-color: rgba(69, 208, 67, 0.05); - color: #CCCCCC; + border-color: SuccessA80; + background-color: SuccessA5; + color: TextDim; } .button--success:focus, .button--success:hover { - border-color: #45D043; - background-color: rgba(69, 208, 67, 0.3); - color: #F2F2F2; + border-color: Success; + background-color: SuccessA30; + color: Text; } .button--success:disabled, .button--success[disabled] { - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .button--success:active { - background-color: rgba(69, 208, 67, 0.2); - color: rgb(244.6, 244.6, 244.6); + background-color: SuccessA20; + color: TextActive; } -.button--error { - border-color: rgba(248, 96, 57, 0.8); - background-color: rgba(248, 96, 57, 0.05); - color: #CCCCCC; +.button--danger { + border-color: DangerA80; + background-color: DangerA5; + color: TextDim; } -.button--error:focus, .button--error:hover { - border-color: #F86039; - background-color: rgba(248, 96, 57, 0.3); - color: #F2F2F2; +.button--danger:focus, .button--danger:hover { + border-color: Danger; + background-color: DangerA30; + color: Text; } -.button--error:disabled, .button--error[disabled] { - color: rgba(255, 255, 255, 0.6); +.button--danger:disabled, .button--danger[disabled] { + color: TextInactive; } -.button--error:active { - background-color: rgba(248, 96, 57, 0.2); - color: rgb(244.6, 244.6, 244.6); +.button--danger:active { + background-color: DangerA20; + color: TextActive; } .button--warning { - border-color: rgba(233, 205, 53, 0.8); - background-color: rgba(233, 205, 53, 0.05); - color: #CCCCCC; + border-color: WarningA80; + background-color: WarningA5; + color: TextDim; } .button--warning:focus, .button--warning:hover { - border-color: #E9CD35; - background-color: rgba(233, 205, 53, 0.3); - color: #F2F2F2; + border-color: Warning; + background-color: WarningA30; + color: Text; } .button--warning:disabled, .button--warning[disabled] { - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .button--warning:active { - background-color: rgba(233, 205, 53, 0.2); - color: rgb(244.6, 244.6, 244.6); + background-color: WarningA20; + color: TextActive; } .button:not([disabled]) { cursor: pointer; @@ -1800,13 +1805,13 @@ scrollbarhorizontal sliderbar { /* */ .icon-button { - color: #CCCCCC; + color: TextDim; transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out, border-color 0.05s linear-in-out; display: flex; align-items: center; @@ -1819,35 +1824,35 @@ scrollbarhorizontal sliderbar { max-height: 53.8dp; border-width: 1.1dp; border-radius: 26.9dp; - border-color: rgba(0, 0, 0, 0); - background-color: rgba(0, 0, 0, 0); + border-color: Transparent; + background-color: Transparent; } .icon-button svg { - image-color: #CCCCCC; + image-color: TextDim; } .icon-button svg { transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out; } .icon-button:focus, .icon-button:hover { - color: #F2F2F2; - background-color: rgba(255, 255, 255, 0.2); + color: Text; + background-color: Border; } .icon-button:focus svg, .icon-button:hover svg { - image-color: #F2F2F2; + image-color: Text; } .icon-button:active { - color: rgb(244.6, 244.6, 244.6); - background-color: rgba(255, 255, 255, 0.1); + color: TextActive; + background-color: BorderSoft; } .icon-button:active svg { - image-color: rgb(244.6, 244.6, 244.6); + image-color: TextActive; } .icon-button:disabled, .icon-button[disabled] { - color: #CCCCCC; + color: TextDim; opacity: 0.5; } .icon-button:disabled svg, .icon-button[disabled] svg { - image-color: #CCCCCC; + image-color: TextDim; } .icon-button:not([disabled]) { cursor: pointer; @@ -1857,70 +1862,70 @@ scrollbarhorizontal sliderbar { height: 32dp; } .icon-button--primary { - border-color: rgba(185, 125, 242, 0.8); - background-color: rgba(185, 125, 242, 0.05); + border-color: PrimaryA80; + background-color: PrimaryA5; } .icon-button--primary:focus, .icon-button--primary:hover { - border-color: #B97DF2; - background-color: rgba(185, 125, 242, 0.3); + border-color: Primary; + background-color: PrimaryA30; } .icon-button--primary:active { - background-color: rgba(185, 125, 242, 0.2); + background-color: PrimaryA20; } .icon-button--secondary { - border-color: rgba(23, 214, 232, 0.8); - background-color: rgba(23, 214, 232, 0.05); + border-color: SecondaryA80; + background-color: SecondaryA5; } .icon-button--secondary:focus, .icon-button--secondary:hover { - border-color: #17D6E8; - background-color: rgba(23, 214, 232, 0.3); + border-color: Secondary; + background-color: SecondaryA30; } .icon-button--secondary:active { - background-color: rgba(23, 214, 232, 0.2); + background-color: SecondaryA20; } .icon-button--tertiary { - border-color: rgba(242, 242, 242, 0.8); - background-color: rgba(242, 242, 242, 0.05); + border-color: TextA80; + background-color: TextA5; } .icon-button--tertiary:focus, .icon-button--tertiary:hover { - border-color: #F2F2F2; - background-color: rgba(242, 242, 242, 0.3); + border-color: Text; + background-color: TextA30; } .icon-button--tertiary:active { - background-color: rgba(242, 242, 242, 0.2); + background-color: TextA20; } .icon-button--success { - border-color: rgba(69, 208, 67, 0.8); - background-color: rgba(69, 208, 67, 0.05); + border-color: SuccessA80; + background-color: SuccessA5; } .icon-button--success:focus, .icon-button--success:hover { - border-color: #45D043; - background-color: rgba(69, 208, 67, 0.3); + border-color: Success; + background-color: SuccessA30; } .icon-button--success:active { - background-color: rgba(69, 208, 67, 0.2); + background-color: SuccessA20; } -.icon-button--error { - border-color: rgba(248, 96, 57, 0.8); - background-color: rgba(248, 96, 57, 0.05); +.icon-button--danger { + border-color: DangerA80; + background-color: DangerA5; } -.icon-button--error:focus, .icon-button--error:hover { - border-color: #F86039; - background-color: rgba(248, 96, 57, 0.3); +.icon-button--danger:focus, .icon-button--danger:hover { + border-color: Danger; + background-color: DangerA30; } -.icon-button--error:active { - background-color: rgba(248, 96, 57, 0.2); +.icon-button--danger:active { + background-color: DangerA20; } .icon-button--warning { - border-color: rgba(233, 205, 53, 0.8); - background-color: rgba(233, 205, 53, 0.05); + border-color: WarningA80; + background-color: WarningA5; } .icon-button--warning:focus, .icon-button--warning:hover { - border-color: #E9CD35; - background-color: rgba(233, 205, 53, 0.3); + border-color: Warning; + background-color: WarningA30; } .icon-button--warning:active { - background-color: rgba(233, 205, 53, 0.2); + background-color: WarningA20; } .launcher { @@ -1930,7 +1935,7 @@ scrollbarhorizontal sliderbar { justify-content: space-between; width: 100%; height: 100%; - background-color: #08070D; + background-color: Background1; } .launcher__vertical-split { @@ -2027,7 +2032,7 @@ scrollbarhorizontal sliderbar { */ .menu-list-item { - color: #CCCCCC; + color: TextDim; display: flex; flex-direction: row; align-items: center; @@ -2039,7 +2044,7 @@ scrollbarhorizontal sliderbar { cursor: pointer; } .menu-list-item svg { - image-color: #CCCCCC; + image-color: TextDim; } .menu-list-item--right { flex-direction: row-reverse; @@ -2050,14 +2055,14 @@ scrollbarhorizontal sliderbar { opacity: 1; } .menu-list-item--right.menu-list-item:focus:not(:disabled, [disabled]), .menu-list-item--right.menu-list-item:hover:not(:disabled, [disabled]) { - decorator: horizontal-gradient(#7A2AC600 #DABAF714); + background-color: WhiteA5; } .menu-list-item:focus:not(:disabled, [disabled]), .menu-list-item:hover:not(:disabled, [disabled]) { - color: #B97DF2; - decorator: horizontal-gradient(#7A2AC614 #DABAF700); + color: Primary; + background-color: WhiteA5; } .menu-list-item:focus:not(:disabled, [disabled]) svg, .menu-list-item:hover:not(:disabled, [disabled]) svg { - image-color: #B97DF2; + image-color: Primary; } .menu-list-item:focus:not(:disabled, [disabled]) .menu-list-item__bullet, .menu-list-item:hover:not(:disabled, [disabled]) .menu-list-item__bullet { opacity: 1; @@ -2097,7 +2102,7 @@ scrollbarhorizontal sliderbar { height: auto; padding: 0; background-color: rgba(0, 0, 0, 0); - color: #CCCCCC; + color: TextDim; text-align: left; cursor: pointer; } @@ -2108,11 +2113,11 @@ scrollbarhorizontal sliderbar { text-align: right; } .subtitle-title[selected] { - color: #F2F2F2; + color: Text; cursor: default; } .subtitle-title:focus:not(:disabled, [disabled]), .subtitle-title:hover:not(:disabled, [disabled], [selected]) { - color: #B97DF2; + color: Primary; } .subtitle-title:disabled, .subtitle-title[disabled] { opacity: 0.5; @@ -2140,16 +2145,16 @@ scrollbarhorizontal sliderbar { height: 72dp; border-radius: 36dp; opacity: 0.9; - background: rgba(0, 0, 0, 0); + background: Transparent; cursor: pointer; } .toggle:hover, .toggle:focus-visible, .toggle:focus { opacity: 1; - background-color: rgba(23, 214, 232, 0.3); + background-color: SecondaryA30; } .toggle:active { opacity: 1; - background-color: rgba(23, 214, 232, 0.05); + background-color: SecondaryA5; } .toggle .toggle__border { position: absolute; @@ -2158,7 +2163,7 @@ scrollbarhorizontal sliderbar { bottom: 1.1dp; left: 1.1dp; border-width: 1.1dp; - border-color: #A2EFF6; + border-color: SecondaryL; display: block; border-radius: 36dp; } @@ -2170,18 +2175,18 @@ scrollbarhorizontal sliderbar { height: 64dp; transform: translateY(-50%); border-radius: 32dp; - background: #25A1AD; + background: SecondaryD; } .toggle--checked .toggle__floater { left: 78dp; } .toggle--checked .toggle__icon.toggle__icon--left { opacity: 0.9; - color: #A2EFF6; + color: SecondaryL; } .toggle--checked .toggle__icon.toggle__icon--right { opacity: 1; - color: #F2F2F2; + color: Text; } .toggle__icons { @@ -2203,11 +2208,11 @@ scrollbarhorizontal sliderbar { justify-content: center; width: 56dp; height: 56dp; - color: #F2F2F2; + color: Text; } .toggle__icon--right { opacity: 1; - color: #A2EFF6; + color: SecondaryL; } .bottom-left { @@ -2224,7 +2229,7 @@ scrollbarhorizontal sliderbar { } .prompt__overlay { - background-color: rgba(190, 184, 219, 0.1); + background-color: BGOverlay; pointer-events: auto; } .prompt__overlay, .prompt__content-wrapper { @@ -2255,8 +2260,8 @@ scrollbarhorizontal sliderbar { margin: auto; border-width: 1.1dp; border-radius: 16dp; - border-color: rgba(255, 255, 255, 0.2); - background: rgba(8, 7, 13, 0.9); + border-color: Border; + background: ModalOverlay; } .prompt__content h3, .prompt__content p { margin: 24dp; @@ -2270,7 +2275,7 @@ scrollbarhorizontal sliderbar { justify-content: center; padding: 24dp 12dp; border-top-width: 1.1dp; - border-top-color: rgba(255, 255, 255, 0.1); + border-top-color: BorderSoft; } .prompt__controls .button { min-width: 233.3333333333dp; @@ -2297,10 +2302,10 @@ scrollbarhorizontal sliderbar { } .config-debug-option { - color: #CCCCCC; + color: TextDim; transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out; border-bottom-width: 1.1dp; - border-bottom-color: rgba(255, 255, 255, 0.1); + border-bottom-color: BorderSoft; display: block; position: relative; flex-direction: column; @@ -2310,17 +2315,17 @@ scrollbarhorizontal sliderbar { background-color: rgba(0, 0, 0, 0); } .config-debug-option svg { - image-color: #CCCCCC; + image-color: TextDim; } .config-debug-option svg { transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out; } .config-debug-option:focus:not(:disabled, [disabled]), .config-debug-option:focus-visible:not(:disabled, [disabled]), .config-debug-option:hover:not(:disabled, [disabled]) { - color: #F2F2F2; - background-color: rgba(190, 184, 219, 0.1); + color: Text; + background-color: BGOverlay; } .config-debug-option:focus:not(:disabled, [disabled]) svg, .config-debug-option:focus-visible:not(:disabled, [disabled]) svg, .config-debug-option:hover:not(:disabled, [disabled]) svg { - image-color: #F2F2F2; + image-color: Text; } .config-debug-option:disabled, .config-debug-option[disabled] { opacity: 0.5; @@ -2396,7 +2401,7 @@ scrollbarhorizontal sliderbar { .config-debug__select-wrapper select { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out, border-color 0.05s linear-in-out; border-width: 1.1dp; - border-color: rgba(255, 255, 255, 0.5); + border-color: WhiteA50; display: block; position: relative; box-sizing: border-box; @@ -2405,7 +2410,7 @@ scrollbarhorizontal sliderbar { width: auto; height: 48dp; border-radius: 12dp; - background-color: rgba(255, 255, 255, 0.05); + background-color: WhiteA5; cursor: pointer; align-items: center; justify-content: flex-start; @@ -2416,8 +2421,8 @@ scrollbarhorizontal sliderbar { } .config-debug__select-wrapper select:hover, .config-debug__select-wrapper select:focus { border-width: 1.1dp; - border-color: rgba(255, 255, 255, 0.8); - background-color: rgba(255, 255, 255, 0.2); + border-color: WhiteA80; + background-color: WhiteA20; } .config-debug__select-wrapper select selectvalue { display: inline; @@ -2426,8 +2431,8 @@ scrollbarhorizontal sliderbar { } .config-debug__select-wrapper select selectbox { border-width: 1.1dp; - border-color: rgba(255, 255, 255, 0.8); - background-color: #191622; + border-color: WhiteA80; + background-color: Background3; padding: 4dp 0; margin-top: 2dp; border-radius: 12dp; @@ -2435,25 +2440,19 @@ scrollbarhorizontal sliderbar { .config-debug__select-wrapper select selectbox option { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; padding: 8dp 12dp; - background-color: rgba(0, 0, 0, 0); - color: #CCCCCC; + background-color: Transparent; + color: TextDim; font-weight: 400; } .config-debug__select-wrapper select selectbox option:hover, .config-debug__select-wrapper select selectbox option:focus { - background-color: rgba(255, 255, 255, 0.2); + background-color: WhiteA20; } .config-debug__select-wrapper select selectbox option:hover:not(:checked) { cursor: pointer; } .config-debug__select-wrapper select selectbox option:checked { - color: #FFFFFF; - background-color: rgba(255, 255, 255, 0.05); -} - -body { - box-sizing: border-box; - color: #F2F2F2; - font-family: LatoLatin; + color: White; + background-color: WhiteA5; } .rmlui-window { @@ -2471,42 +2470,42 @@ body { } button { - background-color: #7A2AC6; + background-color: PrimaryD; } @keyframes blue-pulse { 0% { - color: #17D6E8; + color: Secondary; } 50% { - color: #A2EFF6; + color: SecondaryL; } 100% { - color: #17D6E8; + color: Secondary; } } @keyframes blue-pulse-with-border { 0% { - border-color: #17D6E8; - color: #17D6E8; + border-color: Secondary; + color: Secondary; } 50% { - border-color: #A2EFF6; - color: #A2EFF6; + border-color: SecondaryL; + color: SecondaryL; } 100% { - border-color: #17D6E8; - color: #17D6E8; + border-color: Secondary; + color: Secondary; } } @keyframes blue-pulse-background { 0% { - background-color: #17D6E8; + background-color: Secondary; } 50% { - background-color: #A2EFF6; + background-color: SecondaryL; } 100% { - background-color: #17D6E8; + background-color: Secondary; } } diff --git a/assets/scss/styles/components/Button.scss b/assets/scss/styles/components/Button.scss index d5d1514..b7f8086 100644 --- a/assets/scss/styles/components/Button.scss +++ b/assets/scss/styles/components/Button.scss @@ -1,13 +1,13 @@ @use 'sass:color'; -@mixin create-button-variation($base-col) { - border-color: rgba($base-col, 0.8); - background-color: rgba($base-col, 0.05); +@mixin create-button-variation($base-col, $base-col-05, $base-col-20, $base-col-30, $base-col-80) { + border-color: $base-col-80; + background-color: $base-col-05; color: $color-text-dim; &:focus, &:hover { border-color: $base-col; - background-color: rgba($base-col, 0.3); + background-color: $base-col-30; color: $color-text; } @@ -16,15 +16,15 @@ } &:active { - background-color: rgba($base-col, 0.2); - color: color.scale($color-text, $lightness: 20%); + background-color: $base-col-20; + color: $color-text-active; } } .button { @extend %label-md; @extend %nav-all; - @include create-button-variation($color-primary); + @include create-button-variation($color-primary, $color-primary-a5, $color-primary-a20, $color-primary-a30, $color-primary-a80); @include trans-colors; display: block; @@ -38,7 +38,7 @@ // Setting it by default for convenience &--primary { - @include create-button-variation($color-primary); + @include create-button-variation($color-primary, $color-primary-a5, $color-primary-a20, $color-primary-a30, $color-primary-a80); } &--large { @@ -46,23 +46,23 @@ } &--secondary { - @include create-button-variation($color-secondary); + @include create-button-variation($color-secondary, $color-secondary-a5, $color-secondary-a20, $color-secondary-a30, $color-secondary-a80); } &--tertiary { - @include create-button-variation($color-text); + @include create-button-variation($color-text, $color-text-a5, $color-text-a20, $color-text-a30, $color-text-a80); } &--success { - @include create-button-variation($color-success); + @include create-button-variation($color-success, $color-success-a5, $color-success-a20, $color-success-a30, $color-success-a80); } - &--error { - @include create-button-variation($color-error); + &--danger { + @include create-button-variation($color-danger, $color-danger-a5, $color-danger-a20, $color-danger-a30, $color-danger-a80); } &--warning { - @include create-button-variation($color-warning); + @include create-button-variation($color-warning, $color-warning-a5, $color-warning-a20, $color-warning-a30, $color-warning-a80); } &:not([disabled]) { diff --git a/assets/scss/styles/components/ControlOption.scss b/assets/scss/styles/components/ControlOption.scss index 662fd63..16c086e 100644 --- a/assets/scss/styles/components/ControlOption.scss +++ b/assets/scss/styles/components/ControlOption.scss @@ -31,7 +31,7 @@ @each $slot in $valid-binding-slots { // global attr -> this active row -> binding slot [cur-binding-slot="#{$slot}"] & .control-option__binding[bind-slot="#{$slot}"] { - border-color: $color-error; + border-color: $color-danger; .control-option__binding-icon { opacity: 0; @@ -93,7 +93,7 @@ } &:active { - @include set-color(color.scale($color-text, $lightness: 20%)); + @include set-color($color-text-active); } &:disabled, &[disabled] { @@ -145,7 +145,7 @@ height: space($rec-size); animation: 1.5s sine-in-out infinite control-option__binding-recording-scale; border-radius: space($rec-size); - background-color: $color-error; + background-color: $color-danger; } .control-option__binding-edge { @@ -164,7 +164,7 @@ > svg.control-option__binding-edge-svg { width: space($edge-size); height: space($edge-size); - image-color: $color-error; + image-color: $color-danger; } } } diff --git a/assets/scss/styles/components/IconButton.scss b/assets/scss/styles/components/IconButton.scss index 4e1822a..fc22121 100644 --- a/assets/scss/styles/components/IconButton.scss +++ b/assets/scss/styles/components/IconButton.scss @@ -2,22 +2,22 @@ /* */ -@mixin create-icon-button-variation($base-col) { - border-color: rgba($base-col, 0.8); - background-color: rgba($base-col, 0.05); +@mixin create-icon-button-variation($base-col, $base-col-05, $base-col-20, $base-col-30, $base-col-80) { + border-color: $base-col-80; + background-color: $base-col-05; &:focus, &:hover { border-color: $base-col; - background-color: rgba($base-col, 0.3); + background-color: $base-col-30; } &:active { - background-color: rgba($base-col, 0.2); + background-color: $base-col-20; } } @@ -47,7 +47,7 @@ $icon-button-size: 56 - ($border-width-thickness-num * 2); } &:active { - @include set-color(color.scale($color-text, $lightness: 20%)); + @include set-color($color-text-active); background-color: $color-border-soft; } @@ -67,26 +67,26 @@ $icon-button-size: 56 - ($border-width-thickness-num * 2); } &--primary { - @include create-icon-button-variation($color-primary); + @include create-icon-button-variation($color-primary, $color-primary-a5, $color-primary-a20, $color-primary-a30, $color-primary-a80); } &--secondary { - @include create-icon-button-variation($color-secondary); + @include create-icon-button-variation($color-secondary, $color-secondary-a5, $color-secondary-a20, $color-secondary-a30, $color-secondary-a80); } &--tertiary { - @include create-icon-button-variation($color-text); + @include create-icon-button-variation($color-text, $color-text-a5, $color-text-a20, $color-text-a30, $color-text-a80); } &--success { - @include create-icon-button-variation($color-success); + @include create-icon-button-variation($color-success, $color-success-a5, $color-success-a20, $color-success-a30, $color-success-a80); } - &--error { - @include create-icon-button-variation($color-error); + &--danger { + @include create-icon-button-variation($color-danger, $color-danger-a5, $color-danger-a20, $color-danger-a30, $color-danger-a80); } &--warning { - @include create-icon-button-variation($color-warning); + @include create-icon-button-variation($color-warning, $color-warning-a5, $color-warning-a20, $color-warning-a30, $color-warning-a80); } } diff --git a/assets/scss/styles/components/InputConfig.scss b/assets/scss/styles/components/InputConfig.scss index 71ba960..b2cae6d 100644 --- a/assets/scss/styles/components/InputConfig.scss +++ b/assets/scss/styles/components/InputConfig.scss @@ -195,7 +195,7 @@ $all-inputs: A, } &--Start { - @include set-svgs-color($color-error); + @include set-svgs-color($color-danger); } } diff --git a/assets/scss/styles/components/MenuListItem.scss b/assets/scss/styles/components/MenuListItem.scss index 657f0ef..4fb63aa 100644 --- a/assets/scss/styles/components/MenuListItem.scss +++ b/assets/scss/styles/components/MenuListItem.scss @@ -35,14 +35,16 @@ &.menu-list-item:focus:not(:disabled, [disabled]), &.menu-list-item:hover:not(:disabled, [disabled]) { - decorator: $primary-rl-fade; + // decorator: $primary-rl-fade; + background-color: $color-white-a5; } } &:focus:not(:disabled, [disabled]), &:hover:not(:disabled, [disabled]) { @include set-color($color-primary); - decorator: $primary-lr-fade; + // decorator: $primary-lr-fade; + background-color: $color-white-a5; .menu-list-item__bullet { opacity: 1; diff --git a/assets/scss/styles/global.scss b/assets/scss/styles/global.scss index 2e98925..08242f4 100644 --- a/assets/scss/styles/global.scss +++ b/assets/scss/styles/global.scss @@ -1,10 +1,4 @@ @import "./base"; -@import "./globals/old"; -@import "./globals/scrollbars"; -@import "./components/components"; -@import "./pages/pages"; - -$font-size: 20dp; body { @@ -14,6 +8,14 @@ body font-family: $font-stack; } +@import "./globals/old"; +@import "./globals/scrollbars"; +@import "./components/components"; +@import "./pages/pages"; + +$font-size: 20dp; + + .rmlui-window { opacity: 1; diff --git a/assets/scss/styles/globals/_old.scss b/assets/scss/styles/globals/_old.scss index 706fb94..4343b32 100644 --- a/assets/scss/styles/globals/_old.scss +++ b/assets/scss/styles/globals/_old.scss @@ -13,7 +13,6 @@ hr { body { color: #fff; - font-family: LatoLatin; font-size: 20dp; font-style: normal; font-weight: normal diff --git a/assets/scss/styles/mixins/_typography.scss b/assets/scss/styles/mixins/_typography.scss index fde69e0..384154c 100644 --- a/assets/scss/styles/mixins/_typography.scss +++ b/assets/scss/styles/mixins/_typography.scss @@ -1,5 +1,5 @@ -$font-stack: LatoLatin; +$font-stack: 'Suplexmentary Comic NC'; @mixin set-font-sizing($sz, $spacing) { // font-family: $font-stack; diff --git a/assets/scss/styles/vars/_colors.scss b/assets/scss/styles/vars/_colors.scss index 0b5cfd7..37e3b1e 100644 --- a/assets/scss/styles/vars/_colors.scss +++ b/assets/scss/styles/vars/_colors.scss @@ -1,71 +1,83 @@ /* stylelint-disable color-no-hex, color-hex-length */ -$color-background-1: #08070D; -$color-background-2: #121018; -$color-background-3: #191622; -$color-bg-overlay: rgba(190, 184, 219, 0.1000); -$color-modal-overlay: rgba(8, 7, 13, 0.9000); -$color-bg-shadow: rgba(0, 0, 0, 0.3500); -$color-bg-shadow-2: rgba(8, 7, 13, 0.7200); -$color-text: #F2F2F2; -$color-text-dim: #CCCCCC; -$color-text-inactive: rgba(255, 255, 255, 0.6000); -$color-primary: #B97DF2; -$color-primary-l: #DABAF7; -$color-primary-d: #7A2AC6; -$color-primary-a5: rgba(185, 125, 242, 0.0500); -$color-primary-a20: rgba(185, 125, 242, 0.2000); -$color-primary-a30: rgba(185, 125, 242, 0.3000); -$color-primary-a50: rgba(185, 125, 242, 0.5000); -$color-primary-a80: rgba(185, 125, 242, 0.8000); -$color-secondary: #17D6E8; -$color-secondary-l: #A2EFF6; -$color-secondary-d: #25A1AD; -$color-secondary-a5: rgba(23, 214, 232, 0.0500); -$color-secondary-a20: rgba(23, 214, 232, 0.2000); -$color-secondary-a30: rgba(23, 214, 232, 0.3000); -$color-secondary-a50: rgba(23, 214, 232, 0.5000); -$color-secondary-a80: rgba(23, 214, 232, 0.8000); -$color-warning: #E9CD35; -$color-warning-l: #F9E57C; -$color-warning-d: #C5AA16; -$color-warning-a5: rgba(233, 205, 53, 0.0500); -$color-warning-a20: rgba(233, 205, 53, 0.2000); -$color-warning-a30: rgba(233, 205, 53, 0.3000); -$color-warning-a50: rgba(233, 205, 53, 0.5000); -$color-warning-a80: rgba(233, 205, 53, 0.8000); -$color-error: #F86039; -$color-error-l: #FE8667; -$color-error-d: #B23919; -$color-error-a5: rgba(248, 96, 57, 0.0500); -$color-error-a20: rgba(248, 96, 57, 0.2000); -$color-error-a30: rgba(248, 96, 57, 0.3000); -$color-error-a50: rgba(248, 96, 57, 0.5000); -$color-error-a80: rgba(248, 96, 57, 0.8000); -$color-success: #45D043; -$color-success-l: #AAEAA9; -$color-success-d: #2CA72A; -$color-success-a5: rgba(69, 208, 67, 0.0500); -$color-success-a20: rgba(69, 208, 67, 0.2000); -$color-success-a30: rgba(69, 208, 67, 0.3000); -$color-success-a50: rgba(69, 208, 67, 0.5000); -$color-success-a80: rgba(69, 208, 67, 0.8000); -$color-border: rgba(255, 255, 255, 0.2000); -$color-border-soft: rgba(255, 255, 255, 0.1000); -$color-border-hard: rgba(255, 255, 255, 0.3000); -$color-border-solid: rgba(255, 255, 255, 0.6000); -$color-transparent: rgba(0, 0, 0, 0.0000); -$color-a: #3333FF; -$color-a-l: #B2B2FF; -$color-a-d: #2020AC; -$color-a-a5: rgba(51, 51, 255, 0.0500); -$color-a-a20: rgba(51, 51, 255, 0.2000); -$color-a-a30: rgba(51, 51, 255, 0.3000); -$color-a-a50: rgba(51, 51, 255, 0.5000); -$color-a-a80: rgba(51, 51, 255, 0.8000); -$color-white: #FFFFFF; -$color-white-a5: rgba(255, 255, 255, 0.0500); -$color-white-a20: rgba(255, 255, 255, 0.2000); -$color-white-a30: rgba(255, 255, 255, 0.3000); -$color-white-a50: rgba(255, 255, 255, 0.5000); -$color-white-a80: rgba(255, 255, 255, 0.8000); +$color-background-1: Background1; +$color-background-2: Background2; +$color-background-3: Background3; +$color-bg-overlay: BGOverlay; +$color-modal-overlay: ModalOverlay; +$color-bg-shadow: BGShadow; +$color-bg-shadow-2: BGShadow2; +$color-text: Text; +$color-text-active: TextActive; +$color-text-dim: TextDim; +$color-text-inactive: TextInactive; +$color-text-a5: TextA5; +$color-text-a20: TextA20; +$color-text-a30: TextA30; +$color-text-a50: TextA50; +$color-text-a80: TextA80; +$color-primary: Primary; +$color-primary-l: PrimaryL; +$color-primary-d: PrimaryD; +$color-primary-a5: PrimaryA5; +$color-primary-a20: PrimaryA20; +$color-primary-a30: PrimaryA30; +$color-primary-a50: PrimaryA50; +$color-primary-a80: PrimaryA80; +$color-secondary: Secondary; +$color-secondary-l: SecondaryL; +$color-secondary-d: SecondaryD; +$color-secondary-a5: SecondaryA5; +$color-secondary-a20: SecondaryA20; +$color-secondary-a30: SecondaryA30; +$color-secondary-a50: SecondaryA50; +$color-secondary-a80: SecondaryA80; +$color-warning: Warning; +$color-warning-l: WarningL; +$color-warning-d: WarningD; +$color-warning-a5: WarningA5; +$color-warning-a20: WarningA20; +$color-warning-a30: WarningA30; +$color-warning-a50: WarningA50; +$color-warning-a80: WarningA80; +$color-danger: Danger; +$color-danger-l: DangerL; +$color-danger-d: DangerD; +$color-danger-a5: DangerA5; +$color-danger-a20: DangerA20; +$color-danger-a30: DangerA30; +$color-danger-a50: DangerA50; +$color-danger-a80: DangerA80; +$color-success: Success; +$color-success-l: SuccessL; +$color-success-d: SuccessD; +$color-success-a5: SuccessA5; +$color-success-a20: SuccessA20; +$color-success-a30: SuccessA30; +$color-success-a50: SuccessA50; +$color-success-a80: SuccessA80; +$color-border: Border; +$color-border-soft: BorderSoft; +$color-border-hard: BorderHard; +$color-border-solid: BorderSolid; +$color-transparent: Transparent; +$color-a: A; +$color-a-l: AL; +$color-a-d: AD; +$color-a-a5: AA5; +$color-a-a20: AA20; +$color-a-a30: AA30; +$color-a-a50: AA50; +$color-a-a80: AA80; +$color-white: White; +$color-white-a5: WhiteA5; +$color-white-a20: WhiteA20; +$color-white-a30: WhiteA30; +$color-white-a50: WhiteA50; +$color-white-a80: WhiteA80; +$color-bw-05: BW05; +$color-bw-10: BW10; +$color-bw-25: BW25; +$color-bw-50: BW50; +$color-bw-75: BW75; +$color-bw-90: BW90; diff --git a/assets/scss/styles/vars/_gradients.scss b/assets/scss/styles/vars/_gradients.scss index 1cdebd5..b3e2305 100644 --- a/assets/scss/styles/vars/_gradients.scss +++ b/assets/scss/styles/vars/_gradients.scss @@ -3,5 +3,7 @@ // $primary-lr-fade: linear-gradient(90deg, rgba($color-primary-l, 0.08) 0%, rgba($color-primary-l, 0.00) 100%); // $primary-rl-fade: linear-gradient(90deg, rgba($color-primary-l, 0.00) 0%, rgba($color-primary-l, 0.08) 100%); -$primary-lr-fade: horizontal-gradient(#{$color-primary-d}14 #{$color-primary-l}00); -$primary-rl-fade: horizontal-gradient(#{$color-primary-d}00 #{$color-primary-l}14); +// $primary-lr-fade: horizontal-gradient(#{$color-primary-d}14 #{$color-primary-l}00); +// $primary-rl-fade: horizontal-gradient(#{$color-primary-d}00 #{$color-primary-l}14); +$primary-lr-fade: horizontal-gradient(#ff000014 #ff000000); +$primary-rl-fade: horizontal-gradient(#ff000000 #ff000014); diff --git a/include/recomp_ui.h b/include/recomp_ui.h index f609a52..1856ab0 100644 --- a/include/recomp_ui.h +++ b/include/recomp_ui.h @@ -13,6 +13,8 @@ #include "../src/ui/util/hsv.h" #include "../src/ui/util/bem.h" +#include "../src/ui/elements/ui_button.h" +#include "../src/ui/elements/ui_theme.h" #include "../src/ui/core/ui_context.h" @@ -75,16 +77,6 @@ namespace recompui { void set_config_tabset_mod_nav(); void focus_mod_configure_button(); - enum class ButtonVariant { - Primary, - Secondary, - Tertiary, - Success, - Error, - Warning, - NumVariants, - }; - void init_styling(const std::filesystem::path& rcss_file); void init_prompt_context(); void open_choice_prompt( @@ -94,8 +86,8 @@ namespace recompui { const std::string& cancel_label_text, std::function confirm_action, std::function cancel_action, - ButtonVariant confirm_variant = ButtonVariant::Success, - ButtonVariant cancel_variant = ButtonVariant::Error, + ButtonStyle confirm_variant = ButtonStyle::Success, + ButtonStyle cancel_variant = ButtonStyle::Danger, bool focus_on_cancel = true, const std::string& return_element_id = "" ); @@ -104,7 +96,7 @@ namespace recompui { const std::string& content_text, const std::string& okay_label_text, std::function okay_action, - ButtonVariant okay_variant = ButtonVariant::Error, + ButtonStyle okay_variant = ButtonStyle::Danger, const std::string& return_element_id = "" ); void open_notification( diff --git a/src/main/main.cpp b/src/main/main.cpp index dc6839d..10d2902 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -29,6 +29,7 @@ #include "banjo_game.h" #include "recomp_data.h" #include "ovl_patches.hpp" +#include "theme.h" #include "librecomp/game.hpp" #include "librecomp/mods.hpp" #include "librecomp/helpers.hpp" @@ -602,6 +603,7 @@ int main(int argc, char** argv) { REGISTER_FUNC(recomp_get_analog_inverted_axes); recompui::register_ui_exports(); recomputil::register_data_api_exports(); + recomptheme::set_custom_theme(); banjo::register_bk_overlays(); banjo::register_bk_patches(); diff --git a/src/main/theme.cpp b/src/main/theme.cpp new file mode 100644 index 0000000..228f7e4 --- /dev/null +++ b/src/main/theme.cpp @@ -0,0 +1,88 @@ +#include "recomp_ui.h" +#include "theme.h" + +void recomptheme::set_custom_theme() { + recompui::set_theme_color(recompui::ThemeColor::Background1, recompui::Color{2, 7, 18, 255}); + recompui::set_theme_color(recompui::ThemeColor::Background2, recompui::Color{7, 15, 34, 255}); + recompui::set_theme_color(recompui::ThemeColor::Background3, recompui::Color{18, 24, 38, 255}); + recompui::set_theme_color(recompui::ThemeColor::BGOverlay, recompui::Color{182, 194, 221, 26}); + recompui::set_theme_color(recompui::ThemeColor::ModalOverlay, recompui::Color{2, 7, 18, 229}); + recompui::set_theme_color(recompui::ThemeColor::BGShadow, recompui::Color{0, 0, 0, 89}); + recompui::set_theme_color(recompui::ThemeColor::BGShadow2, recompui::Color{2, 7, 18, 184}); + recompui::set_theme_color(recompui::ThemeColor::Text, recompui::Color{242, 242, 242, 255}); + recompui::set_theme_color(recompui::ThemeColor::TextActive, recompui::Color{245, 245, 245, 255}); + recompui::set_theme_color(recompui::ThemeColor::TextDim, recompui::Color{204, 204, 204, 255}); + recompui::set_theme_color(recompui::ThemeColor::TextInactive, recompui::Color{255, 255, 255, 153}); + recompui::set_theme_color(recompui::ThemeColor::TextA5, recompui::Color{242, 242, 242, 13}); + recompui::set_theme_color(recompui::ThemeColor::TextA20, recompui::Color{242, 242, 242, 51}); + recompui::set_theme_color(recompui::ThemeColor::TextA30, recompui::Color{242, 242, 242, 77}); + recompui::set_theme_color(recompui::ThemeColor::TextA50, recompui::Color{242, 242, 242, 128}); + recompui::set_theme_color(recompui::ThemeColor::TextA80, recompui::Color{242, 242, 242, 204}); + recompui::set_theme_color(recompui::ThemeColor::Primary, recompui::Color{29, 93, 226, 255}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryL, recompui::Color{167, 191, 241, 255}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryD, recompui::Color{0, 38, 117, 255}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryA5, recompui::Color{29, 93, 226, 13}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryA20, recompui::Color{29, 93, 226, 51}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryA30, recompui::Color{29, 93, 226, 77}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryA50, recompui::Color{29, 93, 226, 128}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryA80, recompui::Color{29, 93, 226, 204}); + recompui::set_theme_color(recompui::ThemeColor::Secondary, recompui::Color{247, 158, 8, 255}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryL, recompui::Color{255, 215, 148, 255}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryD, recompui::Color{224, 141, 0, 255}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryA5, recompui::Color{247, 158, 8, 13}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryA20, recompui::Color{247, 158, 8, 51}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryA30, recompui::Color{247, 158, 8, 77}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryA50, recompui::Color{247, 158, 8, 128}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryA80, recompui::Color{247, 158, 8, 204}); + recompui::set_theme_color(recompui::ThemeColor::Warning, recompui::Color{255, 254, 0, 255}); + recompui::set_theme_color(recompui::ThemeColor::WarningL, recompui::Color{255, 254, 143, 255}); + recompui::set_theme_color(recompui::ThemeColor::WarningD, recompui::Color{197, 163, 2, 255}); + recompui::set_theme_color(recompui::ThemeColor::WarningA5, recompui::Color{255, 254, 0, 13}); + recompui::set_theme_color(recompui::ThemeColor::WarningA20, recompui::Color{255, 254, 0, 51}); + recompui::set_theme_color(recompui::ThemeColor::WarningA30, recompui::Color{255, 254, 0, 77}); + recompui::set_theme_color(recompui::ThemeColor::WarningA50, recompui::Color{255, 254, 0, 128}); + recompui::set_theme_color(recompui::ThemeColor::WarningA80, recompui::Color{255, 254, 0, 204}); + recompui::set_theme_color(recompui::ThemeColor::Danger, recompui::Color{255, 53, 31, 255}); + recompui::set_theme_color(recompui::ThemeColor::DangerL, recompui::Color{255, 149, 138, 255}); + recompui::set_theme_color(recompui::ThemeColor::DangerD, recompui::Color{163, 16, 0, 255}); + recompui::set_theme_color(recompui::ThemeColor::DangerA5, recompui::Color{255, 53, 31, 13}); + recompui::set_theme_color(recompui::ThemeColor::DangerA20, recompui::Color{255, 53, 31, 51}); + recompui::set_theme_color(recompui::ThemeColor::DangerA30, recompui::Color{255, 53, 31, 77}); + recompui::set_theme_color(recompui::ThemeColor::DangerA50, recompui::Color{255, 53, 31, 128}); + recompui::set_theme_color(recompui::ThemeColor::DangerA80, recompui::Color{255, 53, 31, 204}); + recompui::set_theme_color(recompui::ThemeColor::Success, recompui::Color{40, 238, 32, 255}); + recompui::set_theme_color(recompui::ThemeColor::SuccessL, recompui::Color{155, 247, 151, 255}); + recompui::set_theme_color(recompui::ThemeColor::SuccessD, recompui::Color{18, 157, 12, 255}); + recompui::set_theme_color(recompui::ThemeColor::SuccessA5, recompui::Color{40, 238, 32, 13}); + recompui::set_theme_color(recompui::ThemeColor::SuccessA20, recompui::Color{40, 238, 32, 51}); + recompui::set_theme_color(recompui::ThemeColor::SuccessA30, recompui::Color{40, 238, 32, 77}); + recompui::set_theme_color(recompui::ThemeColor::SuccessA50, recompui::Color{40, 238, 32, 128}); + recompui::set_theme_color(recompui::ThemeColor::SuccessA80, recompui::Color{40, 238, 32, 204}); + recompui::set_theme_color(recompui::ThemeColor::Border, recompui::Color{255, 255, 255, 51}); + recompui::set_theme_color(recompui::ThemeColor::BorderSoft, recompui::Color{255, 255, 255, 26}); + recompui::set_theme_color(recompui::ThemeColor::BorderHard, recompui::Color{255, 255, 255, 77}); + recompui::set_theme_color(recompui::ThemeColor::BorderSolid, recompui::Color{255, 255, 255, 153}); + recompui::set_theme_color(recompui::ThemeColor::Transparent, recompui::Color{0, 0, 0, 0}); + recompui::set_theme_color(recompui::ThemeColor::A, recompui::Color{51, 51, 255, 255}); + recompui::set_theme_color(recompui::ThemeColor::AL, recompui::Color{178, 178, 255, 255}); + recompui::set_theme_color(recompui::ThemeColor::AD, recompui::Color{32, 32, 172, 255}); + recompui::set_theme_color(recompui::ThemeColor::AA5, recompui::Color{51, 51, 255, 13}); + recompui::set_theme_color(recompui::ThemeColor::AA20, recompui::Color{51, 51, 255, 51}); + recompui::set_theme_color(recompui::ThemeColor::AA30, recompui::Color{51, 51, 255, 77}); + recompui::set_theme_color(recompui::ThemeColor::AA50, recompui::Color{51, 51, 255, 128}); + recompui::set_theme_color(recompui::ThemeColor::AA80, recompui::Color{51, 51, 255, 204}); + recompui::set_theme_color(recompui::ThemeColor::White, recompui::Color{255, 255, 255, 255}); + recompui::set_theme_color(recompui::ThemeColor::WhiteA5, recompui::Color{255, 255, 255, 13}); + recompui::set_theme_color(recompui::ThemeColor::WhiteA20, recompui::Color{255, 255, 255, 51}); + recompui::set_theme_color(recompui::ThemeColor::WhiteA30, recompui::Color{255, 255, 255, 77}); + recompui::set_theme_color(recompui::ThemeColor::WhiteA50, recompui::Color{255, 255, 255, 128}); + recompui::set_theme_color(recompui::ThemeColor::WhiteA80, recompui::Color{255, 255, 255, 204}); + recompui::set_theme_color(recompui::ThemeColor::BW05, recompui::Color{13, 13, 13, 255}); + recompui::set_theme_color(recompui::ThemeColor::BW10, recompui::Color{26, 26, 26, 255}); + recompui::set_theme_color(recompui::ThemeColor::BW25, recompui::Color{64, 64, 64, 255}); + recompui::set_theme_color(recompui::ThemeColor::BW50, recompui::Color{128, 128, 128, 255}); + recompui::set_theme_color(recompui::ThemeColor::BW75, recompui::Color{191, 191, 191, 255}); + recompui::set_theme_color(recompui::ThemeColor::BW90, recompui::Color{229, 229, 229, 255}); +}; + + diff --git a/src/main/theme.h b/src/main/theme.h new file mode 100644 index 0000000..deaa66b --- /dev/null +++ b/src/main/theme.h @@ -0,0 +1,6 @@ +#pragma once + +namespace recomptheme { + // Applies custom themes. recompui::apply_color_hack MUST be called after. + void set_custom_theme(); +} // namespace recomptheme diff --git a/src/ui/elements/ui_button.cpp b/src/ui/elements/ui_button.cpp index 23bbf7b..c3e51a3 100644 --- a/src/ui/elements/ui_button.cpp +++ b/src/ui/elements/ui_button.cpp @@ -20,53 +20,14 @@ namespace recompui { set_font_style(FontStyle::Normal); set_font_weight(700); set_cursor(Cursor::Pointer); - set_color(Color{ 204, 204, 204, 255 }); + set_color(ThemeColor::Text); set_tab_index(TabIndex::Auto); - hover_style.set_color(Color{ 242, 242, 242, 255 }); - focus_style.set_color(Color{ 242, 242, 242, 255 }); - disabled_style.set_color(Color{ 204, 204, 204, 128 }); - hover_disabled_style.set_color(Color{ 242, 242, 242, 128 }); + hover_style.set_color(ThemeColor::Text); + focus_style.set_color(ThemeColor::Text); + disabled_style.set_color(ThemeColor::TextDim, 128); + hover_disabled_style.set_color(ThemeColor::Text, 128); - const uint8_t border_opacity = 204; - const uint8_t background_opacity = 13; - const uint8_t border_hover_opacity = 255; - const uint8_t background_hover_opacity = 76; - switch (style) { - case ButtonStyle::Primary: { - set_border_color({ 185, 125, 242, border_opacity }); - set_background_color({ 185, 125, 242, background_opacity }); - hover_style.set_border_color({ 185, 125, 242, border_hover_opacity }); - hover_style.set_background_color({ 185, 125, 242, background_hover_opacity }); - focus_style.set_border_color({ 185, 125, 242, border_hover_opacity }); - focus_style.set_background_color({ 185, 125, 242, background_hover_opacity }); - disabled_style.set_border_color({ 185, 125, 242, border_opacity / 4 }); - disabled_style.set_background_color({ 185, 125, 242, background_opacity / 4 }); - hover_disabled_style.set_border_color({ 185, 125, 242, border_hover_opacity / 4 }); - hover_disabled_style.set_background_color({ 185, 125, 242, background_hover_opacity / 4 }); - break; - } - case ButtonStyle::Secondary: { - set_border_color({ 23, 214, 232, border_opacity }); - set_background_color({ 23, 214, 232, background_opacity }); - hover_style.set_border_color({ 23, 214, 232, border_hover_opacity }); - hover_style.set_background_color({ 23, 214, 232, background_hover_opacity }); - focus_style.set_border_color({ 23, 214, 232, border_hover_opacity }); - focus_style.set_background_color({ 23, 214, 232, background_hover_opacity }); - disabled_style.set_border_color({ 23, 214, 232, border_opacity / 4 }); - disabled_style.set_background_color({ 23, 214, 232, background_opacity / 4 }); - hover_disabled_style.set_border_color({ 23, 214, 232, border_hover_opacity / 4 }); - hover_disabled_style.set_background_color({ 23, 214, 232, background_hover_opacity / 4 }); - break; - } - default: - assert(false && "Unknown button style."); - break; - } - - add_style(&hover_style, hover_state); - add_style(&focus_style, focus_state); - add_style(&disabled_style, disabled_state); - add_style(&hover_disabled_style, { hover_state, disabled_state }); + apply_button_style(style); // transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; } @@ -111,4 +72,60 @@ namespace recompui { void Button::add_pressed_callback(std::function callback) { pressed_callbacks.emplace_back(callback); } -}; \ No newline at end of file + + void Button::apply_button_style(ButtonStyle new_style) { + style = new_style; + switch (style) { + case ButtonStyle::Primary: { + apply_theme_style(ThemeColor::Primary); + break; + } + case ButtonStyle::Secondary: { + apply_theme_style(ThemeColor::Secondary); + break; + } + case ButtonStyle::Tertiary: { + apply_theme_style(ThemeColor::Text); + break; + } + case ButtonStyle::Success: { + apply_theme_style(ThemeColor::Success); + break; + } + case ButtonStyle::Warning: { + apply_theme_style(ThemeColor::Warning); + break; + } + case ButtonStyle::Danger: { + apply_theme_style(ThemeColor::Danger); + break; + } + default: + assert(false && "Unknown button style."); + break; + } + } + + void Button::apply_theme_style(recompui::ThemeColor color) { + const uint8_t border_opacity = 204; + const uint8_t background_opacity = 13; + const uint8_t border_hover_opacity = 255; + const uint8_t background_hover_opacity = 77; + + set_border_color(color, border_opacity); + set_background_color(color, background_opacity); + hover_style.set_border_color(color, border_hover_opacity); + hover_style.set_background_color(color, background_hover_opacity); + focus_style.set_border_color(color, border_hover_opacity); + focus_style.set_background_color(color, background_hover_opacity); + disabled_style.set_border_color(color, border_opacity / 4); + disabled_style.set_background_color(color, background_opacity / 4); + hover_disabled_style.set_border_color(color, border_hover_opacity / 4); + hover_disabled_style.set_background_color(color, background_hover_opacity / 4); + + add_style(&hover_style, hover_state); + add_style(&focus_style, focus_state); + add_style(&disabled_style, disabled_state); + add_style(&hover_disabled_style, { hover_state, disabled_state }); + } +}; diff --git a/src/ui/elements/ui_button.h b/src/ui/elements/ui_button.h index 182cda3..0781936 100644 --- a/src/ui/elements/ui_button.h +++ b/src/ui/elements/ui_button.h @@ -6,7 +6,11 @@ namespace recompui { enum class ButtonStyle { Primary, - Secondary + Secondary, + Tertiary, + Success, + Warning, + Danger, }; class Button : public Element { @@ -28,6 +32,9 @@ namespace recompui { Style* get_focus_style() { return &focus_style; } Style* get_disabled_style() { return &disabled_style; } Style* get_hover_disabled_style() { return &hover_disabled_style; } + void apply_button_style(ButtonStyle new_style); + private: + void apply_theme_style(recompui::ThemeColor color); }; -} // namespace recompui \ No newline at end of file +} // namespace recompui diff --git a/src/ui/elements/ui_label.cpp b/src/ui/elements/ui_label.cpp index 64a53b8..4138849 100644 --- a/src/ui/elements/ui_label.cpp +++ b/src/ui/elements/ui_label.cpp @@ -7,7 +7,7 @@ namespace recompui { Label::Label(Element *parent, LabelStyle label_style) : Element(parent, 0U, "div", true) { switch (label_style) { case LabelStyle::Annotation: - set_color(Color{ 185, 125, 242, 255 }); + set_color(ThemeColor::Primary); set_font_size(18.0f); set_letter_spacing(2.52f); set_line_height(18.0f); @@ -40,4 +40,4 @@ namespace recompui { set_text(text); } -}; \ No newline at end of file +}; diff --git a/src/ui/elements/ui_radio.cpp b/src/ui/elements/ui_radio.cpp index 6cd1423..6759588 100644 --- a/src/ui/elements/ui_radio.cpp +++ b/src/ui/elements/ui_radio.cpp @@ -17,16 +17,16 @@ namespace recompui { set_line_height(20.0f); set_font_weight(400); set_font_style(FontStyle::Normal); - set_border_color(Color{ 242, 242, 242, 0 }); + set_border_color(ThemeColor::Text, 0); set_border_bottom_width(1.0f); - set_color(Color{ 255, 255, 255, 153 }); + set_color(ThemeColor::TextInactive); set_padding_bottom(8.0f); set_text_transform(TextTransform::Uppercase); set_height_auto(); - hover_style.set_color(Color{ 255, 255, 255, 204 }); - checked_style.set_color(Color{ 255, 255, 255, 255 }); - checked_style.set_border_color(Color{ 242, 242, 242, 255 }); - pulsing_style.set_border_color(Color{ 23, 214, 232, 244 }); + hover_style.set_color(ThemeColor::WhiteA80); + checked_style.set_color(ThemeColor::White); + checked_style.set_border_color(ThemeColor::Text); + pulsing_style.set_border_color(ThemeColor::SecondaryA80); add_style(&hover_style, { hover_state }); add_style(&checked_style, { checked_state }); diff --git a/src/ui/elements/ui_slider.cpp b/src/ui/elements/ui_slider.cpp index c77b45d..702cae1 100644 --- a/src/ui/elements/ui_slider.cpp +++ b/src/ui/elements/ui_slider.cpp @@ -93,11 +93,11 @@ namespace recompui { queue_update(); } else { - circle_element->set_background_color(Color{ 204, 204, 204, 255 }); + circle_element->set_background_color(ThemeColor::TextDim); } } else { - circle_element->set_background_color(Color{ 102, 102, 102, 255 }); + circle_element->set_background_color(ThemeColor::BW25); } break; case EventType::Navigate: @@ -118,12 +118,12 @@ namespace recompui { if (enable_active) { set_cursor(Cursor::Pointer); set_focusable(true); - circle_element->set_background_color(Color{ 204, 204, 204, 255 }); + circle_element->set_background_color(ThemeColor::TextDim); } else { set_cursor(Cursor::None); set_focusable(false); - circle_element->set_background_color(Color{ 102, 102, 102, 255 }); + circle_element->set_background_color(ThemeColor::BW25); } } break; @@ -162,7 +162,7 @@ namespace recompui { bar_element->set_width(100.0f, Unit::Percent); bar_element->set_height(2.0f); bar_element->set_margin_top(8.0f); - bar_element->set_background_color(Color{ 255, 255, 255, 50 }); + bar_element->set_background_color(ThemeColor::WhiteA20); bar_element->add_pressed_callback([this](float x, float y){ bar_pressed(x, y); focus(); }); bar_element->add_dragged_callback([this](float x, float y, recompui::DragPhase phase){ bar_dragged(x, y, phase); focus(); }); @@ -173,7 +173,7 @@ namespace recompui { circle_element->set_margin_top(-7.0f); circle_element->set_margin_right(-8.0f); circle_element->set_margin_left(-8.0f); - circle_element->set_background_color(Color{ 204, 204, 204, 255 }); + circle_element->set_background_color(ThemeColor::TextDim); circle_element->set_border_radius(8.0f); circle_element->add_pressed_callback([this](float, float){ focus(); }); circle_element->add_dragged_callback([this](float x, float y, recompui::DragPhase phase){ circle_dragged(x, y, phase); focus(); }); diff --git a/src/ui/elements/ui_style.cpp b/src/ui/elements/ui_style.cpp index 5708ec5..5f2e6dc 100644 --- a/src/ui/elements/ui_style.cpp +++ b/src/ui/elements/ui_style.cpp @@ -388,11 +388,24 @@ namespace recompui { set_property(Rml::PropertyId::BorderBottomRightRadius, Rml::Property(radius, to_rml(unit))); } + static Color get_theme_color_with_opacity(ThemeColor color, int opacity) { + Color theme_color = get_theme_color(color); + if (opacity == recompui::ThemeDefaultOpacity) { + opacity = theme_color.a; // Use the existing opacity if not specified. + } + theme_color.a = opacity; + return theme_color; + } + void Style::set_background_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::BackgroundColor, property); } + void Style::set_background_color(recompui::ThemeColor color, int opacity) { + set_background_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_border_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::BorderTopColor, property); @@ -401,31 +414,55 @@ namespace recompui { set_property(Rml::PropertyId::BorderRightColor, property); } + void Style::set_border_color(recompui::ThemeColor color, int opacity) { + set_border_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_border_left_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::BorderLeftColor, property); } + void Style::set_border_left_color(recompui::ThemeColor color, int opacity) { + set_border_left_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_border_top_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::BorderTopColor, property); } + void Style::set_border_top_color(recompui::ThemeColor color, int opacity) { + set_border_top_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_border_right_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::BorderRightColor, property); } + void Style::set_border_right_color(recompui::ThemeColor color, int opacity) { + set_border_right_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_border_bottom_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::BorderBottomColor, property); } + void Style::set_border_bottom_color(recompui::ThemeColor color, int opacity) { + set_border_bottom_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::Color, property); } + void Style::set_color(recompui::ThemeColor color, int opacity) { + set_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_cursor(Cursor cursor) { switch (cursor) { case Cursor::None: @@ -609,4 +646,4 @@ namespace recompui { } -} // namespace recompui \ No newline at end of file +} // namespace recompui diff --git a/src/ui/elements/ui_style.h b/src/ui/elements/ui_style.h index 372fa6d..bb6b9de 100644 --- a/src/ui/elements/ui_style.h +++ b/src/ui/elements/ui_style.h @@ -6,8 +6,11 @@ #include "../core/ui_resource.h" #include "ui_types.h" +#include "ui_theme.h" namespace recompui { + const int ThemeDefaultOpacity = -1; // Represents using the theme color's existing opacity. + class ContextId; class Style { friend class Element; // For access to property_map without making it visible to element subclasses. @@ -66,6 +69,13 @@ namespace recompui { void set_border_right_color(const Color &color); void set_border_bottom_color(const Color &color); void set_color(const Color &color); + void set_background_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); + void set_border_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); + void set_border_left_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); + void set_border_top_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); + void set_border_right_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); + void set_border_bottom_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); + void set_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); void set_cursor(Cursor cursor); void set_opacity(float opacity); void set_display(Display display); @@ -105,4 +115,4 @@ namespace recompui { ResourceId get_resource_id() { return resource_id; } }; -} // namespace recompui \ No newline at end of file +} // namespace recompui diff --git a/src/ui/elements/ui_text_input.cpp b/src/ui/elements/ui_text_input.cpp index b496728..d5ac94d 100644 --- a/src/ui/elements/ui_text_input.cpp +++ b/src/ui/elements/ui_text_input.cpp @@ -33,7 +33,7 @@ namespace recompui { set_attribute("type", "password"); } set_min_width(60.0f); - set_border_color(Color{ 242, 242, 242, 255 }); + set_border_color(ThemeColor::Text); set_border_bottom_width(1.0f); set_padding_bottom(6.0f); set_focusable(true); diff --git a/src/ui/elements/ui_theme.cpp b/src/ui/elements/ui_theme.cpp new file mode 100644 index 0000000..7a66e18 --- /dev/null +++ b/src/ui/elements/ui_theme.cpp @@ -0,0 +1,207 @@ +#include +#include "ui_theme.h" + +using ThemeColor = recompui::ThemeColor; +using ThemeColorArray = std::array; +using ThemeColorNameArray = std::array; + +constexpr ThemeColorArray get_default_theme_color_array() { + ThemeColorArray colors; + + colors[(std::size_t)ThemeColor::Background1] = recompui::Color{2, 7, 18, 255}; + colors[(std::size_t)ThemeColor::Background2] = recompui::Color{7, 15, 34, 255}; + colors[(std::size_t)ThemeColor::Background3] = recompui::Color{18, 24, 38, 255}; + colors[(std::size_t)ThemeColor::BGOverlay] = recompui::Color{182, 194, 221, 26}; + colors[(std::size_t)ThemeColor::ModalOverlay] = recompui::Color{2, 7, 18, 229}; + + colors[(std::size_t)ThemeColor::BGShadow] = recompui::Color{0, 0, 0, 89}; + colors[(std::size_t)ThemeColor::BGShadow2] = recompui::Color{2, 7, 18, 184}; + + colors[(std::size_t)ThemeColor::Text] = recompui::Color{242, 242, 242, 255}; + colors[(std::size_t)ThemeColor::TextActive] = recompui::Color{245, 245, 245, 255}; + colors[(std::size_t)ThemeColor::TextDim] = recompui::Color{204, 204, 204, 255}; + colors[(std::size_t)ThemeColor::TextInactive] = recompui::Color{255, 255, 255, 153}; + colors[(std::size_t)ThemeColor::TextA5] = recompui::Color{242, 242, 242, 13}; + colors[(std::size_t)ThemeColor::TextA20] = recompui::Color{242, 242, 242, 51}; + colors[(std::size_t)ThemeColor::TextA30] = recompui::Color{242, 242, 242, 77}; + colors[(std::size_t)ThemeColor::TextA50] = recompui::Color{242, 242, 242, 128}; + colors[(std::size_t)ThemeColor::TextA80] = recompui::Color{242, 242, 242, 204}; + + colors[(std::size_t)ThemeColor::Primary] = recompui::Color{29, 93, 226, 255}; + colors[(std::size_t)ThemeColor::PrimaryL] = recompui::Color{167, 191, 241, 255}; + colors[(std::size_t)ThemeColor::PrimaryD] = recompui::Color{0, 38, 117, 255}; + colors[(std::size_t)ThemeColor::PrimaryA5] = recompui::Color{29, 93, 226, 13}; + colors[(std::size_t)ThemeColor::PrimaryA20] = recompui::Color{29, 93, 226, 51}; + colors[(std::size_t)ThemeColor::PrimaryA30] = recompui::Color{29, 93, 226, 77}; + colors[(std::size_t)ThemeColor::PrimaryA50] = recompui::Color{29, 93, 226, 128}; + colors[(std::size_t)ThemeColor::PrimaryA80] = recompui::Color{29, 93, 226, 204}; + + colors[(std::size_t)ThemeColor::Secondary] = recompui::Color{247, 158, 8, 255}; + colors[(std::size_t)ThemeColor::SecondaryL] = recompui::Color{255, 215, 148, 255}; + colors[(std::size_t)ThemeColor::SecondaryD] = recompui::Color{224, 141, 0, 255}; + colors[(std::size_t)ThemeColor::SecondaryA5] = recompui::Color{247, 158, 8, 13}; + colors[(std::size_t)ThemeColor::SecondaryA20] = recompui::Color{247, 158, 8, 51}; + colors[(std::size_t)ThemeColor::SecondaryA30] = recompui::Color{247, 158, 8, 77}; + colors[(std::size_t)ThemeColor::SecondaryA50] = recompui::Color{247, 158, 8, 128}; + colors[(std::size_t)ThemeColor::SecondaryA80] = recompui::Color{247, 158, 8, 204}; + + colors[(std::size_t)ThemeColor::Warning] = recompui::Color{255, 254, 0, 255}; + colors[(std::size_t)ThemeColor::WarningL] = recompui::Color{255, 254, 143, 255}; + colors[(std::size_t)ThemeColor::WarningD] = recompui::Color{197, 163, 2, 255}; + colors[(std::size_t)ThemeColor::WarningA5] = recompui::Color{255, 254, 0, 13}; + colors[(std::size_t)ThemeColor::WarningA20] = recompui::Color{255, 254, 0, 51}; + colors[(std::size_t)ThemeColor::WarningA30] = recompui::Color{255, 254, 0, 77}; + colors[(std::size_t)ThemeColor::WarningA50] = recompui::Color{255, 254, 0, 128}; + colors[(std::size_t)ThemeColor::WarningA80] = recompui::Color{255, 254, 0, 204}; + + colors[(std::size_t)ThemeColor::Danger] = recompui::Color{255, 53, 31, 255}; + colors[(std::size_t)ThemeColor::DangerL] = recompui::Color{255, 149, 138, 255}; + colors[(std::size_t)ThemeColor::DangerD] = recompui::Color{163, 16, 0, 255}; + colors[(std::size_t)ThemeColor::DangerA5] = recompui::Color{255, 53, 31, 13}; + colors[(std::size_t)ThemeColor::DangerA20] = recompui::Color{255, 53, 31, 51}; + colors[(std::size_t)ThemeColor::DangerA30] = recompui::Color{255, 53, 31, 77}; + colors[(std::size_t)ThemeColor::DangerA50] = recompui::Color{255, 53, 31, 128}; + colors[(std::size_t)ThemeColor::DangerA80] = recompui::Color{255, 53, 31, 204}; + + colors[(std::size_t)ThemeColor::Success] = recompui::Color{40, 238, 32, 255}; + colors[(std::size_t)ThemeColor::SuccessL] = recompui::Color{155, 247, 151, 255}; + colors[(std::size_t)ThemeColor::SuccessD] = recompui::Color{18, 157, 12, 255}; + colors[(std::size_t)ThemeColor::SuccessA5] = recompui::Color{40, 238, 32, 13}; + colors[(std::size_t)ThemeColor::SuccessA20] = recompui::Color{40, 238, 32, 51}; + colors[(std::size_t)ThemeColor::SuccessA30] = recompui::Color{40, 238, 32, 77}; + colors[(std::size_t)ThemeColor::SuccessA50] = recompui::Color{40, 238, 32, 128}; + colors[(std::size_t)ThemeColor::SuccessA80] = recompui::Color{40, 238, 32, 204}; + + colors[(std::size_t)ThemeColor::Border] = recompui::Color{255, 255, 255, 51}; + colors[(std::size_t)ThemeColor::BorderSoft] = recompui::Color{255, 255, 255, 26}; + colors[(std::size_t)ThemeColor::BorderHard] = recompui::Color{255, 255, 255, 77}; + colors[(std::size_t)ThemeColor::BorderSolid] = recompui::Color{255, 255, 255, 153}; + + colors[(std::size_t)ThemeColor::Transparent] = recompui::Color{0, 0, 0, 0}; + + colors[(std::size_t)ThemeColor::A] = recompui::Color{51, 51, 255, 255}; + colors[(std::size_t)ThemeColor::AL] = recompui::Color{178, 178, 255, 255}; + colors[(std::size_t)ThemeColor::AD] = recompui::Color{32, 32, 172, 255}; + colors[(std::size_t)ThemeColor::AA5] = recompui::Color{51, 51, 255, 13}; + colors[(std::size_t)ThemeColor::AA20] = recompui::Color{51, 51, 255, 51}; + colors[(std::size_t)ThemeColor::AA30] = recompui::Color{51, 51, 255, 77}; + colors[(std::size_t)ThemeColor::AA50] = recompui::Color{51, 51, 255, 128}; + colors[(std::size_t)ThemeColor::AA80] = recompui::Color{51, 51, 255, 204}; + + colors[(std::size_t)ThemeColor::White] = recompui::Color{255, 255, 255, 255}; + colors[(std::size_t)ThemeColor::WhiteA5] = recompui::Color{255, 255, 255, 13}; + colors[(std::size_t)ThemeColor::WhiteA20] = recompui::Color{255, 255, 255, 51}; + colors[(std::size_t)ThemeColor::WhiteA30] = recompui::Color{255, 255, 255, 77}; + colors[(std::size_t)ThemeColor::WhiteA50] = recompui::Color{255, 255, 255, 128}; + colors[(std::size_t)ThemeColor::WhiteA80] = recompui::Color{255, 255, 255, 204}; + + colors[(std::size_t)ThemeColor::BW05] = recompui::Color{13, 13, 13, 255}; + colors[(std::size_t)ThemeColor::BW10] = recompui::Color{26, 26, 26, 255}; + colors[(std::size_t)ThemeColor::BW25] = recompui::Color{64, 64, 64, 255}; + colors[(std::size_t)ThemeColor::BW50] = recompui::Color{128, 128, 128, 255}; + colors[(std::size_t)ThemeColor::BW75] = recompui::Color{191, 191, 191, 255}; + colors[(std::size_t)ThemeColor::BW90] = recompui::Color{229, 229, 229, 255}; + + return colors; +} + +constexpr ThemeColorNameArray get_default_theme_color_names() { + ThemeColorNameArray names = {}; + names[(std::size_t)ThemeColor::Background1] = "Background1"; + names[(std::size_t)ThemeColor::Background2] = "Background2"; + names[(std::size_t)ThemeColor::Background3] = "Background3"; + names[(std::size_t)ThemeColor::BGOverlay] = "BGOverlay"; + names[(std::size_t)ThemeColor::ModalOverlay] = "ModalOverlay"; + names[(std::size_t)ThemeColor::BGShadow] = "BGShadow"; + names[(std::size_t)ThemeColor::BGShadow2] = "BGShadow2"; + names[(std::size_t)ThemeColor::Text] = "Text"; + names[(std::size_t)ThemeColor::TextActive] = "TextActive"; + names[(std::size_t)ThemeColor::TextDim] = "TextDim"; + names[(std::size_t)ThemeColor::TextInactive] = "TextInactive"; + names[(std::size_t)ThemeColor::TextA5] = "TextA5"; + names[(std::size_t)ThemeColor::TextA20] = "TextA20"; + names[(std::size_t)ThemeColor::TextA30] = "TextA30"; + names[(std::size_t)ThemeColor::TextA50] = "TextA50"; + names[(std::size_t)ThemeColor::TextA80] = "TextA80"; + names[(std::size_t)ThemeColor::Primary] = "Primary"; + names[(std::size_t)ThemeColor::PrimaryL] = "PrimaryL"; + names[(std::size_t)ThemeColor::PrimaryD] = "PrimaryD"; + names[(std::size_t)ThemeColor::PrimaryA5] = "PrimaryA5"; + names[(std::size_t)ThemeColor::PrimaryA20] = "PrimaryA20"; + names[(std::size_t)ThemeColor::PrimaryA30] = "PrimaryA30"; + names[(std::size_t)ThemeColor::PrimaryA50] = "PrimaryA50"; + names[(std::size_t)ThemeColor::PrimaryA80] = "PrimaryA80"; + names[(std::size_t)ThemeColor::Secondary] = "Secondary"; + names[(std::size_t)ThemeColor::SecondaryL] = "SecondaryL"; + names[(std::size_t)ThemeColor::SecondaryD] = "SecondaryD"; + names[(std::size_t)ThemeColor::SecondaryA5] = "SecondaryA5"; + names[(std::size_t)ThemeColor::SecondaryA20] = "SecondaryA20"; + names[(std::size_t)ThemeColor::SecondaryA30] = "SecondaryA30"; + names[(std::size_t)ThemeColor::SecondaryA50] = "SecondaryA50"; + names[(std::size_t)ThemeColor::SecondaryA80] = "SecondaryA80"; + names[(std::size_t)ThemeColor::Warning] = "Warning"; + names[(std::size_t)ThemeColor::WarningL] = "WarningL"; + names[(std::size_t)ThemeColor::WarningD] = "WarningD"; + names[(std::size_t)ThemeColor::WarningA5] = "WarningA5"; + names[(std::size_t)ThemeColor::WarningA20] = "WarningA20"; + names[(std::size_t)ThemeColor::WarningA30] = "WarningA30"; + names[(std::size_t)ThemeColor::WarningA50] = "WarningA50"; + names[(std::size_t)ThemeColor::WarningA80] = "WarningA80"; + names[(std::size_t)ThemeColor::Danger] = "Danger"; + names[(std::size_t)ThemeColor::DangerL] = "DangerL"; + names[(std::size_t)ThemeColor::DangerD] = "DangerD"; + names[(std::size_t)ThemeColor::DangerA5] = "DangerA5"; + names[(std::size_t)ThemeColor::DangerA20] = "DangerA20"; + names[(std::size_t)ThemeColor::DangerA30] = "DangerA30"; + names[(std::size_t)ThemeColor::DangerA50] = "DangerA50"; + names[(std::size_t)ThemeColor::DangerA80] = "DangerA80"; + names[(std::size_t)ThemeColor::Success] = "Success"; + names[(std::size_t)ThemeColor::SuccessL] = "SuccessL"; + names[(std::size_t)ThemeColor::SuccessD] = "SuccessD"; + names[(std::size_t)ThemeColor::SuccessA5] = "SuccessA5"; + names[(std::size_t)ThemeColor::SuccessA20] = "SuccessA20"; + names[(std::size_t)ThemeColor::SuccessA30] = "SuccessA30"; + names[(std::size_t)ThemeColor::SuccessA50] = "SuccessA50"; + names[(std::size_t)ThemeColor::SuccessA80] = "SuccessA80"; + names[(std::size_t)ThemeColor::Border] = "Border"; + names[(std::size_t)ThemeColor::BorderSoft] = "BorderSoft"; + names[(std::size_t)ThemeColor::BorderHard] = "BorderHard"; + names[(std::size_t)ThemeColor::BorderSolid] = "BorderSolid"; + names[(std::size_t)ThemeColor::Transparent] = "Transparent"; + names[(std::size_t)ThemeColor::A] = "A"; + names[(std::size_t)ThemeColor::AL] = "AL"; + names[(std::size_t)ThemeColor::AD] = "AD"; + names[(std::size_t)ThemeColor::AA5] = "AA5"; + names[(std::size_t)ThemeColor::AA20] = "AA20"; + names[(std::size_t)ThemeColor::AA30] = "AA30"; + names[(std::size_t)ThemeColor::AA50] = "AA50"; + names[(std::size_t)ThemeColor::AA80] = "AA80"; + names[(std::size_t)ThemeColor::White] = "White"; + names[(std::size_t)ThemeColor::WhiteA5] = "WhiteA5"; + names[(std::size_t)ThemeColor::WhiteA20] = "WhiteA20"; + names[(std::size_t)ThemeColor::WhiteA30] = "WhiteA30"; + names[(std::size_t)ThemeColor::WhiteA50] = "WhiteA50"; + names[(std::size_t)ThemeColor::WhiteA80] = "WhiteA80"; + names[(std::size_t)ThemeColor::BW05] = "BW05"; + names[(std::size_t)ThemeColor::BW10] = "BW10"; + names[(std::size_t)ThemeColor::BW25] = "BW25"; + names[(std::size_t)ThemeColor::BW50] = "BW50"; + names[(std::size_t)ThemeColor::BW75] = "BW75"; + names[(std::size_t)ThemeColor::BW90] = "BW90"; + return names; +} + +static ThemeColorArray theme_colors = get_default_theme_color_array(); +static ThemeColorNameArray theme_color_names = get_default_theme_color_names(); + +void recompui::set_theme_color(ThemeColor color, const recompui::Color &value) { + theme_colors[(std::size_t)color] = value; +} + +const recompui::Color &recompui::get_theme_color(recompui::ThemeColor color) { + return theme_colors[(std::size_t)color]; +} + +const char *recompui::get_theme_color_name(recompui::ThemeColor color) { + return theme_color_names[(std::size_t)color]; +} diff --git a/src/ui/elements/ui_theme.h b/src/ui/elements/ui_theme.h new file mode 100644 index 0000000..8d57a79 --- /dev/null +++ b/src/ui/elements/ui_theme.h @@ -0,0 +1,95 @@ +#pragma once + +#include "ui_types.h" + +namespace recompui { + enum class ThemeColor { + Background1, + Background2, + Background3, + BGOverlay, + ModalOverlay, + BGShadow, + BGShadow2, + Text, + TextActive, + TextDim, + TextInactive, + TextA5, + TextA20, + TextA30, + TextA50, + TextA80, + Primary, + PrimaryL, + PrimaryD, + PrimaryA5, + PrimaryA20, + PrimaryA30, + PrimaryA50, + PrimaryA80, + Secondary, + SecondaryL, + SecondaryD, + SecondaryA5, + SecondaryA20, + SecondaryA30, + SecondaryA50, + SecondaryA80, + Warning, + WarningL, + WarningD, + WarningA5, + WarningA20, + WarningA30, + WarningA50, + WarningA80, + Danger, + DangerL, + DangerD, + DangerA5, + DangerA20, + DangerA30, + DangerA50, + DangerA80, + Success, + SuccessL, + SuccessD, + SuccessA5, + SuccessA20, + SuccessA30, + SuccessA50, + SuccessA80, + Border, + BorderSoft, + BorderHard, + BorderSolid, + Transparent, + A, + AL, + AD, + AA5, + AA20, + AA30, + AA50, + AA80, + White, + WhiteA5, + WhiteA20, + WhiteA30, + WhiteA50, + WhiteA80, + BW05, + BW10, + BW25, + BW50, + BW75, + BW90, + + size, + }; + + const char *get_theme_color_name(recompui::ThemeColor color); + void set_theme_color(ThemeColor color, const recompui::Color &value); + const recompui::Color &get_theme_color(recompui::ThemeColor color); +} // namespace recompui diff --git a/src/ui/elements/ui_toggle.cpp b/src/ui/elements/ui_toggle.cpp index 983d7ac..7f58c2e 100644 --- a/src/ui/elements/ui_toggle.cpp +++ b/src/ui/elements/ui_toggle.cpp @@ -15,19 +15,19 @@ namespace recompui { set_opacity(0.9f); set_cursor(Cursor::Pointer); set_border_width(2.0f); - set_border_color(Color{ 177, 76, 34, 255 }); - set_background_color(Color{ 0, 0, 0, 0 }); - checked_style.set_border_color(Color{ 34, 177, 76, 255 }); - hover_style.set_border_color(Color{ 177, 76, 34, 255 }); - hover_style.set_background_color(Color{ 206, 120, 68, 76 }); - focus_style.set_border_color(Color{ 177, 76, 34, 255 }); - focus_style.set_background_color(Color{ 206, 120, 68, 76 }); - checked_hover_style.set_border_color(Color{ 34, 177, 76, 255 }); - checked_hover_style.set_background_color(Color{ 68, 206, 120, 76 }); - checked_focus_style.set_border_color(Color{ 34, 177, 76, 255 }); - checked_focus_style.set_background_color(Color{ 68, 206, 120, 76 }); - disabled_style.set_border_color(Color{ 177, 76, 34, 128 }); - checked_disabled_style.set_border_color(Color{ 34, 177, 76, 128 }); + set_border_color(ThemeColor::DangerD); + set_background_color(ThemeColor::Transparent); + checked_style.set_border_color(ThemeColor::Success); + hover_style.set_border_color(ThemeColor::DangerD); + hover_style.set_background_color(ThemeColor::DangerA30); + focus_style.set_border_color(ThemeColor::DangerD); + focus_style.set_background_color(ThemeColor::DangerA30); + checked_hover_style.set_border_color(ThemeColor::Success); + checked_hover_style.set_background_color(ThemeColor::SuccessA30); + checked_focus_style.set_border_color(ThemeColor::Success); + checked_focus_style.set_background_color(ThemeColor::SuccessA30); + disabled_style.set_border_color(ThemeColor::DangerD, 128); + checked_disabled_style.set_border_color(ThemeColor::SuccessD, 128); add_style(&checked_style, checked_state); add_style(&hover_style, hover_state); add_style(&focus_style, focus_state); @@ -44,10 +44,10 @@ namespace recompui { floater->set_width(80.0f); floater->set_height(64.0f); floater->set_border_radius(32.0f); - floater->set_background_color(Color{ 177, 76, 34, 255 }); - floater_checked_style.set_background_color(Color{ 34, 177, 76, 255 }); - floater_disabled_style.set_background_color(Color{ 177, 76, 34, 128 }); - floater_disabled_checked_style.set_background_color(Color{ 34, 177, 76, 128 }); + floater->set_background_color(ThemeColor::DangerD); + floater_checked_style.set_background_color(ThemeColor::Success); + floater_disabled_style.set_background_color(ThemeColor::DangerD, 128); + floater_disabled_checked_style.set_background_color(ThemeColor::SuccessD, 128); floater->add_style(&floater_checked_style, checked_state); floater->add_style(&floater_disabled_style, disabled_state); floater->add_style(&floater_disabled_checked_style, { checked_state, disabled_state }); @@ -158,4 +158,4 @@ namespace recompui { void Toggle::add_checked_callback(std::function callback) { checked_callbacks.emplace_back(callback); } -}; \ No newline at end of file +}; diff --git a/src/ui/elements/ui_types.h b/src/ui/elements/ui_types.h index 08645ea..726b25c 100644 --- a/src/ui/elements/ui_types.h +++ b/src/ui/elements/ui_types.h @@ -1,5 +1,7 @@ #pragma once +#include +#include #include #include @@ -279,4 +281,4 @@ namespace recompui { Auto }; -} // namespace recompui \ No newline at end of file +} // namespace recompui diff --git a/src/ui/ui_color_hack.cpp b/src/ui/ui_color_hack.cpp index cc9b6fd..edc18e4 100644 --- a/src/ui/ui_color_hack.cpp +++ b/src/ui/ui_color_hack.cpp @@ -37,6 +37,13 @@ namespace recompui { html_colours["aqua"] = Rml::Colourb(0, 255, 255); html_colours["transparent"] = Rml::Colourb(0, 0, 0, 0); html_colours["whitesmoke"] = Rml::Colourb(245, 245, 245); + + for (std::size_t i = 0; i < (std::size_t)recompui::ThemeColor::size; i++) { + const char *color_name = recompui::get_theme_color_name((recompui::ThemeColor)i); + const recompui::Color color_value = recompui::get_theme_color((recompui::ThemeColor)i); + Rml::String color_name_lower = Rml::StringUtilities::ToLower(color_name); + html_colours[color_name_lower] = Rml::Colourb(color_value.r, color_value.g, color_value.b, color_value.a); + } } PropertyParserColorHack::~PropertyParserColorHack() {} @@ -166,6 +173,8 @@ namespace recompui { PropertyParserColorHack* new_parser = new PropertyParserColorHack(); // Copy the allocated object into the color parser pointer to overwrite its vtable. memcpy((void*)Rml::StyleSheetSpecification::GetParser("color"), (void*)new_parser, sizeof(*new_parser)); + // TODO: Register the new parser with RmlUi when RmlUi supports custom parsers overrides. + // Rml::StyleSheetSpecification::RegisterParser("color", new_parser); } ColourMap PropertyParserColorHack::html_colours{}; diff --git a/src/ui/ui_config.cpp b/src/ui/ui_config.cpp index f7a00d5..0dbba71 100644 --- a/src/ui/ui_config.cpp +++ b/src/ui/ui_config.cpp @@ -200,8 +200,8 @@ void close_config_menu() { graphics_model_handle.DirtyAllVariables(); close_config_menu_impl(); }, - recompui::ButtonVariant::Success, - recompui::ButtonVariant::Error, + recompui::ButtonStyle::Success, + recompui::ButtonStyle::Danger, true, "config__close-menu-button" ); @@ -221,8 +221,8 @@ void banjo::open_quit_game_prompt() { ultramodern::quit(); }, []() {}, - recompui::ButtonVariant::Error, - recompui::ButtonVariant::Tertiary, + recompui::ButtonStyle::Danger, + recompui::ButtonStyle::Tertiary, true, "config__quit-game-button" ); diff --git a/src/ui/ui_mod_details_panel.cpp b/src/ui/ui_mod_details_panel.cpp index 9606ca3..66d5f22 100644 --- a/src/ui/ui_mod_details_panel.cpp +++ b/src/ui/ui_mod_details_panel.cpp @@ -11,7 +11,7 @@ ModDetailsPanel::ModDetailsPanel(Element *parent) : Element(parent) { set_height(100.0f, Unit::Percent); set_display(Display::Flex); set_flex_direction(FlexDirection::Column); - set_background_color(Color{ 190, 184, 219, 25 }); + set_background_color(ThemeColor::BGOverlay); ContextId context = get_current_context(); @@ -19,9 +19,9 @@ ModDetailsPanel::ModDetailsPanel(Element *parent) : Element(parent) { header_container->set_flex(0.0f, 0.0f); header_container->set_padding(16.0f); header_container->set_gap(16.0f); - header_container->set_background_color(Color{ 0, 0, 0, 89 }); + header_container->set_background_color(ThemeColor::BGShadow); header_container->set_border_bottom_width(1.1f); - header_container->set_border_bottom_color(Color{ 255, 255, 255, 25 }); + header_container->set_border_bottom_color(ThemeColor::BorderSoft); { thumbnail_container = context.create_element(header_container, FlexDirection::Column, JustifyContent::SpaceEvenly); thumbnail_container->set_flex(0.0f, 0.0f); @@ -29,7 +29,7 @@ ModDetailsPanel::ModDetailsPanel(Element *parent) : Element(parent) { thumbnail_image = context.create_element(thumbnail_container, ""); thumbnail_image->set_width(100.0f); thumbnail_image->set_height(100.0f); - thumbnail_image->set_background_color(Color{ 190, 184, 219, 25 }); + thumbnail_image->set_background_color(ThemeColor::BGOverlay); } header_details_container = context.create_element(header_container, FlexDirection::Column, JustifyContent::SpaceEvenly); @@ -56,8 +56,8 @@ ModDetailsPanel::ModDetailsPanel(Element *parent) : Element(parent) { buttons_container->set_padding(16.0f); buttons_container->set_justify_content(JustifyContent::SpaceBetween); buttons_container->set_border_top_width(1.1f); - buttons_container->set_border_top_color(Color{ 255, 255, 255, 25 }); - buttons_container->set_background_color(Color{ 0, 0, 0, 89 }); + buttons_container->set_border_top_color(ThemeColor::BorderSoft); + buttons_container->set_background_color(ThemeColor::BGShadow); { enable_container = context.create_element(buttons_container, FlexDirection::Row, JustifyContent::FlexStart); enable_container->set_align_items(AlignItems::Center); diff --git a/src/ui/ui_mod_menu.cpp b/src/ui/ui_mod_menu.cpp index ed92a7d..ca18455 100644 --- a/src/ui/ui_mod_menu.cpp +++ b/src/ui/ui_mod_menu.cpp @@ -27,9 +27,6 @@ static bool is_mod_enabled_or_auto(const std::string &mod_id) { } // ModEntryView -#define COL_TEXT_DEFAULT 242, 242, 242 -#define COL_TEXT_DIM 204, 204, 204 -#define COL_SECONDARY 23, 214, 232 constexpr float modEntryHeight = 120.0f; constexpr float modEntryPadding = 4.0f; @@ -45,17 +42,17 @@ ModEntryView::ModEntryView(Element *parent) : Element(parent, Events(EventType:: set_height_auto(); set_padding(modEntryPadding); set_border_left_width(2.0f); - set_border_color(Color{ COL_TEXT_DEFAULT, 12 }); - set_background_color(Color{ COL_TEXT_DEFAULT, 12 }); + set_border_color(ThemeColor::BorderSoft); + set_background_color(ThemeColor::BorderSoft); set_cursor(Cursor::Pointer); - set_color(Color{ COL_TEXT_DEFAULT, 255 }); + set_color(ThemeColor::Text); - checked_style.set_border_color(Color{ COL_TEXT_DEFAULT, 160 }); - checked_style.set_color(Color{ 255, 255, 255, 255 }); - checked_style.set_background_color(Color{ 26, 24, 32, 255 }); - hover_style.set_border_color(Color{ COL_TEXT_DEFAULT, 64 }); - checked_hover_style.set_border_color(Color{ COL_TEXT_DEFAULT, 255 }); - pulsing_style.set_border_color(Color{ 23, 214, 232, 244 }); + checked_style.set_border_color(ThemeColor::BorderSolid); + checked_style.set_color(ThemeColor::White); + checked_style.set_background_color(recompui::ThemeColor::Background3); + hover_style.set_border_color(ThemeColor::BorderHard); + checked_hover_style.set_border_color(ThemeColor::Text); + pulsing_style.set_border_color(ThemeColor::SecondaryA80); { thumbnail_image = context.create_element(this, ""); @@ -63,7 +60,7 @@ ModEntryView::ModEntryView(Element *parent) : Element(parent, Events(EventType:: thumbnail_image->set_height(modEntryHeight); thumbnail_image->set_min_width(modEntryHeight); thumbnail_image->set_min_height(modEntryHeight); - thumbnail_image->set_background_color(Color{ 190, 184, 219, 25 }); + thumbnail_image->set_background_color(ThemeColor::BGOverlay); body_container = context.create_element(this); @@ -78,7 +75,7 @@ ModEntryView::ModEntryView(Element *parent) : Element(parent, Events(EventType:: name_label = context.create_element