31 [[nodiscard]]
size_t nr_items()
const noexcept
40 tt_axiom(index < std::ssize(items));
41 tt_axiom(index + 1 < std::ssize(margins));
42 items[index].update(extent, resistance, base_line);
43 margins[index] =
std::max(margins[index], margin);
44 margins[index+1] =
std::max(margins[index+1], margin);
47 [[nodiscard]]
float minimum_size()
const noexcept
51 return acc + item.minimum_size();
58 set_items_to_minimum_size();
59 auto extra_size = total_size -
size();
62 auto nr_can_grow = number_of_items_that_can_grow(resistance);
63 while (extra_size >= 1.0f && nr_can_grow != 0) {
64 nr_can_grow = grow_items(nr_can_grow, resistance, extra_size);
68 calculate_offset_and_size();
74 [[nodiscard]]
float size() const noexcept
77 return margins.
back();
79 tt_axiom(items.
back().offset >= 0.0f);
80 return items.
back().offset + items.
back().size + margins.
back();
90 tt_axiom(first >= 0 && first < std::ssize(items));
91 tt_axiom(last > 0 && last <= std::ssize(items));
93 auto offset = items[first].offset;
94 auto size = (items[last - 1].offset + items[last - 1].
size) - offset;
95 return {offset,
size};
104 [[nodiscard]] relative_base_line get_base_line(ssize_t index)
const noexcept
106 tt_axiom(index >= 0 && index < ssize(items));
107 return items[index].base_line();
114 while (std::ssize(items) < new_size) {
118 while (std::ssize(margins) < new_size + 1) {
122 tt_axiom(margins.
size() == items.
size() + 1);
126 struct flow_layout_item {
127 constexpr flow_layout_item() noexcept : _minimum_size(0.0f), _resistance(1), _base_line(), offset(-1.0f), size(-1.0f) {}
129 constexpr flow_layout_item(flow_layout_item
const &rhs)
noexcept =
default;
130 constexpr flow_layout_item(flow_layout_item &&rhs)
noexcept =
default;
131 constexpr flow_layout_item &operator=(flow_layout_item
const &rhs)
noexcept =
default;
132 constexpr flow_layout_item &operator=(flow_layout_item &&rhs)
noexcept =
default;
134 constexpr void update(
float minimum_size, ranged_int<3> resistance, relative_base_line base_line)
noexcept
136 _minimum_size =
std::max(_minimum_size, minimum_size);
137 switch (
static_cast<int>(resistance)) {
139 _resistance = _resistance == 2 ? 2 : 0;
149 _base_line =
std::max(_base_line, base_line);
152 [[nodiscard]]
float minimum_size() const noexcept {
153 return _minimum_size;
156 [[nodiscard]]
float maximum_size() const noexcept {
160 [[nodiscard]] ranged_int<3> resistance() const noexcept
165 [[nodiscard]] relative_base_line base_line() const noexcept
175 ranged_int<3> _resistance;
176 relative_base_line _base_line;
186 void set_items_to_minimum_size() noexcept
188 for (
auto &&item : items) {
191 calculate_offset_and_size();
194 [[nodiscard]] ssize_t number_of_items_that_can_grow(ranged_int<3> resistance)
const noexcept
196 auto nr_non_max = ssize_t{0};
198 for (
auto &&item : items) {
199 if (item.resistance() == resistance && item.size < item.maximum_size()) {
206 [[nodiscard]] ssize_t grow_items(ssize_t nr_non_max, ranged_int<3> resistance,
float &extra_size)
noexcept
208 ttlet extra_size_per_item =
std::ceil(extra_size / nr_non_max);
211 for (
auto &&item : items) {
212 if (item.resistance() == resistance) {
213 auto old_size = item.size;
215 ttlet extra_size_this_item =
std::min(extra_size, extra_size_per_item);
217 item.size =
std::ceil(item.size + extra_size_this_item);
218 extra_size -= item.size - old_size;
220 if (item.size < item.maximum_size()) {
228 void calculate_offset_and_size() noexcept
231 for (ssize_t i = 0; i != std::ssize(items); ++i) {
232 offset += margins[i];
234 offset += items[i].
size;