diff --git a/libs/ui/include/psemek/ui/element.hpp b/libs/ui/include/psemek/ui/element.hpp index 319df991..ee057f66 100644 --- a/libs/ui/include/psemek/ui/element.hpp +++ b/libs/ui/include/psemek/ui/element.hpp @@ -19,7 +19,7 @@ namespace psemek::ui : std::enable_shared_from_this { virtual element * parent() const { return parent_; } - virtual void set_parent(element * parent) { parent_ = parent; } + virtual void set_parent(element * parent); using children_range = util::span; @@ -28,7 +28,7 @@ namespace psemek::ui virtual element * root(); virtual element const * root() const; virtual async::event_loop * loop() const; - virtual void set_loop(async::event_loop * loop) { loop_ = loop; } + virtual void set_loop(async::event_loop * loop); virtual bool on_event(mouse_move const &) { return false; } virtual bool on_event(mouse_click const &) { return false; } @@ -81,6 +81,10 @@ namespace psemek::ui std::shared_ptr own_style_; mutable std::shared_ptr merged_style_; mutable std::shared_ptr merged_own_style_; + + mutable std::vector> delayed_callbacks_; + + void post_delayed_callbacks() const; }; } diff --git a/libs/ui/source/element.cpp b/libs/ui/source/element.cpp index 1be9ab1c..620b186a 100644 --- a/libs/ui/source/element.cpp +++ b/libs/ui/source/element.cpp @@ -7,6 +7,13 @@ namespace psemek::ui { + void element::set_parent(element * parent) + { + parent_ = parent; + if (loop()) + post_delayed_callbacks(); + } + element * element::root() { element * r = this; @@ -28,6 +35,12 @@ namespace psemek::ui return e->loop_; } + void element::set_loop(async::event_loop * loop) + { + loop_ = loop; + post_delayed_callbacks(); + } + void element::reshape() { reshape(shape().bbox()); @@ -111,6 +124,8 @@ namespace psemek::ui auto l = loop(); if (l) l->post(std::move(f)); + else + delayed_callbacks_.push_back(std::move(f)); } void element::post_reshape() @@ -128,4 +143,17 @@ namespace psemek::ui if (c) c->set_parent(nullptr); } + void element::post_delayed_callbacks() const + { + auto l = loop(); + assert(l); + for (auto & c : delayed_callbacks_) + l->post(std::move(c)); + delayed_callbacks_.clear(); + + for (auto const & c : children()) + if (c) + c->post_delayed_callbacks(); + } + }