diff --git a/libs/ui/include/psemek/ui/positioner.hpp b/libs/ui/include/psemek/ui/positioner.hpp new file mode 100644 index 00000000..7fce5944 --- /dev/null +++ b/libs/ui/include/psemek/ui/positioner.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +namespace psemek::ui +{ + + struct positioner + : single_container + { + enum class x_align + { + left, + center, + right, + }; + + enum class y_align + { + top, + center, + bottom, + }; + + struct shape const & shape() const override; + void reshape(geom::box const & box) override; + + virtual void set_position(geom::point const & p, x_align x, y_align y); + + void draw(ui::painter &) const override {} + + private: + box_shape shape_; + + geom::point position_{0.f, 0.f}; + x_align x_; + y_align y_; + }; + +} diff --git a/libs/ui/source/positioner.cpp b/libs/ui/source/positioner.cpp new file mode 100644 index 00000000..61e50ba1 --- /dev/null +++ b/libs/ui/source/positioner.cpp @@ -0,0 +1,64 @@ +#include + +namespace psemek::ui +{ + + shape const & positioner::shape() const + { + return shape_; + } + + void positioner::reshape(geom::box const & box) + { + shape_.box = box; + + if (!child_) + return; + + auto sc = child_->size_constraints(); + + geom::vector size; + size[0] = sc[0].min; + size[1] = sc[1].min; + + geom::box cbox; + cbox[0].min = position_[0]; + cbox[1].min = position_[1]; + cbox[0].max = cbox[0].min + size[0]; + cbox[1].max = cbox[1].min + size[1]; + + switch (x_) + { + case x_align::left: + break; + case x_align::center: + cbox[0] -= size[0] / 2.f; + break; + case x_align::right: + cbox[0] -= size[0]; + break; + } + + switch (y_) + { + case y_align::top: + break; + case y_align::center: + cbox[1] -= size[1] / 2.f; + break; + case y_align::bottom: + cbox[1] -= size[1]; + break; + } + + child_->reshape(cbox); + } + + void positioner::set_position(geom::point const & p, x_align x, y_align y) + { + position_ = p; + x_ = x; + y_ = y; + } + +}