diff --git a/libs/ui/source/controller.cpp b/libs/ui/source/controller.cpp index d1d5f4a9..aebd51e9 100644 --- a/libs/ui/source/controller.cpp +++ b/libs/ui/source/controller.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -8,12 +9,54 @@ namespace psemek::ui { + namespace + { + + struct root_proxy + : element + { + children_range children() const override + { + return children_range{&root_raw, &root_raw + 1}; + } + + struct shape const & shape() const override + { + return shape_; + } + + using element::reshape; + + void reshape(geom::box const & bbox) + { + shape_.box = bbox; + if (root) + root->reshape(bbox); + if (on_reshape) + on_reshape(); + } + + geom::box size_constraints() const override + { + return root->size_constraints(); + } + + void draw(painter &) const override {} + + std::shared_ptr root; + element * root_raw = nullptr; + box_shape shape_; + std::function on_reshape; + }; + + } + struct controller::impl { async::executor * loop; painter_impl painter; - std::shared_ptr root; - geom::box shape{{{0.f, 0.f}, {0.f, 0.f}}}; + std::shared_ptr root; + std::optional> mouse; impl(async::executor * loop); @@ -23,7 +66,14 @@ namespace psemek::ui controller::impl::impl(async::executor * loop) : loop(loop) - {} + , root{std::make_shared()} + { + root->set_loop(loop); + root->on_reshape = [this]{ + if (mouse) + event(mouse_move{*mouse}); + }; + } template bool controller::impl::event(E const & e) @@ -49,31 +99,33 @@ namespace psemek::ui std::shared_ptr controller::set_root(std::shared_ptr r) { - auto old = std::move(impl().root); - impl().root = std::move(r); - if (old) old->set_loop(nullptr); - if (impl().root) - { - impl().root->set_loop(impl().loop); - impl().root->reshape(impl().shape); - } + auto old = std::move(impl().root->root); + if (old) + old->set_parent(nullptr); + + impl().root->root = std::move(r); + impl().root->root_raw = impl().root->root.get(); + if (impl().root->root) + impl().root->root->set_parent(impl().root.get()); + + impl().root->reshape(); + return old; } element * controller::root() { - return impl().root.get(); + return impl().root->root.get(); } void controller::reshape(geom::box const & shape) { - impl().shape = shape; - if (impl().root) - impl().root->reshape(impl().shape); + impl().root->reshape(shape); } bool controller::event(mouse_move const & e) { + impl().mouse = e.position; return impl().event(e); } @@ -105,8 +157,7 @@ namespace psemek::ui if (c) self(c); }); - if (impl().root) - visitor(impl().root.get()); + visitor(impl().root.get()); impl().painter.render(geom::window_camera{rt.viewport[0].length(), rt.viewport[1].length()}.transform()); }