mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-31 07:45:48 -04:00
08321699cd
* 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>
88 lines
2.5 KiB
C++
88 lines
2.5 KiB
C++
#pragma once
|
|
|
|
#include "event.hpp"
|
|
#include "ui.hpp"
|
|
|
|
#include <RmlUi/Core.h>
|
|
|
|
#include <memory>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace Rml {
|
|
class Element;
|
|
}
|
|
|
|
namespace dusk::ui {
|
|
|
|
class Component {
|
|
public:
|
|
Component() = default;
|
|
explicit Component(Rml::Element* root);
|
|
virtual ~Component();
|
|
|
|
Component(const Component&) = delete;
|
|
Component& operator=(const Component&) = delete;
|
|
|
|
virtual void update();
|
|
virtual bool focus();
|
|
|
|
virtual bool selected() const { return mRoot->IsPseudoClassSet("selected"); }
|
|
virtual void set_selected(bool selected);
|
|
virtual bool disabled() const { return mRoot->IsPseudoClassSet("disabled"); }
|
|
virtual void set_disabled(bool disabled);
|
|
|
|
void listen(Rml::Element* element, Rml::EventId event, ScopedEventListener::Callback callback,
|
|
bool capture = false);
|
|
bool contains(Rml::Element* element) const;
|
|
|
|
template <typename T, typename... Args>
|
|
requires std::is_base_of_v<Component, T> T& add_child(Args&&... args) {
|
|
auto child = std::make_unique<T>(mRoot, std::forward<Args>(args)...);
|
|
T& ref = *child;
|
|
mChildren.emplace_back(std::move(child));
|
|
return ref;
|
|
}
|
|
|
|
Rml::Element* root() const { return mRoot; }
|
|
|
|
protected:
|
|
void clear_children();
|
|
|
|
Rml::Element* mRoot = nullptr;
|
|
std::vector<std::unique_ptr<Component> > mChildren;
|
|
std::vector<std::unique_ptr<ScopedEventListener> > mListeners;
|
|
};
|
|
|
|
template <class Derived>
|
|
class FluentComponent : public Component {
|
|
public:
|
|
using Component::Component;
|
|
|
|
Derived& listen(
|
|
Rml::EventId event, ScopedEventListener::Callback callback, bool capture = false) {
|
|
Component::listen(mRoot, event, std::move(callback), capture);
|
|
return static_cast<Derived&>(*this);
|
|
}
|
|
|
|
Derived& on_nav_command(std::function<bool(Rml::Event&, NavCommand)> callback) {
|
|
listen(Rml::EventId::Click, [this, callback](Rml::Event& event) {
|
|
if (!disabled() && callback(event, NavCommand::Confirm)) {
|
|
event.StopPropagation();
|
|
}
|
|
});
|
|
listen(Rml::EventId::Keydown, [this, callback = std::move(callback)](Rml::Event& event) {
|
|
if (disabled()) {
|
|
return;
|
|
}
|
|
const auto cmd = map_nav_event(event);
|
|
if (cmd != NavCommand::None && callback(event, cmd)) {
|
|
event.StopPropagation();
|
|
}
|
|
});
|
|
return static_cast<Derived&>(*this);
|
|
}
|
|
};
|
|
|
|
} // namespace dusk::ui
|