116 lines
2.6 KiB
C++
116 lines
2.6 KiB
C++
#include <psemek/ui/screen.hpp>
|
|
|
|
namespace psemek::ui
|
|
{
|
|
|
|
screen::screen()
|
|
: container_(this)
|
|
{}
|
|
|
|
element::children_range screen::children() const
|
|
{
|
|
return container_.children();
|
|
}
|
|
|
|
bool screen::add_child(std::shared_ptr<element> c, x_policy x, y_policy y)
|
|
{
|
|
auto i = container_.add(std::move(c));
|
|
if (i >= policies_.size())
|
|
policies_.resize(i + 1);
|
|
policies_[i] = {x, y};
|
|
return true;
|
|
}
|
|
|
|
bool screen::add_child(std::shared_ptr<element> c)
|
|
{
|
|
return add_child(std::move(c), x_policy::floating, y_policy::floating);
|
|
}
|
|
|
|
bool screen::has_child(element *c) const
|
|
{
|
|
return static_cast<bool>(container_.find(c));
|
|
}
|
|
|
|
std::shared_ptr<element> screen::remove_child(element * c)
|
|
{
|
|
return container_.remove(c);
|
|
}
|
|
|
|
void screen::reshape(geom::box<float, 2> const & bbox)
|
|
{
|
|
shape_.box = bbox;
|
|
auto cs = children();
|
|
for (std::size_t i = 0; i < cs.size(); ++i)
|
|
{
|
|
auto c = cs[i];
|
|
if (!c) continue;
|
|
auto sc = c->size_constraints();
|
|
auto size = bbox.dimensions();
|
|
size[0] = std::min(size[0], sc[0].min);
|
|
size[1] = std::min(size[1], sc[1].min);
|
|
|
|
auto m = bbox.center();
|
|
|
|
geom::box<float, 2> cbox = c->shape().bbox();
|
|
|
|
switch (policies_[i].x)
|
|
{
|
|
case x_policy::left:
|
|
cbox[0] = {bbox[0].min, bbox[0].min + size[0]};
|
|
break;
|
|
case x_policy::center:
|
|
cbox[0] = {m[0] - size[0] / 2.f, m[0] + size[0] / 2.f};
|
|
break;
|
|
case x_policy::right:
|
|
cbox[0] = {bbox[0].max - size[0], bbox[0].max};
|
|
break;
|
|
case x_policy::full:
|
|
cbox[0] = bbox[0];
|
|
break;
|
|
case x_policy::floating:
|
|
cbox[0] = geom::expand(cbox[0], (size[0] - cbox[0].length()) / 2.f);
|
|
|
|
if (cbox[0].min < bbox[0].min)
|
|
cbox[0] += (bbox[0].min - cbox[0].min);
|
|
else if (cbox[0].max > bbox[0].max)
|
|
cbox[0] -= (cbox[0].max - bbox[0].max);
|
|
break;
|
|
}
|
|
|
|
switch (policies_[i].y)
|
|
{
|
|
case y_policy::top:
|
|
cbox[1] = {bbox[1].min, bbox[1].min + size[1]};
|
|
break;
|
|
case y_policy::center:
|
|
cbox[1] = {m[1] - size[1] / 2.f, m[1] + size[1] / 2.f};
|
|
break;
|
|
case y_policy::bottom:
|
|
cbox[1] = {bbox[1].max - size[1], bbox[1].max};
|
|
break;
|
|
case y_policy::full:
|
|
cbox[1] = bbox[1];
|
|
break;
|
|
case y_policy::floating:
|
|
cbox[1] = geom::expand(cbox[1], (size[1] - cbox[1].length()) / 2.f);
|
|
|
|
if (cbox[1].min < bbox[1].min)
|
|
cbox[1] += (bbox[1].min - cbox[1].min);
|
|
else if (cbox[1].max > bbox[1].max)
|
|
cbox[1] -= (cbox[1].max - bbox[1].max);
|
|
break;
|
|
}
|
|
|
|
c->reshape(cbox);
|
|
}
|
|
}
|
|
|
|
geom::box<float, 2> screen::size_constraints() const
|
|
{
|
|
geom::box<float, 2> result = element::size_constraints();
|
|
for (auto c : children())
|
|
if (c) result &= c->size_constraints();
|
|
return result;
|
|
}
|
|
|
|
}
|