1 #ifndef TERMOX_WIDGET_LAYOUTS_DETAIL_SHARED_SPACE_HPP
2 #define TERMOX_WIDGET_LAYOUTS_DETAIL_SHARED_SPACE_HPP
6 #include <termox/widget/size_policy.hpp>
7 #include <termox/widget/widget.hpp>
9 #include "layout_span.hpp"
11 namespace ox::layout::detail {
14 template <
typename Parameters>
17 using Length_list = std::vector<int>;
18 using Position_list = std::vector<int>;
21 [[nodiscard]]
auto calculate_lengths(
Widget& parent) -> Length_list
24 auto children = [&parent,
this] {
27 std::next(std::begin(temp), offset_), std::end(temp),
28 typename Parameters::Primary::get_length{}(parent),
30 return typename Parameters::Primary::get_policy{}(w);
35 auto const difference = find_length_difference(parent, children);
38 this->disperse(children, difference);
39 else if (difference < 0)
40 this->reclaim(children, -1 * difference);
41 return children.get_results();
48 auto result = Position_list{};
49 result.reserve(lengths.size());
50 auto running_total = 0;
51 for (
auto length : lengths) {
52 result.push_back(running_total);
53 running_total += length;
59 [[nodiscard]]
auto get_offset() const -> std::
size_t {
return offset_; }
65 std::size_t offset_ = 0;
68 template <
typename Children_span>
69 void disperse(Children_span& children,
int surplus)
72 while (given_away != 0) {
74 for (
auto iter = children.begin_max(); iter != children.end();
76 auto const& policy = iter.get_policy();
77 auto const max_length = policy.max();
78 auto const stretch_ratio =
79 policy.stretch() / children.total_stretch();
80 auto to_add = int(stretch_ratio * surplus);
81 if ((iter->length + to_add) > max_length)
82 to_add = max_length - iter->length;
83 iter->length += to_add;
86 surplus -= given_away;
88 this->disperse_leftovers(children, surplus);
92 template <
typename Children_span>
93 void disperse_leftovers(Children_span& children,
int surplus)
95 while (children.size() != 0 && surplus != 0) {
96 for (
auto iter = children.begin_max();
97 iter != children.end() && surplus != 0; ++iter) {
104 template <
typename Children_span>
105 void reclaim(Children_span& children,
int deficit)
107 auto taken_back = -1;
108 while (taken_back != 0) {
110 for (
auto iter = children.begin_min(); iter != children.end();
112 auto const& policy = iter.get_policy();
113 auto const min_length =
static_cast<int>(policy.min());
114 auto const inverse_stretch_ratio =
115 (1. / policy.stretch()) / children.total_inverse_stretch();
116 auto to_sub =
static_cast<int>(inverse_stretch_ratio * deficit);
117 if ((
static_cast<int>(iter->length) - to_sub) < min_length)
118 to_sub =
static_cast<int>(iter->length) - min_length;
119 iter->length -= to_sub;
120 taken_back += to_sub;
122 deficit -= taken_back;
124 this->reclaim_leftovers(children, deficit);
128 template <
typename Children_span>
129 void reclaim_leftovers(Children_span& children,
int deficit)
131 while (children.size() != 0 && deficit != 0) {
132 for (
auto iter = children.begin_min();
133 iter != children.end() && deficit != 0; ++iter, --deficit) {
139 template <
typename Children_span>
140 [[nodiscard]]
static auto find_length_difference(Widget
const& parent,
141 Children_span
const& span)
144 auto const parent_length =
145 typename Parameters::Primary::get_length{}(parent);
146 auto const children_entire_length = span.entire_length();
147 return parent_length - children_entire_length;
Defines how a Layout should resize a Widget in one length Dimension.
Definition: size_policy.hpp:11
Container view to iterate over a Widget's children, yielding layout info.
Definition: layout_span.hpp:25
Divides up space between child Widgets where all Widgets share the length.
Definition: shared_space.hpp:15
void set_offset(std::size_t index)
Sets the child Widget offset, does not do bounds checking.
Definition: shared_space.hpp:62
auto get_offset() const -> std::size_t
Return the child Widget offset, the first widget included in the layout.
Definition: shared_space.hpp:59
auto calculate_positions(Length_list const &lengths) -> Position_list
Returns local primary dimension positions, starting at zero.
Definition: shared_space.hpp:45