From 3856fdd82729e5ba5795ce9cba2e887215166bd5 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Mon, 29 Jul 2024 13:24:14 +0300 Subject: [PATCH] UI library wip: implement frame, extend & move --- libs/ui/include/psemek/ui/extend.hpp | 19 ++++++ libs/ui/include/psemek/ui/frame.hpp | 1 + .../ui/include/psemek/ui/impl/extend_base.hpp | 32 +++++++++ libs/ui/include/psemek/ui/impl/frame_base.hpp | 29 ++++++++ libs/ui/include/psemek/ui/impl/move_base.hpp | 29 ++++++++ libs/ui/include/psemek/ui/move.hpp | 17 +++++ .../source/impl/default_component_factory.cpp | 6 ++ libs/ui/source/impl/extend_base.cpp | 67 +++++++++++++++++++ libs/ui/source/impl/frame_base.cpp | 62 +++++++++++++++++ libs/ui/source/impl/move_base.cpp | 57 ++++++++++++++++ 10 files changed, 319 insertions(+) create mode 100644 libs/ui/include/psemek/ui/extend.hpp create mode 100644 libs/ui/include/psemek/ui/impl/extend_base.hpp create mode 100644 libs/ui/include/psemek/ui/impl/frame_base.hpp create mode 100644 libs/ui/include/psemek/ui/impl/move_base.hpp create mode 100644 libs/ui/include/psemek/ui/move.hpp create mode 100644 libs/ui/source/impl/extend_base.cpp create mode 100644 libs/ui/source/impl/frame_base.cpp create mode 100644 libs/ui/source/impl/move_base.cpp diff --git a/libs/ui/include/psemek/ui/extend.hpp b/libs/ui/include/psemek/ui/extend.hpp new file mode 100644 index 00000000..cb4eb1d2 --- /dev/null +++ b/libs/ui/include/psemek/ui/extend.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include + +namespace psemek::ui +{ + + struct extend + { + react::value child = {}; + react::value left = 0.f; + react::value right = 0.f; + react::value top = 0.f; + react::value bottom = 0.f; + }; + +} diff --git a/libs/ui/include/psemek/ui/frame.hpp b/libs/ui/include/psemek/ui/frame.hpp index 17d10050..798ce907 100644 --- a/libs/ui/include/psemek/ui/frame.hpp +++ b/libs/ui/include/psemek/ui/frame.hpp @@ -10,6 +10,7 @@ namespace psemek::ui struct frame { react::value child = {}; + react::value margin = 0.f; }; } diff --git a/libs/ui/include/psemek/ui/impl/extend_base.hpp b/libs/ui/include/psemek/ui/impl/extend_base.hpp new file mode 100644 index 00000000..264236de --- /dev/null +++ b/libs/ui/include/psemek/ui/impl/extend_base.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include + +namespace psemek::ui::impl +{ + + struct extend_base + : single_container + { + extend_base(); + + void reshape(geom::box const & new_shape) override; + react::value size_constraints() const override; + + void set_child(std::unique_ptr child) override; + std::unique_ptr release_child() override; + + void update(extend const & value); + + private: + react::source> left_; + react::source> right_; + react::source> top_; + react::source> bottom_; + react::source> child_size_constraints_; + react::value size_constraints_; + }; + +} diff --git a/libs/ui/include/psemek/ui/impl/frame_base.hpp b/libs/ui/include/psemek/ui/impl/frame_base.hpp new file mode 100644 index 00000000..9047c590 --- /dev/null +++ b/libs/ui/include/psemek/ui/impl/frame_base.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include + +namespace psemek::ui::impl +{ + + struct frame_base + : single_container + { + frame_base(); + + void reshape(geom::box const & new_shape) override; + react::value size_constraints() const override; + + void set_child(std::unique_ptr child) override; + std::unique_ptr release_child() override; + + void update(frame const & value); + + private: + react::source> margin_; + react::source> child_size_constraints_; + react::value size_constraints_; + }; + +} diff --git a/libs/ui/include/psemek/ui/impl/move_base.hpp b/libs/ui/include/psemek/ui/impl/move_base.hpp new file mode 100644 index 00000000..023eafb9 --- /dev/null +++ b/libs/ui/include/psemek/ui/impl/move_base.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include + +namespace psemek::ui::impl +{ + + struct move_base + : single_container + { + move_base(); + + void reshape(geom::box const & new_shape) override; + react::value size_constraints() const override; + + void set_child(std::unique_ptr child) override; + std::unique_ptr release_child() override; + + void update(move const & value); + + private: + react::source>> offset_; + react::source> child_size_constraints_; + react::value size_constraints_; + }; + +} diff --git a/libs/ui/include/psemek/ui/move.hpp b/libs/ui/include/psemek/ui/move.hpp new file mode 100644 index 00000000..bfc71df5 --- /dev/null +++ b/libs/ui/include/psemek/ui/move.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +#include + +namespace psemek::ui +{ + + struct move + { + react::value child = {}; + react::value> offset = geom::vector{0.f, 0.f}; + }; + +} diff --git a/libs/ui/source/impl/default_component_factory.cpp b/libs/ui/source/impl/default_component_factory.cpp index 9f883e85..8e45e730 100644 --- a/libs/ui/source/impl/default_component_factory.cpp +++ b/libs/ui/source/impl/default_component_factory.cpp @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #include namespace psemek::ui::impl @@ -22,6 +25,9 @@ namespace psemek::ui::impl register_type(); register_type(); register_type(); + register_type(); + register_type(); + register_type(); register_type(); } diff --git a/libs/ui/source/impl/extend_base.cpp b/libs/ui/source/impl/extend_base.cpp new file mode 100644 index 00000000..4b761397 --- /dev/null +++ b/libs/ui/source/impl/extend_base.cpp @@ -0,0 +1,67 @@ +#include +#include +#include + +namespace psemek::ui::impl +{ + + namespace + { + + geom::box compute_child_shape(geom::box shape, float left, float right, float top, float bottom) + { + shape[0].min -= left; + shape[0].max += right; + shape[1].min -= top; + shape[1].max += bottom; + return shape; + } + + } + + extend_base::extend_base() + : left_(0.f) + , right_(0.f) + , top_(0.f) + , bottom_(0.f) + , child_size_constraints_(size_constraints::max()) + , size_constraints_(react::join(child_size_constraints_)) + {} + + void extend_base::reshape(geom::box const & new_shape) + { + single_container::reshape(new_shape); + + if (auto child = this->child()) + child->reshape(compute_child_shape(new_shape, **left_, **right_, **top_, **bottom_)); + } + + react::value extend_base::size_constraints() const + { + return size_constraints_; + } + + void extend_base::set_child(std::unique_ptr child) + { + if (child) + child_size_constraints_.set(child->size_constraints()); + else + child_size_constraints_.set(size_constraints::max()); + single_container::set_child(std::move(child)); + } + + std::unique_ptr extend_base::release_child() + { + child_size_constraints_.set(size_constraints::max()); + return single_container::release_child(); + } + + void extend_base::update(extend const & value) + { + left_.set(value.left); + right_.set(value.right); + top_.set(value.top); + bottom_.set(value.bottom); + } + +} diff --git a/libs/ui/source/impl/frame_base.cpp b/libs/ui/source/impl/frame_base.cpp new file mode 100644 index 00000000..69afa241 --- /dev/null +++ b/libs/ui/source/impl/frame_base.cpp @@ -0,0 +1,62 @@ +#include +#include +#include + +namespace psemek::ui::impl +{ + + namespace + { + + size_constraints compute_size_constraints(size_constraints const & child_size_constraints, float margin) + { + return { child_size_constraints.box + geom::vector{2.f * margin, 2.f * margin} }; + } + + geom::box compute_child_shape(geom::box const & shape, float margin) + { + return geom::expand(shape, -margin); + } + + } + + frame_base::frame_base() + : margin_(0.f) + , child_size_constraints_(size_constraints::max()) + , size_constraints_(react::map(compute_size_constraints, react::join(child_size_constraints_), react::join(margin_))) + {} + + void frame_base::reshape(geom::box const & new_shape) + { + single_container::reshape(new_shape); + + if (auto child = this->child()) + child->reshape(compute_child_shape(new_shape, **margin_)); + } + + react::value frame_base::size_constraints() const + { + return size_constraints_; + } + + void frame_base::set_child(std::unique_ptr child) + { + if (child) + child_size_constraints_.set(child->size_constraints()); + else + child_size_constraints_.set(size_constraints::max()); + single_container::set_child(std::move(child)); + } + + std::unique_ptr frame_base::release_child() + { + child_size_constraints_.set(size_constraints::max()); + return single_container::release_child(); + } + + void frame_base::update(frame const & value) + { + margin_.set(value.margin); + } + +} diff --git a/libs/ui/source/impl/move_base.cpp b/libs/ui/source/impl/move_base.cpp new file mode 100644 index 00000000..8bbe8ab0 --- /dev/null +++ b/libs/ui/source/impl/move_base.cpp @@ -0,0 +1,57 @@ +#include +#include +#include + +namespace psemek::ui::impl +{ + + namespace + { + + geom::box compute_child_shape(geom::box const & shape, geom::vector const & offset) + { + return shape + offset; + } + + } + + move_base::move_base() + : offset_({0.f, 0.f}) + , child_size_constraints_(size_constraints::max()) + , size_constraints_(react::join(child_size_constraints_)) + {} + + void move_base::reshape(geom::box const & new_shape) + { + single_container::reshape(new_shape); + + if (auto child = this->child()) + child->reshape(compute_child_shape(new_shape, **offset_)); + } + + react::value move_base::size_constraints() const + { + return size_constraints_; + } + + void move_base::set_child(std::unique_ptr child) + { + if (child) + child_size_constraints_.set(child->size_constraints()); + else + child_size_constraints_.set(size_constraints::max()); + single_container::set_child(std::move(child)); + } + + std::unique_ptr move_base::release_child() + { + child_size_constraints_.set(size_constraints::max()); + return single_container::release_child(); + } + + void move_base::update(move const & value) + { + offset_.set(value.offset); + } + +}