Add ui::positioner element that helps with positioning a child on screen

This commit is contained in:
Nikita Lisitsa 2022-03-10 12:22:33 +03:00
parent 976b493e2b
commit e83fef3369
2 changed files with 105 additions and 0 deletions

View file

@ -0,0 +1,41 @@
#pragma once
#include <psemek/ui/single_container.hpp>
#include <psemek/ui/box_shape.hpp>
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<float, 2> const & box) override;
virtual void set_position(geom::point<float, 2> const & p, x_align x, y_align y);
void draw(ui::painter &) const override {}
private:
box_shape shape_;
geom::point<float, 2> position_{0.f, 0.f};
x_align x_;
y_align y_;
};
}

View file

@ -0,0 +1,64 @@
#include <psemek/ui/positioner.hpp>
namespace psemek::ui
{
shape const & positioner::shape() const
{
return shape_;
}
void positioner::reshape(geom::box<float, 2> const & box)
{
shape_.box = box;
if (!child_)
return;
auto sc = child_->size_constraints();
geom::vector<float, 2> size;
size[0] = sc[0].min;
size[1] = sc[1].min;
geom::box<float, 2> 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<float, 2> const & p, x_align x, y_align y)
{
position_ = p;
x_ = x;
y_ = y;
}
}