Files
dusklight/src/dusk/ui/component.cpp
T
Irastris 08321699cd Display the real title screen behind the prelaunch menu (#638)
* Start game execution as soon as a disk image is available

* Do not update dDemo_c if prelaunch document is visible

* Prevent intro music until prelaunch has popped

* Replace "Start Game" references with "Play"

* Make prelaunch layout respect mirror mode

* Add drop shadow to prelaunch disk-status and version-info

* Remove ImGui prelaunch

* Add "Change Disk Image" button to prelaunch options

* Actually validate discs and make prelaunch very betterer :)

* Check your build before pushing dumbass, and go to sleep

* "Disc" consistency, adjust restart notice logic

* Better LanguageSelect logic

* Add restart notice to SaveTypeSelect

* Added wind sounds to the pre-launch menu

* Add Modal document, use it for disc verification

* Consolidate Modal and PresetWindow

* Squash various bugs, rearrange document flow

* Allow Window inheritors to opt-out of being toggleable

* Tweak focus behavior/syntax

* Implement "Restart Now" option

* Tweaks

* Remove a bunch of dynamic_cast

* Update README.md

---------

Co-authored-by: Luke Street <luke@street.dev>
2026-05-05 12:18:25 -06:00

87 lines
2.2 KiB
C++

#include "component.hpp"
namespace dusk::ui {
Component::Component(Rml::Element* root) : mRoot(root) {}
Component::~Component() = default;
void Component::update() {
for (const auto& child : mChildren) {
child->update();
}
}
bool Component::focus() {
if (disabled()) {
return false;
}
// Can we focus self?
if (mRoot->Focus(true)) {
mRoot->ScrollIntoView(Rml::ScrollIntoViewOptions{
Rml::ScrollAlignment::Center,
Rml::ScrollAlignment::Center,
Rml::ScrollBehavior::Smooth,
Rml::ScrollParentage::Closest,
});
return true;
}
// Otherwise, try to focus a child
for (const auto& child : mChildren) {
if (child->focus()) {
return true;
}
}
return false;
}
void Component::set_selected(bool value) {
// Subclasses may override selected() to return a dynamic value, but
// we're only interested in if the pseudoclass is set or not, so we
// use Component::selected() directly rather than selected().
if (Component::selected() == value) {
return;
}
mRoot->SetPseudoClass("selected", value);
}
void Component::set_disabled(bool value) {
if (Component::disabled() == value) {
return;
}
if (value) {
mRoot->SetAttribute("disabled", "");
mRoot->SetPseudoClass("disabled", true);
mRoot->Blur();
} else {
mRoot->RemoveAttribute("disabled");
mRoot->SetPseudoClass("disabled", false);
}
}
void Component::listen(Rml::Element* element, Rml::EventId event,
ScopedEventListener::Callback callback, bool capture) {
if (element == nullptr) {
element = mRoot;
}
mListeners.emplace_back(
std::make_unique<ScopedEventListener>(element, event, std::move(callback), capture));
}
bool Component::contains(Rml::Element* element) const {
for (const auto* node = element; node != nullptr; node = node->GetParentNode()) {
if (node == mRoot) {
return true;
}
}
return false;
}
void Component::clear_children() {
mChildren.clear();
while (mRoot->GetNumChildren() > 0) {
mRoot->RemoveChild(mRoot->GetFirstChild());
}
}
} // namespace dusk::ui