Replace ui::size_polygon with simpler 2d box
This commit is contained in:
parent
325dc01757
commit
018f3ae0b0
14 changed files with 144 additions and 251 deletions
|
|
@ -37,7 +37,7 @@ namespace psemek::ui::impl
|
|||
box_layout_base(react::value<float> margin);
|
||||
|
||||
void reshape(geom::box<float, 2> const & new_shape) override;
|
||||
react::value<size_polygon> size_constraints() const override;
|
||||
react::value<struct size_constraints> size_constraints() const override;
|
||||
|
||||
void set_children(std::vector<std::unique_ptr<component>> children) override;
|
||||
std::vector<std::unique_ptr<component>> release_children() override;
|
||||
|
|
@ -47,8 +47,8 @@ namespace psemek::ui::impl
|
|||
private:
|
||||
react::value<float> margin_;
|
||||
react::value<std::vector<react::value<box_layout::size_policy>>> size_policies_;
|
||||
react::source<std::vector<react::value<size_polygon>>> children_size_constraints_;
|
||||
react::value<size_polygon> size_constraints_;
|
||||
react::source<std::vector<react::value<struct size_constraints>>> children_size_constraints_;
|
||||
react::value<struct size_constraints> size_constraints_;
|
||||
};
|
||||
|
||||
extern template struct box_layout_base<0>;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/ui/impl/size_polygon.hpp>
|
||||
#include <psemek/ui/impl/size_constraints.hpp>
|
||||
#include <psemek/react/value.hpp>
|
||||
#include <psemek/geom/box.hpp>
|
||||
#include <psemek/geom/interval.hpp>
|
||||
|
|
@ -15,15 +15,12 @@ namespace psemek::ui::impl
|
|||
{
|
||||
static constexpr float infinity = std::numeric_limits<float>::infinity();
|
||||
|
||||
static size_polygon const & default_size_polygon();
|
||||
static react::value<size_polygon> default_size_constraints();
|
||||
|
||||
virtual util::span<std::unique_ptr<component> const> children() const;
|
||||
|
||||
virtual geom::box<float, 2> const & shape() const;
|
||||
virtual void reshape(geom::box<float, 2> const & new_shape);
|
||||
|
||||
virtual react::value<size_polygon> size_constraints() const;
|
||||
virtual react::value<struct size_constraints> size_constraints() const;
|
||||
|
||||
virtual ~component() {}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@
|
|||
#include <psemek/ui/key.hpp>
|
||||
#include <psemek/util/signal.hpp>
|
||||
|
||||
#include <any>
|
||||
|
||||
namespace psemek::ui::impl
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -13,15 +13,15 @@ namespace psemek::ui::impl
|
|||
single_container_base(react::value<geom::vector<float, 2>> margin);
|
||||
|
||||
void reshape(geom::box<float, 2> const & new_shape) override;
|
||||
react::value<size_polygon> size_constraints() const override;
|
||||
react::value<struct size_constraints> size_constraints() const override;
|
||||
|
||||
void set_child(std::unique_ptr<component> child) override;
|
||||
std::unique_ptr<component> release_child() override;
|
||||
|
||||
private:
|
||||
react::value<geom::vector<float, 2>> margin_;
|
||||
react::source<react::value<size_polygon>> child_size_constraints_;
|
||||
react::value<size_polygon> size_constraints_;
|
||||
react::source<react::value<struct size_constraints>> child_size_constraints_;
|
||||
react::value<struct size_constraints> size_constraints_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
28
libs/ui/include/psemek/ui/impl/size_constraints.hpp
Normal file
28
libs/ui/include/psemek/ui/impl/size_constraints.hpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/geom/box.hpp>
|
||||
|
||||
namespace psemek::ui::impl
|
||||
{
|
||||
|
||||
struct size_constraints
|
||||
{
|
||||
geom::box<float, 2> box;
|
||||
|
||||
static size_constraints max();
|
||||
};
|
||||
|
||||
size_constraints shift(size_constraints const & constraints, geom::vector<float, 2> const & delta);
|
||||
size_constraints scale(size_constraints const & constraints, float factor, int dimension);
|
||||
|
||||
float min(size_constraints const & constraints, int dimension);
|
||||
|
||||
size_constraints intersect(size_constraints const & constraints1, size_constraints const & constraints2);
|
||||
|
||||
geom::interval<float> range(size_constraints const & constraints, int dimension);
|
||||
|
||||
size_constraints cut(size_constraints const & constraints, int dimension, geom::interval<float> const & range);
|
||||
|
||||
size_constraints sum_along(size_constraints const & constraints1, size_constraints const & constraints2, int dimension);
|
||||
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/geom/point.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace psemek::ui::impl
|
||||
{
|
||||
|
||||
constexpr float max_size = 16384.f;
|
||||
|
||||
// Convex, in CCW order
|
||||
using size_polygon = std::vector<geom::point<float, 2>>;
|
||||
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/ui/impl/size_polygon.hpp>
|
||||
#include <psemek/geom/interval.hpp>
|
||||
|
||||
namespace psemek::ui::impl
|
||||
{
|
||||
|
||||
size_polygon shift(size_polygon polygon, geom::vector<float, 2> const & delta);
|
||||
|
||||
size_polygon min(size_polygon const & polygon, int dimension);
|
||||
|
||||
size_polygon intersect(size_polygon const & polygon1, size_polygon const & polygon2);
|
||||
|
||||
geom::interval<float> range(size_polygon const & polygon, int dimension);
|
||||
size_polygon cut(size_polygon const & polygon, int dimension, geom::interval<float> const & range);
|
||||
size_polygon sum_along(size_polygon const & polygon1, size_polygon const & polygon2, int dimension);
|
||||
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ namespace psemek::ui::impl
|
|||
stack_layout_base();
|
||||
|
||||
void reshape(geom::box<float, 2> const & new_shape) override;
|
||||
react::value<size_polygon> size_constraints() const override;
|
||||
react::value<struct size_constraints> size_constraints() const override;
|
||||
|
||||
void set_children(std::vector<std::unique_ptr<component>> children) override;
|
||||
std::vector<std::unique_ptr<component>> release_children() override;
|
||||
|
|
@ -23,8 +23,8 @@ namespace psemek::ui::impl
|
|||
{}
|
||||
|
||||
private:
|
||||
react::source<std::vector<react::value<size_polygon>>> children_size_constraints_;
|
||||
react::value<size_polygon> size_constraints_;
|
||||
react::source<std::vector<react::value<struct size_constraints>>> children_size_constraints_;
|
||||
react::value<struct size_constraints> size_constraints_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include <psemek/ui/impl/box_layout_base.hpp>
|
||||
#include <psemek/ui/impl/size_polygon_utils.hpp>
|
||||
#include <psemek/react/map.hpp>
|
||||
#include <psemek/react/join.hpp>
|
||||
|
||||
|
|
@ -12,25 +11,22 @@ namespace psemek::ui::impl
|
|||
static constexpr box_layout::size_policy default_policy = box_layout::weight{};
|
||||
|
||||
template <int Dimension>
|
||||
size_polygon compute_size_constraints(std::vector<box_layout::size_policy> const & size_policies,
|
||||
std::vector<size_polygon const *> const & children_size_constraints, float margin)
|
||||
size_constraints compute_size_constraints(std::vector<box_layout::size_policy> const & size_policies,
|
||||
std::vector<size_constraints> const & children_size_constraints, float margin)
|
||||
{
|
||||
size_polygon minimized{{0.f, 0.f}, {0.f, max_size}};
|
||||
size_polygon weight_unit = minimized;
|
||||
size_constraints minimized = size_constraints::max();
|
||||
size_constraints weight_unit = minimized;
|
||||
float weight_sum = 0.f;
|
||||
|
||||
for (std::size_t i = 0; i < size_policies.size(); ++i)
|
||||
{
|
||||
if (std::get_if<box_layout::minimized>(&size_policies[i]))
|
||||
{
|
||||
minimized = sum_along(minimized, *children_size_constraints[i], Dimension);
|
||||
minimized = sum_along(minimized, children_size_constraints[i], Dimension);
|
||||
}
|
||||
else if (auto weight = std::get_if<box_layout::weight>(&size_policies[i]))
|
||||
{
|
||||
size_polygon child = *children_size_constraints[i];
|
||||
for (auto & p : child)
|
||||
p[Dimension] /= weight->value;
|
||||
weight_unit = sum_along(weight_unit, child, Dimension);
|
||||
weight_unit = intersect(weight_unit, scale(children_size_constraints[i], 1.f / weight->value, Dimension));
|
||||
weight_sum += weight->value;
|
||||
}
|
||||
}
|
||||
|
|
@ -38,17 +34,15 @@ namespace psemek::ui::impl
|
|||
auto result = std::move(minimized);
|
||||
|
||||
if (weight_sum > 0.f)
|
||||
result = sum_along(result, scale(weight_unit, weight_sum, Dimension), Dimension);
|
||||
|
||||
if (size_policies.size() > 0)
|
||||
{
|
||||
for (auto & p : weight_unit)
|
||||
p[Dimension] *= weight_sum;
|
||||
result = sum_along(result, weight_unit, Dimension);
|
||||
geom::vector shift_delta{0.f, 0.f};
|
||||
shift_delta[Dimension] = margin * (size_policies.size() - 1);
|
||||
result = shift(std::move(result), shift_delta);
|
||||
}
|
||||
|
||||
geom::vector shift_delta{0.f, 0.f};
|
||||
shift_delta[Dimension] = margin;
|
||||
|
||||
result = shift(std::move(result), shift_delta);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +62,7 @@ namespace psemek::ui::impl
|
|||
|
||||
if (std::get_if<box_layout::minimized>(&policy))
|
||||
{
|
||||
result[i] = min(*children[i]->size_constraints(), Dimension).front()[Dimension];
|
||||
result[i] = min(*children[i]->size_constraints(), Dimension);
|
||||
total_size -= result[i];
|
||||
}
|
||||
else if (auto weight = std::get_if<box_layout::weight>(&policy))
|
||||
|
|
@ -98,12 +92,16 @@ namespace psemek::ui::impl
|
|||
: margin_(margin)
|
||||
, size_policies_({})
|
||||
, children_size_constraints_()
|
||||
, size_constraints_(react::map([](auto const & size_policies, auto const & children_size_constraints, auto const & margin){
|
||||
return compute_size_constraints<Dimension>(size_policies, children_size_constraints, margin);
|
||||
},
|
||||
react::join(react::map(react::unpack_with_default(default_policy), size_policies_)),
|
||||
react::join(react::map(react::unpack_with_transform([](react::value<size_polygon> const & arg){ return &(*arg); }), children_size_constraints_)),
|
||||
margin_))
|
||||
, size_constraints_(
|
||||
react::map(
|
||||
[](auto const & size_policies, auto const & children_size_constraints, auto const & margin){
|
||||
return compute_size_constraints<Dimension>(size_policies, children_size_constraints, margin);
|
||||
},
|
||||
react::join(react::map(react::unpack_with_default(default_policy), size_policies_)),
|
||||
react::join(react::map(react::unpack, children_size_constraints_)),
|
||||
margin_
|
||||
)
|
||||
)
|
||||
{}
|
||||
|
||||
template <int Dimension>
|
||||
|
|
@ -134,7 +132,7 @@ namespace psemek::ui::impl
|
|||
}
|
||||
|
||||
template <int Dimension>
|
||||
react::value<size_polygon> box_layout_base<Dimension>::size_constraints() const
|
||||
react::value<size_constraints> box_layout_base<Dimension>::size_constraints() const
|
||||
{
|
||||
return size_constraints_;
|
||||
}
|
||||
|
|
@ -144,13 +142,13 @@ namespace psemek::ui::impl
|
|||
{
|
||||
container::set_children(std::move(children));
|
||||
|
||||
std::vector<react::value<size_polygon>> children_size_constraints;
|
||||
std::vector<react::value<struct size_constraints>> children_size_constraints;
|
||||
for (auto const & child : this->children())
|
||||
{
|
||||
if (child)
|
||||
children_size_constraints.push_back(child->size_constraints());
|
||||
else
|
||||
children_size_constraints.push_back(default_size_constraints());
|
||||
children_size_constraints.push_back(size_constraints::max());
|
||||
}
|
||||
children_size_constraints_.set(std::move(children_size_constraints));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,24 +3,6 @@
|
|||
namespace psemek::ui::impl
|
||||
{
|
||||
|
||||
size_polygon const & component::default_size_polygon()
|
||||
{
|
||||
static size_polygon const result{{
|
||||
{max_size, 0.f},
|
||||
{0.f, 0.f},
|
||||
{0.f, max_size},
|
||||
{max_size, max_size}
|
||||
}};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
react::value<size_polygon> component::default_size_constraints()
|
||||
{
|
||||
static react::value<size_polygon> const result{default_size_polygon()};
|
||||
return result;
|
||||
}
|
||||
|
||||
util::span<std::unique_ptr<component> const> component::children() const
|
||||
{
|
||||
return {};
|
||||
|
|
@ -36,9 +18,10 @@ namespace psemek::ui::impl
|
|||
shape_ = new_shape;
|
||||
}
|
||||
|
||||
react::value<size_polygon> component::size_constraints() const
|
||||
react::value<size_constraints> component::size_constraints() const
|
||||
{
|
||||
return default_size_constraints();
|
||||
static react::value<struct size_constraints> const result{size_constraints::max()};
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include <psemek/ui/impl/single_container_base.hpp>
|
||||
#include <psemek/ui/impl/size_polygon_utils.hpp>
|
||||
#include <psemek/react/map.hpp>
|
||||
#include <psemek/react/join.hpp>
|
||||
|
||||
|
|
@ -8,8 +7,8 @@ namespace psemek::ui::impl
|
|||
|
||||
single_container_base::single_container_base(react::value<geom::vector<float, 2>> margin)
|
||||
: margin_(margin)
|
||||
, child_size_constraints_(default_size_constraints())
|
||||
, size_constraints_(react::map([](size_polygon const & child_constraints, geom::vector<float, 2> const & margin){
|
||||
, child_size_constraints_(size_constraints::max())
|
||||
, size_constraints_(react::map([](struct size_constraints const & child_constraints, geom::vector<float, 2> const & margin){
|
||||
return shift(child_constraints, margin);
|
||||
}, react::join(child_size_constraints_), margin))
|
||||
{}
|
||||
|
|
@ -22,7 +21,7 @@ namespace psemek::ui::impl
|
|||
child()->reshape(geom::shrink(new_shape, *margin_));
|
||||
}
|
||||
|
||||
react::value<size_polygon> single_container_base::size_constraints() const
|
||||
react::value<size_constraints> single_container_base::size_constraints() const
|
||||
{
|
||||
return size_constraints_;
|
||||
}
|
||||
|
|
@ -30,13 +29,13 @@ namespace psemek::ui::impl
|
|||
void single_container_base::set_child(std::unique_ptr<component> child)
|
||||
{
|
||||
single_container::set_child(std::move(child));
|
||||
child_size_constraints_.set(this->child() ? this->child()->size_constraints() : default_size_constraints());
|
||||
child_size_constraints_.set(this->child() ? this->child()->size_constraints() : size_constraints::max());
|
||||
}
|
||||
|
||||
std::unique_ptr<component> single_container_base::release_child()
|
||||
{
|
||||
auto child = single_container::release_child();
|
||||
child_size_constraints_.set(default_size_constraints());
|
||||
child_size_constraints_.set(size_constraints::max());
|
||||
return child;
|
||||
}
|
||||
|
||||
|
|
|
|||
63
libs/ui/source/impl/size_constraints.cpp
Normal file
63
libs/ui/source/impl/size_constraints.cpp
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#include <psemek/ui/impl/size_constraints.hpp>
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace psemek::ui::impl
|
||||
{
|
||||
|
||||
size_constraints size_constraints::max()
|
||||
{
|
||||
static constexpr float infinity = std::numeric_limits<float>::infinity();
|
||||
|
||||
return
|
||||
{{{
|
||||
{0.f, infinity},
|
||||
{0.f, infinity},
|
||||
}}};
|
||||
}
|
||||
|
||||
size_constraints shift(size_constraints const & constraints, geom::vector<float, 2> const & delta)
|
||||
{
|
||||
return {constraints.box + delta};
|
||||
}
|
||||
|
||||
size_constraints scale(size_constraints const & constraints, float factor, int dimension)
|
||||
{
|
||||
auto result = constraints;
|
||||
result.box[dimension].min *= factor;
|
||||
result.box[dimension].max *= factor;
|
||||
return result;
|
||||
}
|
||||
|
||||
float min(size_constraints const & constraints, int dimension)
|
||||
{
|
||||
return constraints.box[dimension].min;
|
||||
}
|
||||
|
||||
size_constraints intersect(size_constraints const & constraints1, size_constraints const & constraints2)
|
||||
{
|
||||
return {constraints1.box & constraints2.box};
|
||||
}
|
||||
|
||||
geom::interval<float> range(size_constraints const & constraints, int dimension)
|
||||
{
|
||||
return constraints.box[dimension];
|
||||
}
|
||||
|
||||
size_constraints cut(size_constraints const & constraints, int dimension, geom::interval<float> const & range)
|
||||
{
|
||||
size_constraints result = constraints;
|
||||
result.box[dimension] &= range;
|
||||
return result;
|
||||
}
|
||||
|
||||
size_constraints sum_along(size_constraints const & constraints1, size_constraints const & constraints2, int dimension)
|
||||
{
|
||||
size_constraints result;
|
||||
result.box[dimension].min = constraints1.box[dimension].min + constraints2.box[dimension].min;
|
||||
result.box[dimension].max = constraints1.box[dimension].max + constraints2.box[dimension].max;
|
||||
result.box[dimension ^ 1] = constraints1.box[dimension ^ 1] & constraints2.box[dimension ^ 1];
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
#include <psemek/ui/impl/size_polygon_utils.hpp>
|
||||
#include <psemek/geom/math.hpp>
|
||||
#include <psemek/util/not_implemented.hpp>
|
||||
#include <psemek/util/cyclic_iterator.hpp>
|
||||
|
||||
namespace psemek::ui::impl
|
||||
{
|
||||
|
||||
size_polygon shift(size_polygon polygon, geom::vector<float, 2> const & delta)
|
||||
{
|
||||
for (auto & p : polygon)
|
||||
p += delta;
|
||||
return polygon;
|
||||
}
|
||||
|
||||
size_polygon min(size_polygon const & polygon, int dimension)
|
||||
{
|
||||
if (polygon.empty())
|
||||
return {};
|
||||
|
||||
size_polygon result;
|
||||
|
||||
auto cit = util::make_cyclic_iterator(polygon);
|
||||
std::size_t iterations = 0;
|
||||
|
||||
for (auto next = std::next(cit); (*next)[dimension] <= (*cit)[dimension] && iterations < polygon.size(); cit = next++, ++iterations);
|
||||
|
||||
if (iterations == polygon.size())
|
||||
return polygon;
|
||||
|
||||
for (auto prev = std::prev(cit); (*prev)[dimension] <= (*cit)[dimension]; cit = prev--);
|
||||
|
||||
for (auto cjt = cit; (*cjt)[dimension] == (*cit)[dimension]; ++cjt)
|
||||
result.push_back(*cjt);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_polygon intersect(size_polygon const & polygon1, size_polygon const & polygon2)
|
||||
{
|
||||
// TODO: https://www.cs.jhu.edu/~misha/Spring16/ORourke82.pdf
|
||||
(void)polygon1;
|
||||
(void)polygon2;
|
||||
util::not_implemented();
|
||||
}
|
||||
|
||||
geom::interval<float> range(size_polygon const & polygon, int dimension)
|
||||
{
|
||||
geom::interval<float> result;
|
||||
for (auto const & p : polygon)
|
||||
result |= p[dimension];
|
||||
return result;
|
||||
}
|
||||
|
||||
size_polygon cut(size_polygon const & polygon, int dimension, geom::interval<float> const & range)
|
||||
{
|
||||
size_polygon result;
|
||||
std::size_t iterations = 0;
|
||||
for (auto it = util::make_cyclic_iterator(polygon), next_it = std::next(it); iterations != polygon.size(); (it = next_it++), ++iterations)
|
||||
{
|
||||
auto const & curr = *it;
|
||||
auto const & next = *next_it;
|
||||
|
||||
auto intersection = [&](float value)
|
||||
{
|
||||
// curr + (next - curr) * t = value
|
||||
float t = (value - curr[dimension]) / (next[dimension] - curr[dimension]);
|
||||
geom::point<float, 2> p;
|
||||
p[dimension] = value;
|
||||
p[dimension ^ 1] = geom::lerp(curr[dimension ^ 1], next[dimension ^ 1], t);
|
||||
return p;
|
||||
};
|
||||
|
||||
auto classify = [&](float value)
|
||||
{
|
||||
if (value < range.min)
|
||||
return -2;
|
||||
else if (value == range.min)
|
||||
return -1;
|
||||
else if (value < range.max)
|
||||
return 0;
|
||||
else if (value == range.max)
|
||||
return 1;
|
||||
else // (value > range.max)
|
||||
return 2;
|
||||
};
|
||||
|
||||
int const curr_class = classify(curr[dimension]);
|
||||
int const next_class = classify(next[dimension]);
|
||||
|
||||
if (curr_class >= -1 && curr_class <= 1)
|
||||
result.push_back(curr);
|
||||
|
||||
bool const min = (curr_class == -2 && next_class >= 0) || (curr_class >= 0 && next_class == -2);
|
||||
bool const max = (curr_class == 2 && next_class <= 0) || (curr_class <= 0 && next_class == 2);
|
||||
|
||||
|
||||
if (range.min == range.max)
|
||||
{
|
||||
if (min) result.push_back(intersection(range.min));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (min) result.push_back(intersection(range.min));
|
||||
if (max) result.push_back(intersection(range.max));
|
||||
|
||||
if (min && max && curr_class == 2)
|
||||
std::swap(result.back(), result[result.size() - 2]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_polygon sum_along(size_polygon const & polygon1, size_polygon const & polygon2, int dimension)
|
||||
{
|
||||
if (polygon1.empty() || polygon2.empty())
|
||||
return size_polygon{};
|
||||
|
||||
int const other_dimension = dimension ^ 1;
|
||||
|
||||
auto range1 = range(polygon1, other_dimension);
|
||||
auto range2 = range(polygon2, other_dimension);
|
||||
|
||||
auto common_range = range1 & range2;
|
||||
if (common_range.empty())
|
||||
return size_polygon{};
|
||||
|
||||
auto cut1 = cut(polygon1, other_dimension, common_range);
|
||||
auto cut2 = cut(polygon2, other_dimension, common_range);
|
||||
|
||||
util::not_implemented();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
#include <psemek/ui/impl/stack_layout_base.hpp>
|
||||
#include <psemek/ui/impl/size_polygon_utils.hpp>
|
||||
#include <psemek/react/join.hpp>
|
||||
#include <psemek/react/map.hpp>
|
||||
|
||||
|
|
@ -9,14 +8,11 @@ namespace psemek::ui::impl
|
|||
namespace
|
||||
{
|
||||
|
||||
size_polygon compute_size_constraints(std::vector<size_polygon const *> const & children_size_constraints)
|
||||
size_constraints compute_size_constraints(std::vector<size_constraints> const & children_size_constraints)
|
||||
{
|
||||
if (children_size_constraints.empty())
|
||||
return component::default_size_polygon();
|
||||
|
||||
auto result = *children_size_constraints.front();
|
||||
for (std::size_t i = 1; i < children_size_constraints.size(); ++i)
|
||||
result = intersect(result, *children_size_constraints[i]);
|
||||
size_constraints result = size_constraints::max();
|
||||
for (auto const & constraints : children_size_constraints)
|
||||
result = intersect(result, constraints);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -25,7 +21,7 @@ namespace psemek::ui::impl
|
|||
stack_layout_base::stack_layout_base()
|
||||
: size_constraints_(react::map([](auto const & children_size_constraints){
|
||||
return compute_size_constraints(children_size_constraints);
|
||||
}, react::join(react::map(react::unpack_with_transform([](react::value<size_polygon> const & arg){ return &(*arg); }), children_size_constraints_))))
|
||||
}, react::join(react::map(react::unpack, children_size_constraints_))))
|
||||
{}
|
||||
|
||||
void stack_layout_base::reshape(geom::box<float, 2> const & new_shape)
|
||||
|
|
@ -35,7 +31,7 @@ namespace psemek::ui::impl
|
|||
child->reshape(new_shape);
|
||||
}
|
||||
|
||||
react::value<size_polygon> stack_layout_base::size_constraints() const
|
||||
react::value<size_constraints> stack_layout_base::size_constraints() const
|
||||
{
|
||||
return size_constraints_;
|
||||
}
|
||||
|
|
@ -43,13 +39,13 @@ namespace psemek::ui::impl
|
|||
void stack_layout_base::set_children(std::vector<std::unique_ptr<component>> children)
|
||||
{
|
||||
container::set_children(std::move(children));
|
||||
std::vector<react::value<size_polygon>> children_size_constraints;
|
||||
std::vector<react::value<struct size_constraints>> children_size_constraints;
|
||||
for (auto const & child : this->children())
|
||||
{
|
||||
if (child)
|
||||
children_size_constraints.push_back(child->size_constraints());
|
||||
else
|
||||
children_size_constraints.push_back(default_size_constraints());
|
||||
children_size_constraints.push_back(size_constraints::max());
|
||||
}
|
||||
children_size_constraints_.set(std::move(children_size_constraints));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue