diff --git a/res/FiraSans-Bold.ttf b/res/FiraSans-Bold.ttf new file mode 100644 index 0000000000..e3593fb0f3 Binary files /dev/null and b/res/FiraSans-Bold.ttf differ diff --git a/res/rml/window.rcss b/res/rml/window.rcss index 197711f2a0..17e4dec6f3 100644 --- a/res/rml/window.rcss +++ b/res/rml/window.rcss @@ -233,6 +233,10 @@ select-button value { font-size: 20dp; } +select-button value.modified { + font-weight: bold; +} + select-button input { text-align: right; font-size: 20dp; diff --git a/src/dusk/ui/bool_button.cpp b/src/dusk/ui/bool_button.cpp index cc43bb8b65..873274758e 100644 --- a/src/dusk/ui/bool_button.cpp +++ b/src/dusk/ui/bool_button.cpp @@ -5,7 +5,14 @@ namespace dusk::ui { BoolButton::BoolButton(Rml::Element* parent, Props props) : BaseControlledSelectButton(parent, {std::move(props.key)}), mGetValue(std::move(props.getValue)), mSetValue(std::move(props.setValue)), - mIsDisabled(std::move(props.isDisabled)) {} + mIsDisabled(std::move(props.isDisabled)), mIsModified(std::move(props.isModified)) {} + +bool BoolButton::modified() const { + if (mIsModified) { + return mIsModified(); + } + return BaseControlledSelectButton::modified(); +} bool BoolButton::disabled() const { if (mIsDisabled) { diff --git a/src/dusk/ui/bool_button.hpp b/src/dusk/ui/bool_button.hpp index 750c7e5cdb..8573efbc23 100644 --- a/src/dusk/ui/bool_button.hpp +++ b/src/dusk/ui/bool_button.hpp @@ -10,10 +10,12 @@ public: std::function getValue; std::function setValue; std::function isDisabled; + std::function isModified; }; BoolButton(Rml::Element* parent, Props props); + bool modified() const override; bool disabled() const override; protected: @@ -24,6 +26,7 @@ private: std::function mGetValue; std::function mSetValue; std::function mIsDisabled; + std::function mIsModified; }; } // namespace dusk::ui diff --git a/src/dusk/ui/number_button.cpp b/src/dusk/ui/number_button.cpp index 7a7488207a..97d16a885f 100644 --- a/src/dusk/ui/number_button.cpp +++ b/src/dusk/ui/number_button.cpp @@ -8,8 +8,16 @@ namespace dusk::ui { NumberButton::NumberButton(Rml::Element* parent, Props props) : BaseStringButton(parent, {.key = std::move(props.key), .type = "number"}), mGetValue(std::move(props.getValue)), mSetValue(std::move(props.setValue)), - mIsDisabled(std::move(props.isDisabled)), mMin(props.min), mMax(props.max), mStep(props.step), - mPrefix(std::move(props.prefix)), mSuffix(std::move(props.suffix)) {} + mIsDisabled(std::move(props.isDisabled)), mIsModified(std::move(props.isModified)), + mMin(props.min), mMax(props.max), mStep(props.step), mPrefix(std::move(props.prefix)), + mSuffix(std::move(props.suffix)) {} + +bool NumberButton::modified() const { + if (mIsModified) { + return mIsModified(); + } + return BaseStringButton::modified(); +} bool NumberButton::disabled() const { if (mIsDisabled) { diff --git a/src/dusk/ui/number_button.hpp b/src/dusk/ui/number_button.hpp index d7b6bbc939..29d36d682d 100644 --- a/src/dusk/ui/number_button.hpp +++ b/src/dusk/ui/number_button.hpp @@ -11,6 +11,7 @@ public: std::function getValue; std::function setValue; std::function isDisabled; + std::function isModified; int min = 0; int max = INT_MAX; int step = 1; @@ -20,6 +21,7 @@ public: NumberButton(Rml::Element* parent, Props props); + bool modified() const override; bool disabled() const override; protected: @@ -32,6 +34,7 @@ private: std::function mGetValue; std::function mSetValue; std::function mIsDisabled; + std::function mIsModified; int mMin; int mMax; int mStep; diff --git a/src/dusk/ui/popup.cpp b/src/dusk/ui/popup.cpp index a0cd3c6868..461db91fc6 100644 --- a/src/dusk/ui/popup.cpp +++ b/src/dusk/ui/popup.cpp @@ -23,7 +23,7 @@ const Rml::String kDocumentSource = R"RML( - + )RML"; diff --git a/src/dusk/ui/select_button.cpp b/src/dusk/ui/select_button.cpp index 95cffd873d..73742a60c2 100644 --- a/src/dusk/ui/select_button.cpp +++ b/src/dusk/ui/select_button.cpp @@ -2,6 +2,7 @@ #include "ui.hpp" +#include #include namespace dusk::ui { @@ -23,9 +24,29 @@ SelectButton::SelectButton(Rml::Element* parent, Props props) on_nav_command([this](Rml::Event&, NavCommand cmd) { return handle_nav_command(cmd); }); } +bool SelectButton::modified() const { + return mProps.modified; +} + +void SelectButton::set_modified(bool value) { + if (mProps.modified != value) { + mValueElem->SetClass("modified", value); + if (value) { + mValueElem->SetInnerRML(fmt::format("• {}", escape(mProps.value))); + } else { + mValueElem->SetInnerRML(escape(mProps.value)); + } + mProps.modified = value; + } +} + void SelectButton::set_value_label(const Rml::String& value) { if (mProps.value != value) { - mValueElem->SetInnerRML(escape(value)); + if (mProps.modified) { + mValueElem->SetInnerRML(fmt::format("• {}", escape(value))); + } else { + mValueElem->SetInnerRML(escape(value)); + } mProps.value = value; } } @@ -35,6 +56,7 @@ void SelectButton::update_props(Props props) { mKeyElem->SetInnerRML(escape(props.key)); } set_value_label(props.value); + set_modified(props.modified); mProps = std::move(props); } @@ -49,9 +71,17 @@ bool SelectButton::handle_nav_command(NavCommand cmd) { void BaseControlledSelectButton::update() { set_disabled(disabled()); set_value_label(format_value()); + set_modified(modified()); SelectButton::update(); } +bool ControlledSelectButton::modified() const { + if (mIsModified) { + return mIsModified(); + } + return BaseControlledSelectButton::modified(); +} + bool ControlledSelectButton::disabled() const { if (mIsDisabled) { return mIsDisabled(); diff --git a/src/dusk/ui/select_button.hpp b/src/dusk/ui/select_button.hpp index 4a9612076d..4640f7235f 100644 --- a/src/dusk/ui/select_button.hpp +++ b/src/dusk/ui/select_button.hpp @@ -10,10 +10,13 @@ public: struct Props { Rml::String key; Rml::String value; + bool modified = false; }; SelectButton(Rml::Element* parent, Props props); + virtual bool modified() const; + void set_modified(bool value); void set_value_label(const Rml::String& value); protected: @@ -23,7 +26,6 @@ protected: Props mProps; Rml::Element* mKeyElem = nullptr; Rml::Element* mValueElem = nullptr; - std::function mOnHover; }; class BaseControlledSelectButton : public SelectButton { @@ -43,12 +45,15 @@ public: Rml::String key; std::function getValue; std::function isDisabled; + std::function isModified; }; ControlledSelectButton(Rml::Element* parent, Props props) : BaseControlledSelectButton(parent, {std::move(props.key)}), - mGetValue(std::move(props.getValue)), mIsDisabled(std::move(props.isDisabled)) {} + mGetValue(std::move(props.getValue)), mIsDisabled(std::move(props.isDisabled)), + mIsModified(std::move(props.isModified)) {} + bool modified() const override; bool disabled() const override; protected: @@ -56,6 +61,7 @@ protected: std::function mGetValue; std::function mIsDisabled; + std::function mIsModified; }; } // namespace dusk::ui diff --git a/src/dusk/ui/settings.cpp b/src/dusk/ui/settings.cpp index 2cdb2d50d9..1f32071d37 100644 --- a/src/dusk/ui/settings.cpp +++ b/src/dusk/ui/settings.cpp @@ -81,8 +81,7 @@ struct ConfigBoolProps { SelectButton& config_bool_select( Pane& leftPane, Pane& rightPane, ConfigVar& var, ConfigBoolProps props) { return leftPane - .add_child(BoolButton::Props{ - .key = std::move(props.key), + .add_child(BoolButton::Props{.key = std::move(props.key), .getValue = [&var] { return var.getValue(); }, .setValue = [&var, callback = std::move(props.onChange)](bool value) { @@ -96,7 +95,7 @@ SelectButton& config_bool_select( } }, .isDisabled = std::move(props.isDisabled), - }) + .isModified = [&var] { return var.getValue() != var.getDefaultValue(); }}) .on_focus([&rightPane, helpText = std::move(props.helpText)](Rml::Event&) { rightPane.clear(); rightPane.add_rml(helpText); @@ -116,6 +115,7 @@ SelectButton& config_percent_select(Pane& leftPane, Pane& rightPane, ConfigVar(getSettings().game.bloomMode.getValue())); }, + .isModified = + [] { + return getSettings().game.bloomMode.getValue() != + getSettings().game.bloomMode.getDefaultValue(); + }, }) .on_nav_command([](Rml::Event&, NavCommand cmd) { if (cmd == NavCommand::Confirm || cmd == NavCommand::Left || @@ -559,6 +584,11 @@ SettingsWindow::SettingsWindow() { }, .isDisabled = [] { return getSettings().game.bloomMode.getValue() == BloomMode::Off; }, + .isModified = + [] { + return getSettings().game.bloomMultiplier.getValue() != + getSettings().game.bloomMultiplier.getDefaultValue(); + }, }) .on_nav_command([](Rml::Event&, NavCommand cmd) { if (cmd == NavCommand::Confirm || cmd == NavCommand::Left || @@ -619,7 +649,6 @@ SettingsWindow::SettingsWindow() { "- Account Username" }); #endif - leftPane.add_section("Advanced"); config_bool_select(leftPane, rightPane, getSettings().backend.skipPreLaunchUI, { .key = "Skip Pre-Launch UI", diff --git a/src/dusk/ui/ui.cpp b/src/dusk/ui/ui.cpp index a0764ecf08..10a62436b5 100644 --- a/src/dusk/ui/ui.cpp +++ b/src/dusk/ui/ui.cpp @@ -33,6 +33,7 @@ bool initialize() noexcept { } load_font("FiraSans-Regular.ttf", true); + load_font("FiraSans-Bold.ttf"); load_font("FiraSansCondensed-Regular.ttf"); load_font("FiraSansCondensed-Bold.ttf"); load_font("AlegreyaSC-Regular.ttf");