Make ui styles update elements on change

This commit is contained in:
Nikita Lisitsa 2022-03-10 17:36:17 +03:00
parent 83df1a82ef
commit 4dcac2a5ac
4 changed files with 49 additions and 1 deletions

View file

@ -61,7 +61,7 @@ namespace psemek::ui
virtual void draw(painter & p) const = 0;
virtual void post_draw(painter & /* p */) const {}
virtual ~element() {}
virtual ~element();
virtual void post(util::function<void()> f) const;
virtual void post_reshape();

View file

@ -4,6 +4,7 @@
#include <psemek/gfx/color.hpp>
#include <optional>
#include <unordered_set>
namespace psemek::ui
{
@ -14,6 +15,8 @@ namespace psemek::ui
down,
};
struct element;
struct style
{
std::optional<int> scale;
@ -48,6 +51,18 @@ namespace psemek::ui
std::optional<geom::vector<int, 2>> text_shadow_offset;
std::shared_ptr<struct font> font;
mutable std::unordered_set<element *> use_as_style;
mutable std::unordered_set<element *> use_as_own_style;
style() = default;
style(style &&) = default;
style(style const &);
style & operator = (style &&) = default;
style & operator = (style const &) = delete;
void on_changed();
};
void merge(style & dst, style const & src);

View file

@ -57,8 +57,14 @@ namespace psemek::ui
std::shared_ptr<style const> element::set_style(std::shared_ptr<struct style const> st)
{
if (style_)
style_->use_as_style.erase(this);
std::swap(st, style_);
if (style_)
style_->use_as_style.insert(this);
auto visitor = util::recursive([](auto && self, element * e) -> void {
e->merged_style_ = nullptr;
e->merged_own_style_ = nullptr;
@ -72,8 +78,14 @@ namespace psemek::ui
std::shared_ptr<struct style const> element::set_own_style(std::shared_ptr<struct style const> st)
{
if (style_)
style_->use_as_own_style.erase(this);
std::swap(st, own_style_);
if (style_)
style_->use_as_own_style.insert(this);
auto visitor = util::recursive([](auto && self, element * e) -> void {
e->merged_style_ = nullptr;
e->merged_own_style_ = nullptr;
@ -122,6 +134,12 @@ namespace psemek::ui
return merged_own_style_;
}
element::~element()
{
set_style(nullptr);
set_own_style(nullptr);
}
void element::post(util::function<void()> f) const
{
auto l = loop();

View file

@ -1,4 +1,5 @@
#include <psemek/ui/style.hpp>
#include <psemek/ui/element.hpp>
namespace psemek::ui
{
@ -34,6 +35,20 @@ namespace psemek::ui
}
style::style(style const & other)
{
merge(*this, other);
}
void style::on_changed()
{
for (auto e : use_as_style)
e->set_style(e->style());
for (auto e : use_as_own_style)
e->set_own_style(e->own_style());
}
void merge(style & dst, style const & src)
{
merge(dst.scale, src.scale);