From 313b43bc8716587de8c2504112a97b4444062a26 Mon Sep 17 00:00:00 2001 From: Dario Date: Sun, 12 Jan 2025 23:54:54 -0300 Subject: [PATCH] Add styles. --- CMakeLists.txt | 1 + src/ui/elements/ui_button.cpp | 29 ++- src/ui/elements/ui_button.h | 4 +- src/ui/elements/ui_element.cpp | 456 ++++----------------------------- src/ui/elements/ui_element.h | 232 ++--------------- src/ui/elements/ui_style.cpp | 427 ++++++++++++++++++++++++++++++ src/ui/elements/ui_style.h | 82 ++++++ src/ui/elements/ui_types.h | 156 +++++++++++ src/ui/ui_mod_menu.cpp | 5 +- 9 files changed, 751 insertions(+), 641 deletions(-) create mode 100644 src/ui/elements/ui_style.cpp create mode 100644 src/ui/elements/ui_style.h create mode 100644 src/ui/elements/ui_types.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 58c5387..44601ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,6 +180,7 @@ set (SOURCES ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_image.cpp ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_label.cpp ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_scroll_container.cpp + ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_style.cpp ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_toggle.cpp ${CMAKE_SOURCE_DIR}/rsp/aspMain.cpp diff --git a/src/ui/elements/ui_button.cpp b/src/ui/elements/ui_button.cpp index 4b6a8fb..9d6102e 100644 --- a/src/ui/elements/ui_button.cpp +++ b/src/ui/elements/ui_button.cpp @@ -4,6 +4,8 @@ namespace recompui { + static const std::string hover_style_name = "hover"; + Button::Button(const std::string &text, ButtonStyle style, Element *parent) : Element(parent, Events(EventType::Click, EventType::Hover), "button") { this->style = style; @@ -18,32 +20,36 @@ namespace recompui { set_font_style(FontStyle::Normal); set_font_weight(700); set_cursor(Cursor::Pointer); + set_color(Color{ 204, 204, 204, 255 }); + hover_style.set_color(Color{ 242, 242, 242, 255 }); - // transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; - - update_properties(); - } - - void Button::update_properties() { - uint8_t border_opacity = hovered ? 255 : 204; - uint8_t background_opacity = hovered ? 76 : 13; - set_color(hovered ? Color{ 242, 242, 242, 255 } : Color{ 204, 204, 204, 255 }); - + const uint8_t border_opacity = 204; + const uint8_t background_opacity = 13; + const uint8_t border_hover_opacity = 255; + const uint8_t background_hover_opacity = 76; switch (style) { case ButtonStyle::Primary: { set_border_color({ 185, 125, 242, border_opacity }); set_background_color({ 185, 125, 242, background_opacity }); + hover_style.set_border_color({ 185, 125, 242, border_hover_opacity }); + hover_style.set_background_color({ 185, 125, 242, background_hover_opacity }); break; } case ButtonStyle::Secondary: { set_border_color({ 23, 214, 232, border_opacity }); set_background_color({ 23, 214, 232, background_opacity }); + hover_style.set_border_color({ 23, 214, 232, border_hover_opacity }); + hover_style.set_background_color({ 23, 214, 232, background_hover_opacity }); break; } default: assert(false && "Unknown button style."); break; } + + add_style(hover_style_name, &hover_style); + + // transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; } void Button::process_event(const Event &e) { @@ -54,8 +60,7 @@ namespace recompui { } break; case EventType::Hover: - hovered = e.hover.active; - update_properties(); + enable_style(hover_style_name, e.hover.active); break; default: assert(false && "Unknown event type."); diff --git a/src/ui/elements/ui_button.h b/src/ui/elements/ui_button.h index 7ba2d21..8b02d8d 100644 --- a/src/ui/elements/ui_button.h +++ b/src/ui/elements/ui_button.h @@ -12,10 +12,8 @@ namespace recompui { class Button : public Element { protected: ButtonStyle style = ButtonStyle::Primary; + Style hover_style; std::list> pressed_callbacks; - bool hovered = false; - - void update_properties(); // Element overrides. virtual void process_event(const Event &e) override; diff --git a/src/ui/elements/ui_element.cpp b/src/ui/elements/ui_element.cpp index ebf4cc3..b97cae5 100644 --- a/src/ui/elements/ui_element.cpp +++ b/src/ui/elements/ui_element.cpp @@ -4,69 +4,6 @@ namespace recompui { -static Rml::Unit to_rml(Unit unit) { - switch (unit) { - case Unit::Float: - return Rml::Unit::NUMBER; - case Unit::Dp: - return Rml::Unit::DP; - case Unit::Percent: - return Rml::Unit::PERCENT; - default: - return Rml::Unit::UNKNOWN; - } -} - -static Rml::Style::AlignItems to_rml(AlignItems align_items) { - switch (align_items) { - case AlignItems::FlexStart: - return Rml::Style::AlignItems::FlexStart; - case AlignItems::FlexEnd: - return Rml::Style::AlignItems::FlexEnd; - case AlignItems::Center: - return Rml::Style::AlignItems::Center; - case AlignItems::Baseline: - return Rml::Style::AlignItems::Baseline; - case AlignItems::Stretch: - return Rml::Style::AlignItems::Stretch; - default: - assert(false && "Unknown align items."); - return Rml::Style::AlignItems::FlexStart; - } -} - -static Rml::Style::Overflow to_rml(Overflow overflow) { - switch (overflow) { - case Overflow::Visible: - return Rml::Style::Overflow::Visible; - case Overflow::Hidden: - return Rml::Style::Overflow::Hidden; - case Overflow::Auto: - return Rml::Style::Overflow::Auto; - case Overflow::Scroll: - return Rml::Style::Overflow::Scroll; - default: - assert(false && "Unknown overflow."); - return Rml::Style::Overflow::Visible; - } -} - -static Rml::Style::TextAlign to_rml(TextAlign text_align) { - switch (text_align) { - case TextAlign::Left: - return Rml::Style::TextAlign::Left; - case TextAlign::Right: - return Rml::Style::TextAlign::Right; - case TextAlign::Center: - return Rml::Style::TextAlign::Center; - case TextAlign::Justify: - return Rml::Style::TextAlign::Justify; - default: - assert(false && "Unknown text align."); - return Rml::Style::TextAlign::Left; - } -} - Element::Element(Rml::Element *base) { assert(base != nullptr); @@ -75,14 +12,19 @@ Element::Element(Rml::Element *base) { } Element::Element(Element *parent, uint32_t events_enabled, Rml::String base_class) { - assert(parent != nullptr); + owner = true; - this->owner = true; + Rml::ElementPtr element = parent->base->GetOwnerDocument()->CreateElement(base_class); + if (parent != nullptr) { + base = parent->base->AppendChild(std::move(element)); - base = parent->base->AppendChild(parent->base->GetOwnerDocument()->CreateElement(base_class)); - - if (parent->owner) { - parent->add_child(this); + if (parent->owner) { + parent->add_child(this); + } + } + else { + base = element.release(); + orphaned = true; } register_event_listeners(events_enabled); @@ -92,7 +34,12 @@ Element::~Element() { children.clear(); if (owner) { - base->GetParentNode()->RemoveChild(base); + if (orphaned) { + delete base; + } + else { + base->GetParentNode()->RemoveChild(base); + } } } @@ -107,6 +54,9 @@ void Element::set_property(Rml::PropertyId property_id, const Rml::Property &pro if (animation.type == AnimationType::None) { base->SetProperty(property_id, property); + + // Only non-animated properties should be stored as part of the style. + Style::set_property(property_id, property, animation); } else { const Rml::String property_name = Rml::StyleSheetSpecification::GetPropertyName(property_id); @@ -132,6 +82,22 @@ void Element::register_event_listeners(uint32_t events_enabled) { } } +void Element::apply_style(Style *style) { + for (auto it : style->property_map) { + base->SetProperty(it.first, it.second); + } +} + +void Element::apply_styles() { + apply_style(this); + + for (size_t i = 0; i < styles_active.size(); i++) { + if (styles_active[i]) { + apply_style(styles[i]); + } + } +} + void Element::ProcessEvent(Rml::Event &event) { // Events that are processed during any phase. switch (event.GetId()) { @@ -167,353 +133,29 @@ void Element::process_event(const Event &) { // Does nothing by default. } -void Element::set_position(Position position) { - switch (position) { - case Position::Absolute: - set_property(Rml::PropertyId::Position, Rml::Style::Position::Absolute); - break; - case Position::Relative: - set_property(Rml::PropertyId::Position, Rml::Style::Position::Relative); - break; - default: - assert(false && "Unknown position."); - break; - } +void Element::clear_children() { + children.clear(); } -void Element::set_left(float left, Unit unit, Animation animation) { - set_property(Rml::PropertyId::Left, Rml::Property(left, to_rml(unit)), animation); +void Element::add_style(const std::string &style_name, Style *style) { + assert(style_name_index_map.find(style_name) == style_name_index_map.end()); + + style_name_index_map[style_name] = styles.size(); + styles.emplace_back(style); + styles_active.push_back(false); } -void Element::set_top(float top, Unit unit, Animation animation) { - set_property(Rml::PropertyId::Top, Rml::Property(top, to_rml(unit)), animation); -} +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_right(float right, Unit unit, Animation animation) { - set_property(Rml::PropertyId::Right, Rml::Property(right, to_rml(unit)), animation); -} + styles_active[it->second] = enable; -void Element::set_bottom(float bottom, Unit unit, Animation animation) { - set_property(Rml::PropertyId::Bottom, Rml::Property(bottom, to_rml(unit)), animation); -} - -void Element::set_width(float width, Unit unit, Animation animation) { - set_property(Rml::PropertyId::Width, Rml::Property(width, to_rml(unit)), animation); -} - -void Element::set_width_auto() { - set_property(Rml::PropertyId::Width, Rml::Property(Rml::Style::FlexBasis::Type::Auto, Rml::Unit::KEYWORD)); -} - -void Element::set_height(float height, Unit unit, Animation animation) { - set_property(Rml::PropertyId::Height, Rml::Property(height, to_rml(unit)), animation); -} - -void Element::set_height_auto() { - set_property(Rml::PropertyId::Height, Rml::Property(Rml::Style::FlexBasis::Type::Auto, Rml::Unit::KEYWORD)); -} - -void Element::set_min_width(float width, Unit unit, Animation animation) { - set_property(Rml::PropertyId::MinWidth, Rml::Property(width, to_rml(unit)), animation); -} - -void Element::set_min_height(float height, Unit unit, Animation animation) { - set_property(Rml::PropertyId::MinHeight, Rml::Property(height, to_rml(unit)), animation); -} - -void Element::set_max_width(float width, Unit unit, Animation animation) { - set_property(Rml::PropertyId::MaxWidth, Rml::Property(width, to_rml(unit)), animation); -} - -void Element::set_max_height(float height, Unit unit, Animation animation) { - set_property(Rml::PropertyId::MaxHeight, Rml::Property(height, to_rml(unit)), animation); -} - -void Element::set_padding(float padding, Unit unit, Animation animation) { - set_property(Rml::PropertyId::PaddingLeft, Rml::Property(padding, to_rml(unit)), animation); - set_property(Rml::PropertyId::PaddingTop, Rml::Property(padding, to_rml(unit)), animation); - set_property(Rml::PropertyId::PaddingRight, Rml::Property(padding, to_rml(unit)), animation); - set_property(Rml::PropertyId::PaddingBottom, Rml::Property(padding, to_rml(unit)), animation); -} - -void Element::set_padding_left(float padding, Unit unit, Animation animation) { - set_property(Rml::PropertyId::PaddingLeft, Rml::Property(padding, to_rml(unit)), animation); -} - -void Element::set_padding_top(float padding, Unit unit, Animation animation) { - set_property(Rml::PropertyId::PaddingTop, Rml::Property(padding, to_rml(unit)), animation); -} - -void Element::set_padding_right(float padding, Unit unit, Animation animation) { - set_property(Rml::PropertyId::PaddingRight, Rml::Property(padding, to_rml(unit)), animation); -} - -void Element::set_padding_bottom(float padding, Unit unit, Animation animation) { - set_property(Rml::PropertyId::PaddingBottom, Rml::Property(padding, to_rml(unit)), animation); -} - -void Element::set_margin(float margin, Unit unit, Animation animation) { - set_property(Rml::PropertyId::MarginLeft, Rml::Property(margin, to_rml(unit)), animation); - set_property(Rml::PropertyId::MarginTop, Rml::Property(margin, to_rml(unit)), animation); - set_property(Rml::PropertyId::MarginRight, Rml::Property(margin, to_rml(unit)), animation); - set_property(Rml::PropertyId::MarginBottom, Rml::Property(margin, to_rml(unit)), animation); -} - -void Element::set_margin_left(float margin, Unit unit, Animation animation) { - set_property(Rml::PropertyId::MarginLeft, Rml::Property(margin, to_rml(unit)), animation); -} - -void Element::set_margin_top(float margin, Unit unit, Animation animation) { - set_property(Rml::PropertyId::MarginTop, Rml::Property(margin, to_rml(unit)), animation); -} - -void Element::set_margin_right(float margin, Unit unit, Animation animation) { - set_property(Rml::PropertyId::MarginRight, Rml::Property(margin, to_rml(unit)), animation); -} - -void Element::set_margin_bottom(float margin, Unit unit, Animation animation) { - set_property(Rml::PropertyId::MarginBottom, Rml::Property(margin, to_rml(unit)), animation); -} - -void Element::set_border_width(float width, Unit unit, Animation animation) { - Rml::Property property(width, to_rml(unit)); - set_property(Rml::PropertyId::BorderTopWidth, property, animation); - set_property(Rml::PropertyId::BorderBottomWidth, property, animation); - set_property(Rml::PropertyId::BorderLeftWidth, property, animation); - set_property(Rml::PropertyId::BorderRightWidth, property, animation); -} - -void Element::set_border_left_width(float width, Unit unit, Animation animation) { - set_property(Rml::PropertyId::BorderLeftWidth, Rml::Property(width, to_rml(unit)), animation); -} - -void Element::set_border_top_width(float width, Unit unit, Animation animation) { - set_property(Rml::PropertyId::BorderTopWidth, Rml::Property(width, to_rml(unit)), animation); -} - -void Element::set_border_right_width(float width, Unit unit, Animation animation) { - set_property(Rml::PropertyId::BorderRightWidth, Rml::Property(width, to_rml(unit)), animation); -} - -void Element::set_border_bottom_width(float width, Unit unit, Animation animation) { - set_property(Rml::PropertyId::BorderBottomWidth, Rml::Property(width, to_rml(unit)), animation); -} - -void Element::set_border_radius(float radius, Unit unit, Animation animation) { - Rml::Property property(radius, to_rml(unit)); - set_property(Rml::PropertyId::BorderTopLeftRadius, property, animation); - set_property(Rml::PropertyId::BorderTopRightRadius, property, animation); - set_property(Rml::PropertyId::BorderBottomLeftRadius, property, animation); - set_property(Rml::PropertyId::BorderBottomRightRadius, property, animation); -} - -void Element::set_border_top_left_radius(float radius, Unit unit, Animation animation) { - set_property(Rml::PropertyId::BorderTopLeftRadius, Rml::Property(radius, to_rml(unit)), animation); -} - -void Element::set_border_top_right_radius(float radius, Unit unit, Animation animation) { - set_property(Rml::PropertyId::BorderTopRightRadius, Rml::Property(radius, to_rml(unit)), animation); -} - -void Element::set_border_bottom_left_radius(float radius, Unit unit, Animation animation) { - set_property(Rml::PropertyId::BorderBottomLeftRadius, Rml::Property(radius, to_rml(unit)), animation); -} - -void Element::set_border_bottom_right_radius(float radius, Unit unit, Animation animation) { - set_property(Rml::PropertyId::BorderBottomRightRadius, Rml::Property(radius, to_rml(unit)), animation); -} - -void Element::set_background_color(const Color &color, Animation animation) { - Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); - set_property(Rml::PropertyId::BackgroundColor, property, animation); -} - -void Element::set_border_color(const Color &color, Animation animation) { - Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); - set_property(Rml::PropertyId::BorderTopColor, property, animation); - set_property(Rml::PropertyId::BorderBottomColor, property, animation); - set_property(Rml::PropertyId::BorderLeftColor, property, animation); - set_property(Rml::PropertyId::BorderRightColor, property, animation); -} - -void Element::set_border_left_color(const Color &color, Animation animation) { - Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); - set_property(Rml::PropertyId::BorderLeftColor, property, animation); -} - -void Element::set_border_top_color(const Color &color, Animation animation) { - Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); - set_property(Rml::PropertyId::BorderTopColor, property, animation); -} - -void Element::set_border_right_color(const Color &color, Animation animation) { - Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); - set_property(Rml::PropertyId::BorderRightColor, property, animation); -} - -void Element::set_border_bottom_color(const Color &color, Animation animation) { - Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); - set_property(Rml::PropertyId::BorderBottomColor, property, animation); -} - -void Element::set_color(const Color &color, Animation animation) { - Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); - set_property(Rml::PropertyId::Color, property, animation); -} - -void Element::set_cursor(Cursor cursor) { - switch (cursor) { - case Cursor::None: - assert(false && "Unimplemented."); - break; - case Cursor::Pointer: - set_property(Rml::PropertyId::Cursor, Rml::Property("pointer", Rml::Unit::STRING)); - break; - default: - assert(false && "Unknown cursor."); - break; - } -} - -void Element::set_opacity(float opacity, Animation animation) { - set_property(Rml::PropertyId::Opacity, Rml::Property(opacity, Rml::Unit::NUMBER), animation); -} - -void Element::set_display(Display display) { - switch (display) { - case Display::Block: - set_property(Rml::PropertyId::Display, Rml::Style::Display::Block); - break; - case Display::Flex: - set_property(Rml::PropertyId::Display, Rml::Style::Display::Flex); - break; - default: - assert(false && "Unknown display."); - break; - } -} - -void Element::set_justify_content(JustifyContent justify_content) { - switch (justify_content) { - case JustifyContent::FlexStart: - set_property(Rml::PropertyId::JustifyContent, Rml::Style::JustifyContent::FlexStart); - break; - case JustifyContent::FlexEnd: - set_property(Rml::PropertyId::JustifyContent, Rml::Style::JustifyContent::FlexEnd); - break; - case JustifyContent::Center: - set_property(Rml::PropertyId::JustifyContent, Rml::Style::JustifyContent::Center); - break; - case JustifyContent::SpaceBetween: - set_property(Rml::PropertyId::JustifyContent, Rml::Style::JustifyContent::SpaceBetween); - break; - case JustifyContent::SpaceAround: - set_property(Rml::PropertyId::JustifyContent, Rml::Style::JustifyContent::SpaceAround); - break; - case JustifyContent::SpaceEvenly: - set_property(Rml::PropertyId::JustifyContent, Rml::Style::JustifyContent::SpaceEvenly); - break; - default: - assert(false && "Unknown justify content."); - break; - } -} - -void Element::set_flex_grow(float grow, Animation animation) { - set_property(Rml::PropertyId::FlexGrow, Rml::Property(grow, Rml::Unit::NUMBER), animation); -} - -void Element::set_flex_shrink(float shrink, Animation animation) { - set_property(Rml::PropertyId::FlexShrink, Rml::Property(shrink, Rml::Unit::NUMBER), animation); -} - -void Element::set_flex_basis_auto() { - set_property(Rml::PropertyId::FlexBasis, Rml::Property(Rml::Style::FlexBasis::Type::Auto, Rml::Unit::KEYWORD)); -} - -void Element::set_flex_basis_percentage(float basis, Animation animation) { - set_property(Rml::PropertyId::FlexBasis, Rml::Property(basis, Rml::Unit::PERCENT), animation); -} - -void Element::set_flex(float grow, float shrink, Animation animation) { - set_flex_grow(grow, animation); - set_flex_shrink(shrink, animation); - set_flex_basis_auto(); -} - -void Element::set_flex(float grow, float shrink, float basis_percentage, Animation animation) { - set_flex_grow(grow, animation); - set_flex_shrink(shrink, animation); - set_flex_basis_percentage(basis_percentage, animation); -} - -void Element::set_flex_direction(FlexDirection flex_direction) { - switch (flex_direction) { - case FlexDirection::Row: - set_property(Rml::PropertyId::FlexDirection, Rml::Style::FlexDirection::Row); - break; - case FlexDirection::Column: - set_property(Rml::PropertyId::FlexDirection, Rml::Style::FlexDirection::Column); - break; - default: - assert(false && "Unknown flex direction."); - break; - } -} - -void Element::set_align_items(AlignItems align_items) { - set_property(Rml::PropertyId::AlignItems, to_rml(align_items)); -} - -void Element::set_overflow(Overflow overflow) { - set_property(Rml::PropertyId::OverflowX, to_rml(overflow)); - set_property(Rml::PropertyId::OverflowY, to_rml(overflow)); -} - -void Element::set_overflow_x(Overflow overflow) { - set_property(Rml::PropertyId::OverflowX, to_rml(overflow)); -} - -void Element::set_overflow_y(Overflow overflow) { - set_property(Rml::PropertyId::OverflowY, to_rml(overflow)); -} - -void Element::set_font_size(float size, Unit unit, Animation animation) { - set_property(Rml::PropertyId::FontSize, Rml::Property(size, to_rml(unit)), animation); -} - -void Element::set_letter_spacing(float spacing, Unit unit, Animation animation) { - set_property(Rml::PropertyId::LetterSpacing, Rml::Property(spacing, to_rml(unit)), animation); -} - -void Element::set_line_height(float height, Unit unit, Animation animation) { - set_property(Rml::PropertyId::LineHeight, Rml::Property(height, to_rml(unit)), animation); -} - -void Element::set_font_style(FontStyle style) { - switch (style) { - case FontStyle::Normal: - set_property(Rml::PropertyId::FontStyle, Rml::Style::FontStyle::Normal); - break; - case FontStyle::Italic: - set_property(Rml::PropertyId::FontStyle, Rml::Style::FontStyle::Italic); - break; - default: - assert(false && "Unknown font style."); - break; - } -} - -void Element::set_font_weight(uint32_t weight, Animation animation) { - set_property(Rml::PropertyId::FontWeight, Rml::Style::FontWeight(weight), animation); + apply_styles(); } void Element::set_text(const std::string &text) { base->SetInnerRML(text); } -void Element::set_text_align(TextAlign text_align) { - set_property(Rml::PropertyId::TextAlign, to_rml(text_align)); -} - }; \ No newline at end of file diff --git a/src/ui/elements/ui_element.h b/src/ui/elements/ui_element.h index 68ef1ae..d71b979 100644 --- a/src/ui/elements/ui_element.h +++ b/src/ui/elements/ui_element.h @@ -1,171 +1,31 @@ #pragma once -#include "RmlUi/Core.h" +#include "ui_style.h" namespace recompui { -struct Color { - uint8_t r = 255; - uint8_t g = 255; - uint8_t b = 255; - uint8_t a = 255; -}; - -enum class Cursor { - None, - Pointer -}; - -enum class EventType { - None, - Click, - Focus, - Hover, - Count -}; - -template >> -constexpr uint32_t Events(Enum first) { - return 1u << static_cast(first); -} - -template >> -constexpr uint32_t Events(Enum first, Enums... rest) { - return Events(first) | Events(rest...); -} - -struct Event { - struct Mouse { - float x; - float y; - }; - - EventType type; - - union { - struct { - Mouse mouse; - } click; - - struct { - bool active; - } focus; - - struct { - bool active; - } hover; - }; - - static Event click_event(float x, float y) { - Event e = {}; - e.type = EventType::Click; - e.click.mouse.x = x; - e.click.mouse.y = y; - return e; - } - - static Event focus_event(bool active) { - Event e = {}; - e.type = EventType::Focus; - e.focus.active = active; - return e; - } - - static Event hover_event(bool active) { - Event e = {}; - e.type = EventType::Hover; - e.focus.active = active; - return e; - } -}; - -enum class Display { - Block, - Flex -}; - -enum class Position { - Absolute, - Relative -}; - -enum class JustifyContent { - FlexStart, - FlexEnd, - Center, - SpaceBetween, - SpaceAround, - SpaceEvenly -}; - -enum class FlexDirection { - Row, - Column -}; - -enum class AlignItems { - FlexStart, - FlexEnd, - Center, - Baseline, - Stretch -}; - -enum class Overflow { - Visible, - Hidden, - Auto, - Scroll -}; - -enum class Unit { - Float, - Dp, - Percent -}; - -enum class AnimationType { - None, - Tween -}; - -enum class FontStyle { - Normal, - Italic -}; - -enum class TextAlign { - Left, - Right, - Center, - Justify -}; - -struct Animation { - AnimationType type = AnimationType::None; - float duration = 0.0f; - - static Animation tween(float duration) { - Animation a; - a.type = AnimationType::Tween; - a.duration = duration; - return a; - } -}; - -class Element : public Rml::EventListener { +class Element : public Style, public Rml::EventListener { friend class Element; private: + std::vector