mirror of
https://github.com/Mr-Wiseguy/Zelda64Recomp.git
synced 2025-02-10 00:48:49 +01:00
Multi-style state and disabled state propagation.
This commit is contained in:
parent
97998956bb
commit
0a7ad6eadf
@ -4,9 +4,10 @@
|
||||
|
||||
namespace recompui {
|
||||
|
||||
static const std::string hover_style_name = "hover";
|
||||
static const std::string hover_state = "hover";
|
||||
static const std::string disabled_state = "disabled";
|
||||
|
||||
Button::Button(const std::string &text, ButtonStyle style, Element *parent) : Element(parent, Events(EventType::Click, EventType::Hover), "button") {
|
||||
Button::Button(const std::string &text, ButtonStyle style, Element *parent) : Element(parent, Events(EventType::Click, EventType::Hover, EventType::Enable), "button") {
|
||||
this->style = style;
|
||||
|
||||
set_text(text);
|
||||
@ -47,8 +48,15 @@ namespace recompui {
|
||||
break;
|
||||
}
|
||||
|
||||
add_style(hover_style_name, &hover_style);
|
||||
|
||||
disabled_style.set_border_color({ 128, 128, 128, border_hover_opacity });
|
||||
disabled_style.set_background_color({ 128, 128, 128, background_hover_opacity });
|
||||
hover_disabled_style.set_border_color({ 196, 196, 196, border_hover_opacity });
|
||||
hover_disabled_style.set_background_color({ 196, 196, 196, background_hover_opacity });
|
||||
|
||||
add_style(&hover_style, { hover_state });
|
||||
add_style(&disabled_style, { disabled_state });
|
||||
add_style(&hover_disabled_style, { hover_state, disabled_state });
|
||||
|
||||
// transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out;
|
||||
}
|
||||
|
||||
@ -60,7 +68,10 @@ namespace recompui {
|
||||
}
|
||||
break;
|
||||
case EventType::Hover:
|
||||
enable_style(hover_style_name, e.hover.active);
|
||||
set_style_enabled(hover_state, e.hover.active);
|
||||
break;
|
||||
case EventType::Enable:
|
||||
set_style_enabled(disabled_state, !e.enable.enable);
|
||||
break;
|
||||
default:
|
||||
assert(false && "Unknown event type.");
|
||||
|
@ -13,6 +13,8 @@ namespace recompui {
|
||||
protected:
|
||||
ButtonStyle style = ButtonStyle::Primary;
|
||||
Style hover_style;
|
||||
Style disabled_style;
|
||||
Style hover_disabled_style;
|
||||
std::list<std::function<void()>> pressed_callbacks;
|
||||
|
||||
// Element overrides.
|
||||
|
@ -67,6 +67,8 @@ void Element::set_property(Rml::PropertyId property_id, const Rml::Property &pro
|
||||
void Element::register_event_listeners(uint32_t events_enabled) {
|
||||
assert(base != nullptr);
|
||||
|
||||
this->events_enabled = events_enabled;
|
||||
|
||||
if (events_enabled & Events(EventType::Click)) {
|
||||
base->AddEventListener(Rml::EventId::Mousedown, this);
|
||||
}
|
||||
@ -91,13 +93,31 @@ void Element::apply_style(Style *style) {
|
||||
void Element::apply_styles() {
|
||||
apply_style(this);
|
||||
|
||||
for (size_t i = 0; i < styles_active.size(); i++) {
|
||||
if (styles_active[i]) {
|
||||
for (size_t i = 0; i < styles_counter.size(); i++) {
|
||||
if (styles_counter[i] == 0) {
|
||||
apply_style(styles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Element::propagate_disabled(bool disabled) {
|
||||
disabled_from_parent = disabled;
|
||||
|
||||
bool attribute_state = disabled_from_parent || !enabled;
|
||||
if (disabled_attribute != attribute_state) {
|
||||
disabled_attribute = attribute_state;
|
||||
base->SetAttribute("disabled", attribute_state);
|
||||
|
||||
if (events_enabled & Events(EventType::Enable)) {
|
||||
process_event(Event::enable_event(!attribute_state));
|
||||
}
|
||||
|
||||
for (auto &child : children) {
|
||||
child->propagate_disabled(attribute_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Element::ProcessEvent(Rml::Event &event) {
|
||||
// Events that are processed during any phase.
|
||||
switch (event.GetId()) {
|
||||
@ -137,25 +157,59 @@ void Element::clear_children() {
|
||||
children.clear();
|
||||
}
|
||||
|
||||
void Element::add_style(const std::string &style_name, Style *style) {
|
||||
assert(style_name_index_map.find(style_name) == style_name_index_map.end());
|
||||
void Element::add_style(Style *style, const std::list<std::string> &style_names) {
|
||||
for (const std::string &style_name : style_names) {
|
||||
style_name_index_map.emplace(style_name, styles.size());
|
||||
}
|
||||
|
||||
style_name_index_map[style_name] = styles.size();
|
||||
styles.emplace_back(style);
|
||||
styles_active.push_back(false);
|
||||
|
||||
uint32_t initial_style_counter = style_names.size();
|
||||
for (const std::string &style_name : style_names) {
|
||||
if (style_active_set.find(style_name) != style_active_set.end()) {
|
||||
initial_style_counter--;
|
||||
}
|
||||
}
|
||||
|
||||
styles_counter.push_back(initial_style_counter);
|
||||
}
|
||||
|
||||
void Element::enable_style(const std::string &style_name, bool enable) {
|
||||
auto it = style_name_index_map.find(style_name);
|
||||
assert(it != style_name_index_map.end());
|
||||
void Element::set_enabled(bool enabled) {
|
||||
this->enabled = enabled;
|
||||
|
||||
styles_active[it->second] = enable;
|
||||
|
||||
apply_styles();
|
||||
propagate_disabled(disabled_from_parent);
|
||||
}
|
||||
|
||||
void Element::set_text(const std::string &text) {
|
||||
base->SetInnerRML(text);
|
||||
}
|
||||
|
||||
void Element::set_style_enabled(const std::string &style_name, bool enable) {
|
||||
if (enable && style_active_set.find(style_name) == style_active_set.end()) {
|
||||
// Style was disabled and will be enabled.
|
||||
style_active_set.emplace(style_name);
|
||||
|
||||
}
|
||||
else if (!enable && style_active_set.find(style_name) != style_active_set.end()) {
|
||||
// Style was enabled and will be disabled.
|
||||
style_active_set.erase(style_name);
|
||||
}
|
||||
else {
|
||||
// Do nothing.
|
||||
return;
|
||||
}
|
||||
|
||||
auto range = style_name_index_map.equal_range(style_name);
|
||||
for (auto it = range.first; it != range.second; it++) {
|
||||
if (enable) {
|
||||
styles_counter[it->second]--;
|
||||
}
|
||||
else {
|
||||
styles_counter[it->second]++;
|
||||
}
|
||||
}
|
||||
|
||||
apply_styles();
|
||||
}
|
||||
|
||||
};
|
@ -2,19 +2,23 @@
|
||||
|
||||
#include "ui_style.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
namespace recompui {
|
||||
|
||||
class Element : public Style, public Rml::EventListener {
|
||||
friend class Element;
|
||||
private:
|
||||
std::vector<Style *> styles;
|
||||
std::vector<bool> styles_active;
|
||||
std::map<std::string, uint32_t> style_name_index_map;
|
||||
std::vector<uint32_t> styles_counter;
|
||||
std::unordered_set<std::string> style_active_set;
|
||||
std::unordered_multimap<std::string, uint32_t> style_name_index_map;
|
||||
|
||||
void add_child(Element *child);
|
||||
void register_event_listeners(uint32_t events_enabled);
|
||||
void apply_style(Style *style);
|
||||
void apply_styles();
|
||||
void propagate_disabled(bool disabled);
|
||||
|
||||
// Style overrides.
|
||||
virtual void set_property(Rml::PropertyId property_id, const Rml::Property &property, Animation animation) override;
|
||||
@ -24,8 +28,12 @@ private:
|
||||
protected:
|
||||
Rml::Element *base = nullptr;
|
||||
std::vector<std::unique_ptr<Element>> children;
|
||||
uint32_t events_enabled = 0;
|
||||
bool owner = false;
|
||||
bool orphaned = false;
|
||||
bool enabled = true;
|
||||
bool disabled_attribute = false;
|
||||
bool disabled_from_parent = false;
|
||||
|
||||
virtual void process_event(const Event &e);
|
||||
public:
|
||||
@ -36,9 +44,10 @@ public:
|
||||
Element(Element *parent, uint32_t events_enabled = 0, Rml::String base_class = "div");
|
||||
virtual ~Element();
|
||||
void clear_children();
|
||||
void add_style(const std::string &style_name, Style *style);
|
||||
void enable_style(const std::string &style_name, bool enable);
|
||||
void add_style(Style *style, const std::list<std::string> &style_names);
|
||||
void set_enabled(bool enabled);
|
||||
void set_text(const std::string &text);
|
||||
void set_style_enabled(const std::string &style_name, bool enabled);
|
||||
};
|
||||
|
||||
} // namespace recompui
|
@ -21,6 +21,7 @@ namespace recompui {
|
||||
Click,
|
||||
Focus,
|
||||
Hover,
|
||||
Enable,
|
||||
Count
|
||||
};
|
||||
|
||||
@ -54,6 +55,10 @@ namespace recompui {
|
||||
struct {
|
||||
bool active;
|
||||
} hover;
|
||||
|
||||
struct {
|
||||
bool enable;
|
||||
} enable;
|
||||
};
|
||||
|
||||
static Event click_event(float x, float y) {
|
||||
@ -77,6 +82,13 @@ namespace recompui {
|
||||
e.focus.active = active;
|
||||
return e;
|
||||
}
|
||||
|
||||
static Event enable_event(bool enable) {
|
||||
Event e = {};
|
||||
e.type = EventType::Enable;
|
||||
e.enable.enable = enable;
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
enum class Display {
|
||||
|
Loading…
x
Reference in New Issue
Block a user