diff --git a/examples/ui.cpp b/examples/ui.cpp index b14fe676..43cb37db 100644 --- a/examples/ui.cpp +++ b/examples/ui.cpp @@ -39,7 +39,7 @@ struct ui_example : app("UI example", 1) , ui_controller(&loop) { - auto style = std::make_shared(ui::default_style()); + auto style = std::make_shared(); style->font = ui::make_default_9x12_font(); style->text_scale = 2; diff --git a/libs/ui/include/psemek/ui/element.hpp b/libs/ui/include/psemek/ui/element.hpp index 0c55311c..d4bac324 100644 --- a/libs/ui/include/psemek/ui/element.hpp +++ b/libs/ui/include/psemek/ui/element.hpp @@ -44,8 +44,9 @@ namespace psemek::ui virtual void enable() { set_enabled(true); } virtual void disable() { set_enabled(false); } - virtual std::shared_ptr style() const; + virtual std::shared_ptr style() const { return style_; } virtual std::shared_ptr set_style(std::shared_ptr st); + virtual std::shared_ptr merged_style() const; virtual void draw(painter & p) const = 0; @@ -59,6 +60,7 @@ namespace psemek::ui async::executor * loop_ = nullptr; bool enabled_ = true; std::shared_ptr style_; + mutable std::shared_ptr merged_style_; }; } diff --git a/libs/ui/include/psemek/ui/style.hpp b/libs/ui/include/psemek/ui/style.hpp index b8da9c7c..5176c4bc 100644 --- a/libs/ui/include/psemek/ui/style.hpp +++ b/libs/ui/include/psemek/ui/style.hpp @@ -31,6 +31,8 @@ namespace psemek::ui std::shared_ptr font; }; + void merge(style & dst, style const & src); + style default_style(); } diff --git a/libs/ui/source/default_element_factory.cpp b/libs/ui/source/default_element_factory.cpp index 3fa0319c..e8063623 100644 --- a/libs/ui/source/default_element_factory.cpp +++ b/libs/ui/source/default_element_factory.cpp @@ -37,9 +37,9 @@ namespace psemek::ui void reshape(geom::box const & bbox) override { shape_.box = bbox; - auto s = style(); + auto st = merged_style(); element * c = label() ? (element *)label() : icon(); - if (s && c) c->reshape(geom::shrink(bbox, 1.f * (*s->border_width + *s->inner_margin))); + if (st && c) c->reshape(geom::shrink(bbox, 1.f * (*st->border_width + *st->inner_margin))); } void on_state_changed() override @@ -63,21 +63,21 @@ namespace psemek::ui void draw(painter & p) const override { - auto s = style(); - if (!s) return; + auto st = merged_style(); + if (!st) return; - if (s->shadow_offset != geom::vector{0, 0}) - p.draw_rect(shape_.box + geom::cast(*s->shadow_offset), *s->shadow_color); + if (st->shadow_offset != geom::vector{0, 0}) + p.draw_rect(shape_.box + geom::cast(*st->shadow_offset), *st->shadow_color); - if (s->border_width > 0) - p.draw_rect(shape_.box, *s->border_color); + if (st->border_width > 0) + p.draw_rect(shape_.box, *st->border_color); - gfx::color_rgba color = *s->fg_color; + gfx::color_rgba color = *st->fg_color; if (state() == state_t::mouseover) - color = *s->highlight_color; + color = *st->highlight_color; else if (state() == state_t::mousedown) - color = *s->action_color; - p.draw_rect(geom::shrink(shape_.box, 1.f * (*s->border_width)), color); + color = *st->action_color; + p.draw_rect(geom::shrink(shape_.box, 1.f * (*st->border_width)), color); } geom::box size_constraints() const override @@ -90,7 +90,7 @@ namespace psemek::ui { sc = c->size_constraints(); - if (auto st = style()) + if (auto st = merged_style()) { float extra = 2.f * (*st->border_width + *st->inner_margin); sc[0] += extra; @@ -113,7 +113,7 @@ namespace psemek::ui void reshape(geom::box const & bbox) override { shape_.box = bbox; - auto st = style(); + auto st = merged_style(); if (!st) return; for (auto c : children()) if (c) c->reshape(geom::shrink(bbox, 1.f * (*st->border_width + *st->outer_margin))); @@ -127,7 +127,7 @@ namespace psemek::ui if (c) r = c->size_constraints(); - auto st = style(); + auto st = merged_style(); if (st) { float extra = 2.f * (*st->border_width + *st->outer_margin); @@ -154,7 +154,7 @@ namespace psemek::ui void draw(painter & p) const override { - auto st = style(); + auto st = merged_style(); if (!st) return; if (st->shadow_offset != geom::vector{0, 0}) diff --git a/libs/ui/source/element.cpp b/libs/ui/source/element.cpp index 01cb5ed3..f216bfbe 100644 --- a/libs/ui/source/element.cpp +++ b/libs/ui/source/element.cpp @@ -1,5 +1,7 @@ #include +#include + #include namespace psemek::ui @@ -37,19 +39,46 @@ namespace psemek::ui return {{{0.f, inf}, {0.f, inf}}}; } - std::shared_ptr element::style() const - { - element const * e = this; - while (!e->style_ && e->parent()) e = e->parent(); - return e->style_; - } - std::shared_ptr