HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
row_column_layout_widget.hpp
1// Copyright Take Vos 2020.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "abstract_container_widget.hpp"
8#include "../GUI/theme.hpp"
9#include "../flow_layout.hpp"
10#include "../alignment.hpp"
11#include <memory>
12
13namespace tt {
14
15template<arrangement Arrangement>
17public:
19 static constexpr auto arrangement = Arrangement;
20
23 {
24 }
25
26 [[nodiscard]] bool update_constraints(hires_utc_clock::time_point display_time_point, bool need_reconstrain) noexcept
27 {
28 tt_axiom(gui_system_mutex.recurse_lock_count());
29
30 if (super::update_constraints(display_time_point, need_reconstrain)) {
31 auto shared_base_line = relative_base_line{vertical_alignment::middle, 0.0f, 100};
32 auto shared_thickness = 0.0f;
33
34 _layout.clear();
35 _layout.reserve(std::ssize(_children));
36
37 ssize_t index = 0;
38 for (ttlet &child : _children) {
39 update_constraints_for_child(*child, index++, shared_base_line, shared_thickness);
40 }
41
42 tt_axiom(index == std::ssize(_children));
43
44 if constexpr (arrangement == arrangement::row) {
45 _preferred_size = {_layout.minimum_size(), shared_thickness};
46 } else {
47 _preferred_size = {shared_thickness, _layout.minimum_size()};
48 }
49 return true;
50 } else {
51 return false;
52 }
53 }
54
55 [[nodiscard]] void update_layout(hires_utc_clock::time_point display_time_point, bool need_layout) noexcept
56 {
57 tt_axiom(gui_system_mutex.recurse_lock_count());
58
59 need_layout |= std::exchange(_request_relayout, false);
60 if (need_layout) {
61 _layout.set_size(arrangement == arrangement::row ? rectangle().width() : rectangle().height());
62
63 ssize_t index = 0;
64 for (ttlet &child : _children) {
65 update_layout_for_child(*child, index++);
66 }
67
68 tt_axiom(index == std::ssize(_children));
69 }
70 abstract_container_widget::update_layout(display_time_point, need_layout);
71 }
72
73private:
74 flow_layout _layout;
75
76 void update_constraints_for_child(
77 widget const &child,
78 ssize_t index,
79 relative_base_line &shared_base_line,
80 float &shared_thickness) noexcept
81 {
82 tt_axiom(gui_system_mutex.recurse_lock_count());
83
84 ttlet length = arrangement == arrangement::row ? child.preferred_size().minimum().width() :
85 child.preferred_size().minimum().height();
86 ttlet thickness = arrangement == arrangement::row ? child.preferred_size().minimum().height() :
87 child.preferred_size().minimum().width();
88
89 ttlet length_resistance = arrangement == arrangement::row ? child.width_resistance() : child.height_resistance();
90
91 _layout.update(index, length, length_resistance, child.margin());
92
93 shared_thickness = std::max(shared_thickness, thickness + child.margin() * 2.0f);
94 }
95
96 void update_layout_for_child(widget &child, ssize_t index) const noexcept
97 {
98 tt_axiom(gui_system_mutex.recurse_lock_count());
99
100 ttlet[child_offset, child_length] = _layout.get_offset_and_size(index++);
101
102 ttlet child_rectangle = arrangement == arrangement::row ?
103 aarectangle{
104 rectangle().left() + child_offset,
105 rectangle().bottom() + child.margin(),
106 child_length,
107 rectangle().height() - child.margin() * 2.0f} :
108 aarectangle{
109 rectangle().left() + child.margin(),
110 rectangle().top() - child_offset - child_length,
111 rectangle().width() - child.margin() * 2.0f,
112 child_length
113 };
114
115
116 child.set_layout_parameters_from_parent(child_rectangle);
117 }
118};
119
120using row_layout_widget = row_column_layout_widget<arrangement::row>;
121using column_layout_widget = row_column_layout_widget<arrangement::column>;
122
123} // namespace tt
Definition alignment.hpp:104
Layout algorithm.
Definition flow_layout.hpp:18
void reserve(ssize_t new_size) noexcept
Grow layout to include upto new_size of items.
Definition flow_layout.hpp:106
std::pair< float, float > get_offset_and_size(ssize_t first, ssize_t last) const noexcept
Definition flow_layout.hpp:88
void set_size(float total_size) noexcept
Update the layout of all items based on the total size.
Definition flow_layout.hpp:57
Definition gui_window.hpp:37
int recurse_lock_count() const noexcept
This function should be used in tt_axiom() to check if the lock is held by current thread.
Definition unfair_recursive_mutex.hpp:60
Definition abstract_container_widget.hpp:11
void update_layout(hires_utc_clock::time_point display_time_point, bool need_layout) noexcept
Update the internal layout of the widget.
Definition abstract_container_widget.hpp:110
bool update_constraints(hires_utc_clock::time_point display_time_point, bool need_reconstrain) noexcept
Update the constraints of the widget.
Definition abstract_container_widget.hpp:95
Definition row_column_layout_widget.hpp:16
bool update_constraints(hires_utc_clock::time_point display_time_point, bool need_reconstrain) noexcept
Update the constraints of the widget.
Definition row_column_layout_widget.hpp:26
void update_layout(hires_utc_clock::time_point display_time_point, bool need_layout) noexcept
Update the internal layout of the widget.
Definition row_column_layout_widget.hpp:55
Definition widget.hpp:97
widget(gui_window &window, std::shared_ptr< abstract_container_widget > parent) noexcept
aarectangle rectangle() const noexcept
Get the rectangle in local coordinates.
Definition widget.hpp:342
gui_window & window
Convenient reference to the Window.
Definition widget.hpp:101
abstract_container_widget const & parent() const noexcept
Get a reference to the parent.
T max(T... args)