From ecd74a4cbd68abbf50975851867e6f411dcf70c0 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Wed, 29 Apr 2026 19:54:37 -0600 Subject: [PATCH] More settings/editor components --- res/rml/window.rcss | 25 ++- src/dusk/ui/component.hpp | 4 + src/dusk/ui/editor.cpp | 292 +++++++++++++++++++++++++++++++--- src/dusk/ui/select_button.cpp | 53 ++++-- src/dusk/ui/select_button.hpp | 15 +- src/dusk/ui/settings.cpp | 158 +++++++++++++----- src/dusk/ui/window.cpp | 3 +- src/m_Do/m_Do_main.cpp | 4 +- 8 files changed, 464 insertions(+), 90 deletions(-) diff --git a/res/rml/window.rcss b/res/rml/window.rcss index dca04cb1e9..28d01db8ec 100644 --- a/res/rml/window.rcss +++ b/res/rml/window.rcss @@ -120,12 +120,15 @@ button { transition: background-color 0.1s linear-in-out, opacity 0.1s linear-in-out; } -.button.active, .button:hover, .button:focus-visible { +.button:not(:disabled).active, +.button:not(:disabled):hover, +.button:not(:disabled):focus-visible { background-color: rgba(204, 184, 119, 20%); box-shadow: #C2A42D 0 0 0 2dp; } -.button.selected, .button:active { +.button:not(:disabled).selected, +.button:not(:disabled):active { opacity: 1; background-color: rgba(204, 184, 119, 40%); box-shadow: #C2A42D 0 0 0 2dp; @@ -143,25 +146,39 @@ button { transition: background-color 0.1s linear-in-out, opacity 0.1s linear-in-out; } -.select-button.active, .select-button:hover, .select-button:focus-visible { +.select-button:not(:disabled).active, +.select-button:not(:disabled):hover, +.select-button:not(:disabled):focus-visible { background-color: rgba(204, 184, 119, 20%); box-shadow: #C2A42D 0 0 0 2dp; } -.select-button.selected, .select-button:active { +.select-button:not(:disabled).selected, +.select-button:not(:disabled):active { opacity: 1; background-color: rgba(204, 184, 119, 40%); box-shadow: #C2A42D 0 0 0 2dp; } +.select-button:disabled { + opacity: 0.35; + cursor: default; +} + .select-button .key { font-family: "Fira Sans Condensed"; font-weight: bold; font-size: 18dp; text-transform: uppercase; + flex: 1 0 auto; } .select-button .value { margin-left: auto; font-size: 20dp; } + +.select-button input { + text-align: right; + font-size: 20dp; +} diff --git a/src/dusk/ui/component.hpp b/src/dusk/ui/component.hpp index a90aad45af..79f09dd4ad 100644 --- a/src/dusk/ui/component.hpp +++ b/src/dusk/ui/component.hpp @@ -5,6 +5,7 @@ #include #include +#include #include namespace Rml { @@ -27,6 +28,9 @@ public: void listen(Rml::Element* element, Rml::EventId event, ScopedEventListener::Callback callback, bool capture = false); + void listen(Rml::EventId event, ScopedEventListener::Callback callback, bool capture = false) { + listen(mRoot, event, std::move(callback), capture); + } bool contains(Rml::Element* element) const; template diff --git a/src/dusk/ui/editor.cpp b/src/dusk/ui/editor.cpp index 5a0c8464a4..d6818e3604 100644 --- a/src/dusk/ui/editor.cpp +++ b/src/dusk/ui/editor.cpp @@ -9,6 +9,8 @@ #include "pane.hpp" #include "select_button.hpp" +#include + namespace dusk::ui { namespace { aurora::Module Log{"dusk::ui::editor"}; @@ -26,18 +28,26 @@ dSv_player_status_a_c* get_player_status() { Rml::String get_player_name() { if (!has_save_data()) { - return "Link"; + return ""; } return dComIfGs_getPlayerName(); } +void set_player_name(Rml::String name) { + dComIfGs_setPlayerName(name.c_str()); +} + Rml::String get_horse_name() { if (!has_save_data()) { - return "Epona"; + return ""; } return dComIfGs_getHorseName(); } +void set_horse_name(Rml::String name) { + dComIfGs_setHorseName(name.c_str()); +} + Rml::String value_for_player_selection(const Rml::String& selection) { dSv_player_status_a_c* status = get_player_status(); if (selection == "get_horse_name") { @@ -171,43 +181,275 @@ bool handle_editor_action(const Rml::VariantList& arguments) { } // namespace +class ControlledSelectButton : public SelectButton { +public: + ControlledSelectButton(Rml::Element* parent, Props props) + : SelectButton(parent, std::move(props)) {} + + void update() override { + set_disabled(is_disabled()); + set_value_label(format_value()); + SelectButton::update(); + } + +protected: + virtual Rml::String format_value() = 0; + virtual bool is_disabled() { return false; } +}; + +class BaseStringButton : public ControlledSelectButton { +public: + struct Props { + Rml::String key; + Rml::String type = "text"; + int maxLength = -1; + }; + + BaseStringButton(Rml::Element* parent, Props props) + : ControlledSelectButton(parent, {std::move(props.key)}), mType(std::move(props.type)), + mMaxLength(props.maxLength) { + mInputListeners.reserve(3); + } + + void update() override { + if (mPendingStopEditing) { + stop_editing(mPendingCommit, mPendingRefocusRoot); + } + ControlledSelectButton::update(); + } + + void start_editing() { + if (mInputElem != nullptr) { + return; + } + auto* doc = mRoot->GetOwnerDocument(); + auto elemPtr = doc->CreateElement("input"); + mInputElem = rmlui_dynamic_cast(elemPtr.get()); + if (mInputElem == nullptr) { + return; + } + mInputElem->SetAttribute("type", mType); + mInputElem->SetAttribute("value", format_value()); + if (mMaxLength > -1) { + mInputElem->SetAttribute("maxlength", mMaxLength); + } + mRoot->AppendChild(std::move(elemPtr)); + mValueElem->SetProperty(Rml::PropertyId::Visibility, Rml::Style::Visibility::Hidden); + mInputElem->Focus(true); + const int end = static_cast(Rml::StringUtilities::LengthUTF8(mInputElem->GetValue())); + mInputElem->SetSelectionRange(0, end); + set_selected(true); + mInputListeners.emplace_back(std::make_unique( + mInputElem, Rml::EventId::Keydown, [this](Rml::Event& event) { + const auto cmd = map_nav_event(event); + if (cmd == NavCommand::Confirm) { + request_stop_editing(true, true); + event.StopImmediatePropagation(); + } else if (cmd == NavCommand::Cancel) { + request_stop_editing(false, true); + event.StopImmediatePropagation(); + } + })); + mInputListeners.emplace_back(std::make_unique( + mInputElem, Rml::EventId::Click, [](Rml::Event& event) { event.StopPropagation(); })); + mInputListeners.emplace_back(std::make_unique(mInputElem, + Rml::EventId::Blur, [this](Rml::Event&) { request_stop_editing(true, false); })); + } + + void request_stop_editing(bool commit, bool refocusRoot) { + mPendingStopEditing = true; + mPendingCommit = commit; + mPendingRefocusRoot = refocusRoot; + } + +protected: + bool handle_nav_command(NavCommand cmd) override { + if (cmd == NavCommand::Confirm) { + if (mInputElem == nullptr) { + start_editing(); + } else { + request_stop_editing(true, true); + } + return true; + } else if (cmd == NavCommand::Cancel) { + request_stop_editing(false, true); + return true; + } + return false; + } + + virtual void set_value(Rml::String value) = 0; + +private: + void stop_editing(bool commit = true, bool refocusRoot = false) { + if (mInputElem == nullptr) { + return; + } + mPendingStopEditing = false; + if (commit) { + set_value(mInputElem->GetValue()); + } + mInputListeners.clear(); + mRoot->RemoveChild(mInputElem); + mInputElem = nullptr; + mValueElem->SetProperty(Rml::PropertyId::Visibility, Rml::Style::Visibility::Visible); + set_selected(false); + if (refocusRoot) { + mRoot->Focus(true); + } + } + + Rml::ElementFormControlInput* mInputElem = nullptr; + std::vector > mInputListeners; + Rml::String mType; + int mMaxLength; + bool mPendingStopEditing = false; + bool mPendingCommit = true; + bool mPendingRefocusRoot = false; +}; + +class StringButton : public BaseStringButton { +public: + struct Props { + Rml::String key; + std::function getValue; + std::function setValue; + int maxLength = -1; + }; + + StringButton(Rml::Element* parent, Props props) + : BaseStringButton(parent, + { + .key = std::move(props.key), + .maxLength = props.maxLength, + }), + mGetValue(std::move(props.getValue)), mSetValue(std::move(props.setValue)) {} + +protected: + Rml::String format_value() override { return mGetValue(); } + void set_value(Rml::String value) override { + if (mSetValue) { + mSetValue(std::move(value)); + } + } + +private: + std::function mGetValue; + std::function mSetValue; +}; + +struct IntSelectProps { + Rml::String key; + std::function getValue; + std::function setValue; + int min = 0; + int max = INT_MAX; + int step = 1; +}; + +class IntSelectButton : public BaseStringButton { +public: + using Props = IntSelectProps; + + IntSelectButton(Rml::Element* parent, Props props) + : BaseStringButton(parent, {.key = std::move(props.key), .type = "number"}), + mGetValue(std::move(props.getValue)), mSetValue(std::move(props.setValue)), + mMin(props.min), mMax(props.max), mStep(props.step) {} + +protected: + Rml::String format_value() override { return fmt::to_string(mGetValue()); } + void set_value(Rml::String value) override { + if (!mSetValue) { + return; + } + + int parsedValue = 0; + const char* begin = value.data(); + const char* end = begin + value.size(); + const auto result = std::from_chars(begin, end, parsedValue); + if (result.ec != std::errc() || result.ptr != end) { + return; + } + + mSetValue(std::clamp(parsedValue, mMin, mMax)); + } + + bool handle_nav_command(NavCommand cmd) override { + if (cmd == NavCommand::Left) { + mSetValue(std::clamp(mGetValue() - mStep, mMin, mMax)); + return true; + } else if (cmd == NavCommand::Right) { + mSetValue(std::clamp(mGetValue() + mStep, mMin, mMax)); + return true; + } + return BaseStringButton::handle_nav_command(cmd); + } + +private: + std::function mGetValue; + std::function mSetValue; + int mMin; + int mMax; + int mStep; +}; + EditorWindow::EditorWindow() { add_tab("Player Status", [this](Rml::Element* content) { auto& leftPane = add_child(content, Pane::Direction::Vertical); + auto& rightPane = add_child(content, Pane::Direction::Vertical); + leftPane.add_section("Player"); - leftPane.add_select_button({ - .key = "Player Name", - .getValue = get_player_name, - }); - leftPane.add_select_button({ - .key = "Horse Name", - .getValue = get_horse_name, - }); - leftPane.add_select_button({ - .key = "Max Health", - .getValue = [] { return value_for_player_selection("max_health"); }, - }); - leftPane.add_select_button({ - .key = "Max Oil", - .getValue = [] { return value_for_player_selection("max_oil"); }, - }); - leftPane.add_select_button({ - .key = "Oil", - .getValue = [] { return value_for_player_selection("oil"); }, - }); + leftPane.add_child(leftPane.root(), StringButton::Props{ + .key = "Player Name", + .getValue = get_player_name, + .setValue = set_player_name, + .maxLength = 16, + }); + leftPane.add_child(leftPane.root(), StringButton::Props{ + .key = "Horse Name", + .getValue = get_horse_name, + .setValue = set_horse_name, + .maxLength = 16, + }); + leftPane.add_child(leftPane.root(), + IntSelectButton::Props{ + .key = "Max Health", + .getValue = [] { return get_player_status()->getMaxLife(); }, + .setValue = [](int value) { return get_player_status()->setMaxLife(value); }, + .max = UINT16_MAX, // TODO: actual max + }); + leftPane.add_child(leftPane.root(), + IntSelectButton::Props{ + .key = "Health", + .getValue = [] { return get_player_status()->getLife(); }, + .setValue = [](int value) { return get_player_status()->setLife(value); }, + .max = UINT16_MAX, // TODO: actual max + }); + leftPane.add_child(leftPane.root(), + IntSelectButton::Props{ + .key = "Max Oil", + .getValue = [] { return get_player_status()->getMaxOil(); }, + .setValue = [](int value) { return get_player_status()->setMaxOil(value); }, + .max = UINT16_MAX, // TODO: actual max + }); + leftPane.add_child(leftPane.root(), + IntSelectButton::Props{ + .key = "Oil", + .getValue = [] { return get_player_status()->getOil(); }, + .setValue = [](int value) { return get_player_status()->setOil(value); }, + .max = UINT16_MAX, // TODO: actual max + }); + leftPane.add_section("Equipment"); leftPane.add_select_button({ .key = "Equip X", .value = "TODO", - .selected = true, }); leftPane.add_select_button({ .key = "Equip Y", .value = "TODO", - .selected = false, }); - auto& rightPane = add_child(content, Pane::Direction::Vertical); rightPane.add_button({ .text = "Hello, world!", }); diff --git a/src/dusk/ui/select_button.cpp b/src/dusk/ui/select_button.cpp index 0d5fa56a4d..9413124926 100644 --- a/src/dusk/ui/select_button.cpp +++ b/src/dusk/ui/select_button.cpp @@ -23,17 +23,29 @@ SelectButton::SelectButton(Rml::Element* parent, Props props) : Component(create mValueElem->SetClass("value", true); update_props(std::move(props)); listen(mRoot, Rml::EventId::Click, [this](Rml::Event& event) { - if (mProps.onPressed) { - mProps.onPressed(*this, event); + if (mProps.disabled) { + return; + } + if (handle_nav_command(NavCommand::Confirm)) { + event.StopPropagation(); + } + }); + listen(mRoot, Rml::EventId::Keydown, [this](Rml::Event& event) { + if (mProps.disabled) { + return; + } + const auto cmd = map_nav_event(event); + if (cmd != NavCommand::None && handle_nav_command(cmd)) { + event.StopPropagation(); } }); } -void SelectButton::update() { - if (mProps.getValue) { - set_value(mProps.getValue()); +bool SelectButton::focus() { + if (mProps.disabled) { + return false; } - Component::update(); + return Component::focus(); } void SelectButton::set_selected(bool selected) { @@ -43,7 +55,21 @@ void SelectButton::set_selected(bool selected) { } } -void SelectButton::set_value(const Rml::String& value) { +void SelectButton::set_disabled(bool disabled) { + if (mProps.disabled != disabled) { + if (disabled) { + mRoot->SetAttribute("disabled", ""); + mRoot->SetPseudoClass("disabled", true); + mRoot->Blur(); + } else { + mRoot->RemoveAttribute("disabled"); + mRoot->SetPseudoClass("disabled", false); + } + mProps.disabled = disabled; + } +} + +void SelectButton::set_value_label(const Rml::String& value) { if (mProps.value != value) { mValueElem->SetInnerRML(escape(value)); mProps.value = value; @@ -54,9 +80,18 @@ void SelectButton::update_props(Props props) { if (mProps.key != props.key) { mKeyElem->SetInnerRML(escape(props.key)); } - set_value(props.value); + set_value_label(props.value); set_selected(props.selected); + set_disabled(props.disabled); mProps = std::move(props); } -} // namespace dusk::ui \ No newline at end of file +bool SelectButton::handle_nav_command(NavCommand cmd) { + if (cmd == NavCommand::Confirm) { + set_selected(!get_selected()); + return true; + } + return false; +} + +} // namespace dusk::ui diff --git a/src/dusk/ui/select_button.hpp b/src/dusk/ui/select_button.hpp index f717c6bb5e..880f2fbb55 100644 --- a/src/dusk/ui/select_button.hpp +++ b/src/dusk/ui/select_button.hpp @@ -1,6 +1,7 @@ #pragma once #include "component.hpp" +#include "ui.hpp" namespace dusk::ui { @@ -9,9 +10,8 @@ class SelectButton; struct SelectButtonProps { Rml::String key; Rml::String value; - std::function getValue; - std::function onPressed; bool selected = false; + bool disabled = false; }; class SelectButton : public Component { @@ -20,19 +20,22 @@ public: SelectButton(Rml::Element* parent, SelectButtonProps props); - void update() override; + bool focus() override; void set_selected(bool selected); bool get_selected() const { return mProps.selected; } + void set_disabled(bool disabled); + bool get_disabled() const { return mProps.disabled; } - void set_value(const Rml::String& value); + void set_value_label(const Rml::String& value); -private: +protected: void update_props(Props props); + virtual bool handle_nav_command(NavCommand cmd); SelectButtonProps mProps; Rml::Element* mKeyElem = nullptr; Rml::Element* mValueElem = nullptr; }; -} // namespace dusk::ui \ No newline at end of file +} // namespace dusk::ui diff --git a/src/dusk/ui/settings.cpp b/src/dusk/ui/settings.cpp index fd80ba5340..0d45837579 100644 --- a/src/dusk/ui/settings.cpp +++ b/src/dusk/ui/settings.cpp @@ -8,6 +8,8 @@ #include "pane.hpp" #include "ui.hpp" +#include + namespace dusk::ui { template @@ -15,81 +17,109 @@ struct ConfigProps { Rml::String key; ConfigVar* value; std::function onChange; + std::function isDisabled; Rml::String helpText; Pane* rightPane = nullptr; - bool selected = false; }; -class ConfigBoolSelect : public SelectButton { +template +class ConfigSelect : public SelectButton { public: - using Props = ConfigProps; + using Props = ConfigProps; - ConfigBoolSelect(Rml::Element* parent, Props props) - : SelectButton( - parent, { - .key = std::move(props.key), - .getValue = [this] { return mValue->getValue() ? "On" : "Off"; }, - .onPressed = [this](SelectButton&, Rml::Event&) { toggle_value(); }, - .selected = props.selected, - }), - mValue(props.value), onChange(std::move(props.onChange)), + ConfigSelect(Rml::Element* parent, Props props) + : SelectButton(parent, {std::move(props.key)}), mVar(props.value), + mOnChange(std::move(props.onChange)), mIsDisabled(std::move(props.isDisabled)), mHelpText(std::move(props.helpText)), mRightPane(props.rightPane) { if (!mHelpText.empty() && mRightPane != nullptr) { - listen(nullptr, Rml::EventId::Focus, [this](Rml::Event&) { + listen(Rml::EventId::Focus, [this](Rml::Event&) { mRightPane->clear(); mRightPane->add_text(mHelpText); }); - listen(nullptr, Rml::EventId::Mouseover, [this](Rml::Event&) { + listen(Rml::EventId::Mouseover, [this](Rml::Event&) { mRightPane->clear(); mRightPane->add_text(mHelpText); }); } - listen(nullptr, Rml::EventId::Keydown, [this](Rml::Event& event) { - const auto cmd = map_nav_event(event); - if (cmd == NavCommand::Left || cmd == NavCommand::Right || cmd == NavCommand::Confirm) { - toggle_value(); - event.StopPropagation(); - } - }); } -private: - void toggle_value() { - const bool newValue = !mValue->getValue(); - mValue->setValue(newValue); - if (onChange) { - onChange(newValue); + void update() override { + if (mIsDisabled) { + set_disabled(mIsDisabled()); + } + set_value_label(get_value()); + SelectButton::update(); + } + +protected: + virtual Rml::String get_value() = 0; + + void set_value(T newValue) { + if (mVar->getValue() == newValue) { + return; + } + mVar->setValue(newValue); + if (mOnChange) { + mOnChange(newValue); } config::Save(); } - ConfigVar* mValue; - std::function onChange; + ConfigVar* mVar; + std::function mOnChange; + std::function mIsDisabled; Rml::String mHelpText; Pane* mRightPane; }; +class ConfigBoolSelect : public ConfigSelect { +public: + ConfigBoolSelect(Rml::Element* parent, Props props) : ConfigSelect(parent, std::move(props)) {} + +protected: + Rml::String get_value() override { return mVar->getValue() ? "On" : "Off"; } + bool handle_nav_command(NavCommand cmd) override { + if (cmd == NavCommand::Confirm || cmd == NavCommand::Left || cmd == NavCommand::Right) { + set_value(!mVar->getValue()); + return true; + } + return false; + } +}; + +class ConfigIntPercentSelect : public ConfigSelect { +public: + ConfigIntPercentSelect(Rml::Element* parent, Props props) + : ConfigSelect(parent, std::move(props)) {} + +protected: + Rml::String get_value() override { return fmt::format("{}%", mVar->getValue()); } + bool handle_nav_command(NavCommand cmd) override { + if (cmd == NavCommand::Left) { + set_value(std::max(mVar->getValue() - 1, 0)); + return true; + } else if (cmd == NavCommand::Right) { + set_value(std::min(mVar->getValue() + 1, 100)); + return true; + } + return false; + } +}; + SettingsWindow::SettingsWindow() { add_tab("Audio", [this](Rml::Element* content) { auto& leftPane = add_child(content, Pane::Direction::Vertical); auto& rightPane = add_child(content, Pane::Direction::Vertical); leftPane.add_section("Volume"); - { - auto& btn = leftPane.add_select_button({ + leftPane.add_child(leftPane.root(), + ConfigIntPercentSelect::Props{ .key = "Master Volume", - .getValue = - [] { return fmt::format("{}%", getSettings().audio.masterVolume.getValue()); }, + .value = &getSettings().audio.masterVolume, + .onChange = [](int value) { audio::SetMasterVolume(value / 100.f); }, + .helpText = "Adjusts the volume of all sounds in the game.", + .rightPane = &rightPane, }); - btn.listen(nullptr, Rml::EventId::Focus, [&](Rml::Event&) { - rightPane.clear(); - rightPane.add_text("Adjusts the volume of all sounds in the game."); - }); - btn.listen(nullptr, Rml::EventId::Mouseover, [&](Rml::Event&) { - rightPane.clear(); - rightPane.add_text("Adjusts the volume of all sounds in the game."); - }); - } leftPane.add_section("Effects"); leftPane.add_child( @@ -119,7 +149,49 @@ SettingsWindow::SettingsWindow() { }); add_tab("Cheats", [this](Rml::Element* content) { + auto& leftPane = add_child(content, Pane::Direction::Vertical); + auto& rightPane = add_child(content, Pane::Direction::Vertical); + auto addCheat = [&](const Rml::String& key, ConfigVar& value, + const Rml::String& helpText) { + leftPane.add_child( + leftPane.root(), ConfigBoolSelect::Props{ + .key = key, + .value = &value, + .isDisabled = [] { return !getSettings().game.speedrunMode; }, + .helpText = helpText, + .rightPane = &rightPane, + }); + }; + + leftPane.add_section("Resources"); + addCheat("Infinite Hearts", getSettings().game.infiniteHearts, "Keeps your health full."); + addCheat( + "Infinite Arrows", getSettings().game.infiniteArrows, "Keeps your arrow count full."); + addCheat("Infinite Bombs", getSettings().game.infiniteBombs, "Keeps all bomb bags full."); + addCheat("Infinite Oil", getSettings().game.infiniteOil, "Keeps your lantern oil full."); + addCheat("Infinite Oxygen", getSettings().game.infiniteOxygen, + "Keeps your underwater oxygen meter full."); + addCheat( + "Infinite Rupees", getSettings().game.infiniteRupees, "Keeps your rupee count full."); + addCheat("No Item Timer", getSettings().game.enableIndefiniteItemDrops, + "Item drops such as rupees and hearts will never disappear after they drop."); + + leftPane.add_section("Abilities"); + addCheat( + "Moon Jump (R+A)", getSettings().game.moonJump, "Hold R and A to rise into the air."); + addCheat("Super Clawshot", getSettings().game.superClawshot, + "Extends clawshot behavior beyond the normal game rules."); + addCheat("Always Greatspin", getSettings().game.alwaysGreatspin, + "Allows the Great Spin attack without requiring full health."); + addCheat("Fast Iron Boots", getSettings().game.enableFastIronBoots, + "Speeds up movement while wearing the Iron Boots."); + addCheat("Can Transform Anywhere", getSettings().game.canTransformAnywhere, + "Allows transforming even if NPCs are looking."); + addCheat("Fast Spinner", getSettings().game.fastSpinner, + "Speeds up Spinner movement while holding R."); + addCheat("Free Magic Armor", getSettings().game.freeMagicArmor, + "Lets the magic armor work without consuming rupees."); }); add_tab("Gameplay", [this](Rml::Element* content) { @@ -177,4 +249,4 @@ SettingsWindow::SettingsWindow() { }); } -} // namespace dusk::ui \ No newline at end of file +} // namespace dusk::ui diff --git a/src/dusk/ui/window.cpp b/src/dusk/ui/window.cpp index f7532393e1..4f5635aefa 100644 --- a/src/dusk/ui/window.cpp +++ b/src/dusk/ui/window.cpp @@ -9,7 +9,6 @@ #include "ui.hpp" namespace dusk::ui { -static aurora::Module Log{"dusk::ui::window"}; Window::Window() { auto* context = aurora::rmlui::get_context(); @@ -115,6 +114,7 @@ void Window::add_tab(const Rml::String& title, TabBuilder builder) { }); if (index == mSelectedTabIndex && builder) { builder(mDocument->GetElementById("content")); + focus_active_tab(); } } @@ -176,6 +176,7 @@ bool Window::handle_tab_bar_nav(Rml::Event& event, NavCommand cmd) noexcept { } return false; } + bool Window::handle_content_nav(Rml::Event& event, NavCommand cmd) noexcept { if (cmd == NavCommand::Up || cmd == NavCommand::Cancel) { return focus_active_tab(); diff --git a/src/m_Do/m_Do_main.cpp b/src/m_Do/m_Do_main.cpp index e6ae5a6d42..6ec5d0f2f4 100644 --- a/src/m_Do/m_Do_main.cpp +++ b/src/m_Do/m_Do_main.cpp @@ -590,9 +590,9 @@ int game_main(int argc, char* argv[]) { // TODO: just for testing auto& editorWindow = dusk::ui::add_window(std::make_unique()); - // editorWindow.show(); + editorWindow.show(); auto& settingsWindow = dusk::ui::add_window(std::make_unique()); - settingsWindow.show(); + // settingsWindow.show(); std::string dvd_path; bool dvd_opened = false;