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 _preferred_base_line = shared_base_line;
47 } else {
48 _preferred_size = {shared_thickness, _layout.minimum_size()};
49 _preferred_base_line = relative_base_line{};
50 }
51 return true;
52 } else {
53 return false;
54 }
55 }
56
57 [[nodiscard]] void update_layout(hires_utc_clock::time_point display_time_point, bool need_layout) noexcept
58 {
59 tt_axiom(gui_system_mutex.recurse_lock_count());
60
61 need_layout |= std::exchange(_request_relayout, false);
62 if (need_layout) {
63 _layout.set_size(arrangement == arrangement::row ? rectangle().width() : rectangle().height());
64
65 ssize_t index = 0;
66 for (ttlet &child : _children) {
67 update_layout_for_child(*child, index++);
68 }
69
70 tt_axiom(index == std::ssize(_children));
71 }
72 abstract_container_widget::update_layout(display_time_point, need_layout);
73 }
74
75private:
76 flow_layout _layout;
77
78 void update_constraints_for_child(
79 widget const &child,
80 ssize_t index,
81 relative_base_line &shared_base_line,
82 float &shared_thickness) noexcept
83 {
84 tt_axiom(gui_system_mutex.recurse_lock_count());
85
86 ttlet length = arrangement == arrangement::row ? child.preferred_size().minimum().width() :
87 child.preferred_size().minimum().height();
88 ttlet thickness = arrangement == arrangement::row ? child.preferred_size().minimum().height() :
89 child.preferred_size().minimum().width();
90
91 ttlet length_resistance = arrangement == arrangement::row ? child.width_resistance() : child.height_resistance();
92
93 _layout.update(index, length, length_resistance, child.margin(), child.preferred_base_line());
94
95 shared_base_line = std::max(shared_base_line, child.preferred_base_line());
96 shared_thickness = std::max(shared_thickness, thickness + child.margin() * 2.0f);
97 }
98
99 void update_layout_for_child(widget &child, ssize_t index) const noexcept
100 {
101 tt_axiom(gui_system_mutex.recurse_lock_count());
102
103 ttlet[child_offset, child_length] = _layout.get_offset_and_size(index++);
104
105 ttlet child_rectangle = arrangement == arrangement::row ?
106 aarect{
107 rectangle().left() + child_offset,
108 rectangle().bottom() + child.margin(),
109 child_length,
110 rectangle().height() - child.margin() * 2.0f} :
111 aarect{
112 rectangle().left() + child.margin(),
113 rectangle().top() - child_offset - child_length,
114 rectangle().width() - child.margin() * 2.0f,
115 child_length
116 };
117
118 ttlet child_window_rectangle = translate2{_window_rectangle} * child_rectangle;
119
120 if constexpr (arrangement == arrangement::row) {
121 child.set_layout_parameters(child_window_rectangle, _window_clipping_rectangle, _window_base_line);
122 } else {
123 child.set_layout_parameters(child_window_rectangle, _window_clipping_rectangle);
124 }
125 }
126};
127
128using row_layout_widget = row_column_layout_widget<arrangement::row>;
129using column_layout_widget = row_column_layout_widget<arrangement::column>;
130
131} // 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:112
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:39
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:111
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:96
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:57
Definition widget.hpp:96
widget(gui_window &window, std::shared_ptr< abstract_container_widget > parent) noexcept
gui_window & window
Convenient reference to the Window.
Definition widget.hpp:100
abstract_container_widget const & parent() const noexcept
Get a reference to the parent.
aarect rectangle() const noexcept
Get the rectangle in local coordinates.
Definition widget.hpp:340
T max(T... args)