HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
widget_state.hpp
1// Copyright Take Vos 2023.
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 "../concurrency/concurrency.hpp"
8#include "../macros.hpp"
9#include <cstdint>
10#include <utility>
11#include <concepts>
12#include <compare>
13
14hi_export_module(hikogui.GUI : widget_state);
15
16hi_export namespace hi { inline namespace v1 {
17
25enum class widget_mode {
33 collapse = 0,
34
40 invisible = 1,
41
47 disabled = 2,
48
54 display = 3,
55
62 select = 4,
63
72 partial = 5,
73
80 enabled = 6,
81};
82
83enum class widget_value {
84 off = 0,
85 on = 1,
86 other = 2,
87};
88
89enum class widget_phase {
90 inactive = 0,
91 normal = 1,
92 hover = 2,
93 pressed = 3,
94};
95
96constexpr auto widget_state_mode_shift = 0;
97constexpr auto widget_state_value_shift = 5;
98
105public:
106 constexpr widget_state(widget_state const &) noexcept = default;
107 constexpr widget_state(widget_state &&) noexcept = default;
108 constexpr widget_state &operator=(widget_state const &) noexcept = default;
109 constexpr widget_state &operator=(widget_state &&) noexcept = default;
110
111 constexpr widget_state() noexcept = default;
112
115 constexpr static widget_state begin() noexcept
116 {
117 auto r = widget_state{};
119 r.set_layer(0);
120 r.set_value(widget_value::off);
121 r.set_pressed(false);
122 r.set_hover(false);
123 r.set_active(false);
124 r.set_focus(false);
125 return r;
126 }
127
130 constexpr static widget_state end() noexcept
131 {
132 auto r = begin();
133 r._end = true;
134 return r;
135 }
136
139 constexpr static size_t size() noexcept
140 {
141 return static_cast<size_t>(end());
142 }
143
148 [[nodiscard]] constexpr widget_mode mode() const noexcept
149 {
150 return static_cast<widget_mode>(_mode);
151 }
152
158 {
159 _mode = static_cast<uint16_t>(mode);
160 return *this;
161 }
162
168 [[nodiscard]] constexpr size_t layer() const noexcept
169 {
170 return _layer;
171 }
172
177 constexpr widget_state &set_layer(size_t layer) noexcept
178 {
179 _layer = static_cast<uint16_t>(layer % 4);
180 return *this;
181 }
182
187 [[nodiscard]] constexpr widget_value value() const noexcept
188 {
189 return static_cast<widget_value>(_value);
190 }
191
196 constexpr widget_state &set_value(widget_value value) noexcept
197 {
198 _value = static_cast<uint16_t>(value);
199 return *this;
200 }
201
206 [[nodiscard]] constexpr widget_phase phase() const noexcept
207 {
208 if (_pressed) {
209 return widget_phase::pressed;
210 } else if (_hover) {
211 return widget_phase::hover;
212 } else if (_active) {
213 return widget_phase::normal;
214 } else {
215 return widget_phase::inactive;
216 }
217 }
218
223 constexpr widget_state &set_pressed(bool pressed) noexcept
224 {
225 _pressed = static_cast<bool>(pressed);
226 return *this;
227 }
228
233 constexpr widget_state &set_hover(bool hover) noexcept
234 {
235 _hover = static_cast<bool>(hover);
236 return *this;
237 }
238
243 constexpr widget_state &set_active(bool active) noexcept
244 {
245 _active = static_cast<bool>(active);
246 return *this;
247 }
248
251 [[nodiscard]] constexpr bool focus() const noexcept
252 {
253 return static_cast<bool>(_focus);
254 }
255
258 constexpr widget_state &set_focus(bool focus) noexcept
259 {
260 _focus = static_cast<uint16_t>(focus);
261 return *this;
262 }
263
270 template<std::integral T>
271 constexpr explicit operator T() const noexcept
272 requires(sizeof(T) >= 2)
273 {
274 auto r = T{0};
275
276 r += static_cast<T>(_end);
277
278 r *= 2;
279 r += static_cast<T>(focus());
280
281 r *= 4;
282 r += static_cast<T>(phase());
283
284 r *= 3;
285 r += static_cast<T>(value());
286
287 r *= 4;
288 r += static_cast<T>(layer());
289
290 r *= 7;
291 r += static_cast<T>(mode());
292 return r;
293 }
294
295 [[nodiscard]] constexpr friend bool operator==(widget_state const &lhs, widget_state const &rhs) noexcept
296 {
297 return static_cast<uint16_t>(lhs) == static_cast<uint16_t>(rhs);
298 }
299
305 constexpr widget_state& operator++() noexcept
306 {
307 if (mode() < widget_mode::enabled) {
308 set_mode(static_cast<widget_mode>(std::to_underlying(mode()) + 1));
309 return *this;
310 }
312
313 if (layer() < 3) {
314 set_layer(layer() + 1);
315 return *this;
316 }
317 set_layer(0);
318
319 if (value() < widget_value::other) {
320 set_value(static_cast<widget_value>(std::to_underlying(value()) + 1));
321 return *this;
322 }
323 set_value(widget_value::off);
324
325 switch (phase()) {
326 case widget_phase::inactive:
327 set_pressed(false);
328 set_hover(false);
329 set_active(true);
330 return *this;
331 case widget_phase::normal:
332 set_pressed(false);
333 set_hover(true);
334 set_active(true);
335 return *this;
336 case widget_phase::hover:
337 set_pressed(true);
338 set_hover(true);
339 set_active(true);
340 return *this;
341 case widget_phase::pressed:
342 set_pressed(false);
343 set_hover(false);
344 set_active(false);
345 break;
346 default:
347 hi_no_default();
348 }
349
350 if (focus() == false) {
351 set_focus(true);
352 return *this;
353 }
354 set_focus(false);
355
356 _end = true;
357 return *this;
358 }
359
362 [[nodiscard]] constexpr friend bool need_reconstrain(widget_state const &lhs, widget_state const &rhs) noexcept
363 {
364 return lhs._mode != rhs._mode;
365 }
366
369 [[nodiscard]] constexpr friend bool need_relayout(widget_state const &lhs, widget_state const &rhs) noexcept
370 {
371 return need_reconstrain(lhs, rhs) or lhs._layer != rhs._layer;
372 }
373
376 [[nodiscard]] constexpr friend bool need_redraw(widget_state const &lhs, widget_state const &rhs) noexcept
377 {
378 return lhs != rhs;
379 }
380
381private:
384 uint16_t _mode : 3 = static_cast<uint16_t>(widget_mode::enabled);
385
388 uint16_t _layer : 2 = 0;
389
392 uint16_t _value : 2 = static_cast<uint16_t>(widget_value::off);
393
396 uint16_t _active: 1 = 1;
397
400 uint16_t _hover : 1 = 0;
401
404 uint16_t _pressed : 1 = 0;
405
408 uint16_t _focus : 1 = 0;
409
412 uint16_t _end : 1 = 0;
413};
414
415}}
@ other
The gui_event does not have associated data.
widget_mode
The mode that the widget is operating at.
Definition widget_state.hpp:25
@ partial
A widget is partially enabled.
@ collapse
The widget is collapsed.
@ invisible
The widget is invisible.
@ select
The widget is selectable.
@ enabled
The widget is fully enabled.
@ display
The widget is in display-only mode.
The HikoGUI namespace.
Definition array_generic.hpp:20
@ on
The border is drawn on the edge of a quad.
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
The state the widget is in.
Definition widget_state.hpp:104
constexpr widget_state & set_layer(size_t layer) noexcept
Set the layer of the widget.
Definition widget_state.hpp:177
constexpr widget_state & set_hover(bool hover) noexcept
Set if the mouse hovers over the widget.
Definition widget_state.hpp:233
constexpr widget_state & set_mode(widget_mode mode) noexcept
Set the mode of a widget.
Definition widget_state.hpp:157
static constexpr widget_state end() noexcept
End of the iteration of all possible widget states.
Definition widget_state.hpp:130
constexpr size_t layer() const noexcept
Get the layer of a widget.
Definition widget_state.hpp:168
constexpr widget_state & set_active(bool active) noexcept
Set if the window is active widget.
Definition widget_state.hpp:243
constexpr bool focus() const noexcept
Get if the window has keyboard focus.
Definition widget_state.hpp:251
constexpr widget_phase phase() const noexcept
Get the phase of the widget.
Definition widget_state.hpp:206
constexpr widget_state & set_value(widget_value value) noexcept
Set the value of the widget.
Definition widget_state.hpp:196
constexpr widget_state & set_pressed(bool pressed) noexcept
Set if the mouse/finger presses the widget.
Definition widget_state.hpp:223
constexpr friend bool need_reconstrain(widget_state const &lhs, widget_state const &rhs) noexcept
Check if the change in widget-state requires the widget to reconstrain.
Definition widget_state.hpp:362
static constexpr size_t size() noexcept
The number if possible widget states.
Definition widget_state.hpp:139
static constexpr widget_state begin() noexcept
Start of the iteration of all possible widget states.
Definition widget_state.hpp:115
constexpr widget_state & operator++() noexcept
Increment the widget-state.
Definition widget_state.hpp:305
constexpr widget_state & set_focus(bool focus) noexcept
Set if the window has keyboard focus.
Definition widget_state.hpp:258
constexpr friend bool need_relayout(widget_state const &lhs, widget_state const &rhs) noexcept
Check if the change in widget-state requires the widget to relayout.
Definition widget_state.hpp:369
constexpr widget_value value() const noexcept
Get the value of the widget.
Definition widget_state.hpp:187
constexpr widget_mode mode() const noexcept
Get the mode of a widget.
Definition widget_state.hpp:148
constexpr friend bool need_redraw(widget_state const &lhs, widget_state const &rhs) noexcept
Check if the change in widget-state requires the widget to redraw.
Definition widget_state.hpp:376