18 minimum_size(0), preferred_size(0), maximum_size(0), offset(0), size(0)
27 constexpr void update(
float min_size,
float pref_size,
float max_size)
noexcept
34 maximum_size =
std::max(maximum_size, minimum_size);
37 preferred_size = std::clamp(preferred_size, minimum_size, maximum_size);
39 tt_axiom(minimum_size <= preferred_size);
40 tt_axiom(preferred_size <= maximum_size);
66 [[nodiscard]]
size_t nr_items()
const noexcept
71 void update(
ssize_t index,
float minimum_size,
float preferred_size,
float maximum_size,
float margin)
noexcept
74 tt_axiom(index < std::ssize(items));
75 tt_axiom(index + 1 < std::ssize(margins));
77 items[index].update(minimum_size, preferred_size, maximum_size);
79 ttlet margin_ = narrow_cast<int>(
std::ceil(margin));
80 margins[index] =
std::max(margins[index], margin_);
81 margins[index + 1] =
std::max(margins[index + 1], margin_);
84 [[nodiscard]]
int total_margin_size()
const noexcept
89 [[nodiscard]]
float minimum_size()
const noexcept
91 auto a = total_margin_size();
92 for (ttlet &item : items) {
93 a += item.minimum_size;
95 return narrow_cast<float>(a);
98 [[nodiscard]]
float preferred_size()
const noexcept
100 auto a = total_margin_size();
101 for (ttlet &item : items) {
102 a += item.preferred_size;
104 return narrow_cast<float>(a);
107 [[nodiscard]]
float maximum_size()
const noexcept
109 auto a = total_margin_size();
110 for (ttlet &item : items) {
111 a += item.maximum_size;
113 return narrow_cast<float>(a);
120 ttlet total_size_ = narrow_cast<int>(
std::round(total_size));
122 tt_axiom(total_size_ >= minimum_size());
124 set_items_to_preferred_size();
126 auto grow_by = total_size_ - size();
127 while (grow_by != 0) {
128 int num = num_items_can_resize(grow_by);
130 auto resize_beyond_maximum = num == 0;
131 if (resize_beyond_maximum) {
132 num = narrow_cast<int>(std::size(items));
135 resize_items(num, grow_by, resize_beyond_maximum);
137 grow_by = total_size_ - size();
143 tt_axiom(index < std::size(items));
144 auto offset = narrow_cast<float>(items[index].offset);
145 auto size = narrow_cast<float>(items[index].size);
146 return {offset, size};
153 while (std::ssize(items) < new_size) {
154 items.emplace_back();
157 while (std::ssize(margins) < new_size + 1) {
161 tt_axiom(margins.
size() == items.size() + 1);
172 void set_items_to_preferred_size() noexcept
174 for (
auto &&item : items) {
175 item.
size = item.preferred_size;
177 calculate_offset_and_size();
180 [[nodiscard]]
int num_items_can_resize(
int grow_by)
noexcept
183 return narrow_cast<int>(std::ranges::count_if(items, [](ttlet &item) {
184 return item.size < item.maximum_size;
186 }
else if (grow_by < 0) {
187 return narrow_cast<int>(std::ranges::count_if(items, [](ttlet &item) {
188 return item.size > item.minimum_size;
196 [[nodiscard]]
void resize_items(
int nr_items,
int grow_by,
bool resize_beyond_maximum)
noexcept
198 tt_axiom(grow_by != 0);
199 tt_axiom(nr_items > 0);
201 auto per_item_grow_by = grow_by / nr_items;
202 if (per_item_grow_by == 0) {
203 per_item_grow_by = grow_by > 0 ? 1 : -1;
206 for (
auto &&item : items) {
207 auto new_item_size = item.size + per_item_grow_by;
208 if (!resize_beyond_maximum) {
209 new_item_size = std::clamp(new_item_size, item.minimum_size, item.maximum_size);
212 ttlet this_item_grown_by = new_item_size - item.size;
213 item.size = new_item_size;
215 tt_axiom(item.size >= item.minimum_size);
216 if (!resize_beyond_maximum) {
217 tt_axiom(item.size <= item.maximum_size);
220 if ((grow_by -= this_item_grown_by) == 0) {
226 calculate_offset_and_size();
229 void calculate_offset_and_size() noexcept
232 for (ssize_t i = 0; i != std::ssize(items); ++i) {
233 offset += margins[i];
234 items[i].offset = offset;
235 offset += items[i].
size;
242 [[nodiscard]]
int size() const noexcept
245 return margins.
back();
247 tt_axiom(items.
back().offset >= 0);
248 return items.
back().offset + items.
back().size + margins.
back();
void reserve(ssize_t new_size) noexcept
Grow layout to include upto new_size of items.
Definition flow_layout.hpp:151
void set_size(float total_size) noexcept
Update the layout of all items based on the total size.
Definition flow_layout.hpp:118