HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
tab_widget.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2021-2022.
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
9#pragma once
10
11#include "widget.hpp"
12#include "grid_widget.hpp"
13#include "tab_delegate.hpp"
14#include "../macros.hpp"
15
16namespace hi { inline namespace v1 {
17
37class tab_widget final : public widget {
38public:
39 using super = widget;
40 using delegate_type = tab_delegate;
41
43
45 {
46 hi_assert_not_null(delegate);
47 delegate->deinit(*this);
48 }
49
56 {
57 hi_axiom(loop::main().on_thread());
58 hi_assert_not_null(parent);
59
60 // The tab-widget will not draw itself, only its selected child.
61 semantic_layer = parent->semantic_layer;
62
63 hi_assert_not_null(this->delegate);
64 _delegate_cbt = this->delegate->subscribe([&] {
65 ++global_counter<"tab_widget:delegate:constrain">;
67 });
68
69 this->delegate->init(*this);
70 }
71
79 requires requires { make_default_tab_delegate(hi_forward(value)); }
80 : tab_widget(parent, make_default_tab_delegate(hi_forward(value)))
81 {
82 }
83
92 template<typename WidgetType, typename Key, typename... Args>
93 WidgetType& make_widget(Key const& key, Args&&...args)
94 {
95 hi_axiom(loop::main().on_thread());
96
97 auto tmp = std::make_unique<WidgetType>(this, std::forward<Args>(args)...);
98 auto& ref = *tmp;
99
100 hi_assert_not_null(delegate);
101 delegate->add_tab(*this, static_cast<std::size_t>(key), size(_children));
102 _children.push_back(std::move(tmp));
103 ++global_counter<"tab_widget:make_widget:constrain">;
105 return ref;
106 }
107
109 [[nodiscard]] generator<widget_intf &> children(bool include_invisible) noexcept override
110 {
111 for (hilet& child : _children) {
112 co_yield *child;
113 }
114 }
115
116 [[nodiscard]] box_constraints update_constraints() noexcept override
117 {
118 _layout = {};
119
120 auto& selected_child_ = selected_child();
121
122 if (_previous_selected_child != &selected_child_) {
123 _previous_selected_child = &selected_child_;
124 hi_log_info("tab_widget::update_constraints() selected tab changed");
126 }
127
128 for (hilet& child : _children) {
129 child->mode = child.get() == &selected_child_ ? widget_mode::enabled : widget_mode::invisible;
130 }
131
132 return selected_child_.update_constraints();
133 }
134 void set_layout(widget_layout const& context) noexcept override
135 {
136 _layout = context;
137
138 for (hilet& child : _children) {
139 if (*child->mode > widget_mode::invisible) {
140 child->set_layout(context);
141 }
142 }
143 }
144 void draw(draw_context const& context) noexcept override
145 {
147 for (hilet& child : _children) {
148 child->draw(context);
149 }
150 }
151 }
152 [[nodiscard]] hitbox hitbox_test(point2 position) const noexcept override
153 {
154 hi_axiom(loop::main().on_thread());
155
156 if (*mode >= widget_mode::partial) {
157 auto r = hitbox{};
158 for (hilet& child : _children) {
159 r = child->hitbox_test_from_parent(position, r);
160 }
161 return r;
162 } else {
163 return {};
164 }
165 }
166 [[nodiscard]] widget_id find_next_widget(
167 widget_id current_widget,
168 keyboard_focus_group group,
169 keyboard_focus_direction direction) const noexcept override
170 {
171 hi_axiom(loop::main().on_thread());
172 return selected_child().find_next_widget(current_widget, group, direction);
173 }
175private:
176 widget const *_previous_selected_child = nullptr;
178 notifier<>::callback_token _delegate_cbt;
179
180 using const_iterator = decltype(_children)::const_iterator;
181
182 [[nodiscard]] const_iterator find_selected_child() const noexcept
183 {
184 hi_axiom(loop::main().on_thread());
185 hi_assert_not_null(delegate);
186
187 auto index = delegate->index(const_cast<tab_widget&>(*this));
188 if (index >= 0 and index < ssize(_children)) {
189 return _children.begin() + index;
190 }
191
192 return _children.end();
193 }
194 [[nodiscard]] widget& selected_child() const noexcept
195 {
196 hi_axiom(loop::main().on_thread());
197 hi_assert(not _children.empty());
198
199 auto i = find_selected_child();
200 if (i != _children.cend()) {
201 return **i;
202 } else {
203 return *_children.front();
204 }
205 }
206};
207
208}} // namespace hi::v1
Defines widget.
Defines grid_widget.
Defines delegate_delegate and some default tab delegates.
@ window_reconstrain
Request that widget get constraint on the next frame.
@ window_resize
Request that the window resizes to desired constraints on the next frame.
std::shared_ptr< tab_delegate > make_default_tab_delegate(auto &&value) noexcept
Create a shared pointer to a default tab delegate.
Definition tab_delegate.hpp:103
@ partial
A widget is partially enabled.
@ invisible
The widget is invisible.
@ enabled
The widget is fully enabled.
DOXYGEN BUG.
Definition algorithm.hpp:16
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
widget_intf * parent
Pointer to the parent widget.
Definition widget_intf.hpp:28
A delegate that controls the state of a tab_widget.
Definition tab_delegate.hpp:22
A graphical element that shows only one of a predefined set of mutually exclusive child widgets.
Definition tab_widget.hpp:37
tab_widget(widget *parent, different_from< std::shared_ptr< delegate_type > > auto &&value) noexcept
Construct a tab widget with an observer value.
Definition tab_widget.hpp:78
WidgetType & make_widget(Key const &key, Args &&...args)
Make and add a child widget.
Definition tab_widget.hpp:93
tab_widget(widget *parent, std::shared_ptr< delegate_type > delegate) noexcept
Construct a tab widget with a delegate.
Definition tab_widget.hpp:55
An interactive graphical object as part of the user-interface.
Definition widget.hpp:37
int semantic_layer
The draw layer of the widget.
Definition widget.hpp:66
virtual widget_id find_next_widget(widget_id current_keyboard_widget, keyboard_focus_group group, keyboard_focus_direction direction) const noexcept override
Find the next widget that handles keyboard focus.
Definition widget.hpp:288
widget(widget *parent) noexcept
Definition widget.hpp:87
bool process_event(gui_event const &event) const noexcept override
Send a event to the window.
Definition widget.hpp:178
observer< widget_mode > mode
The widget mode.
Definition widget.hpp:42
Definition concepts.hpp:54
T begin(T... args)
T empty(T... args)
T end(T... args)
T front(T... args)
T move(T... args)