Support delaying posted callbacks until a ui element gets attached to an event loop

This commit is contained in:
Nikita Lisitsa 2022-02-02 22:05:40 +03:00
parent e4bd58c5ef
commit a01bd019f8
2 changed files with 34 additions and 2 deletions

View file

@ -19,7 +19,7 @@ namespace psemek::ui
: std::enable_shared_from_this<element> : std::enable_shared_from_this<element>
{ {
virtual element * parent() const { return parent_; } 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<element * const>; using children_range = util::span<element * const>;
@ -28,7 +28,7 @@ namespace psemek::ui
virtual element * root(); virtual element * root();
virtual element const * root() const; virtual element const * root() const;
virtual async::event_loop * loop() 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_move const &) { return false; }
virtual bool on_event(mouse_click const &) { return false; } virtual bool on_event(mouse_click const &) { return false; }
@ -81,6 +81,10 @@ namespace psemek::ui
std::shared_ptr<struct style const> own_style_; std::shared_ptr<struct style const> own_style_;
mutable std::shared_ptr<struct style const> merged_style_; mutable std::shared_ptr<struct style const> merged_style_;
mutable std::shared_ptr<struct style const> merged_own_style_; mutable std::shared_ptr<struct style const> merged_own_style_;
mutable std::vector<util::function<void()>> delayed_callbacks_;
void post_delayed_callbacks() const;
}; };
} }

View file

@ -7,6 +7,13 @@
namespace psemek::ui namespace psemek::ui
{ {
void element::set_parent(element * parent)
{
parent_ = parent;
if (loop())
post_delayed_callbacks();
}
element * element::root() element * element::root()
{ {
element * r = this; element * r = this;
@ -28,6 +35,12 @@ namespace psemek::ui
return e->loop_; return e->loop_;
} }
void element::set_loop(async::event_loop * loop)
{
loop_ = loop;
post_delayed_callbacks();
}
void element::reshape() void element::reshape()
{ {
reshape(shape().bbox()); reshape(shape().bbox());
@ -111,6 +124,8 @@ namespace psemek::ui
auto l = loop(); auto l = loop();
if (l) if (l)
l->post(std::move(f)); l->post(std::move(f));
else
delayed_callbacks_.push_back(std::move(f));
} }
void element::post_reshape() void element::post_reshape()
@ -128,4 +143,17 @@ namespace psemek::ui
if (c) c->set_parent(nullptr); 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();
}
} }