HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
abstract_button_widget.hpp
1// Copyright Take Vos 2020-2021.
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 "widget.hpp"
8
9namespace tt {
10
15template<typename T>
17public:
18 using super = widget;
19 using value_type = T;
20
21 value_type const true_value;
23
24 using notifier_type = notifier<void()>;
25 using callback_type = typename notifier_type::callback_type;
26 using callback_ptr_type = typename notifier_type::callback_ptr_type;
27
28 template<typename Value = observable<value_type>>
29 [[nodiscard]] abstract_button_widget(
32 value_type true_value,
33 Value &&value = {}) :
34 super(window, parent), true_value(std::move(true_value)), value(std::forward<Value>(value))
35 {
36 }
37
38 color background_color() const noexcept override
39 {
40 if (_pressed) {
41 return theme::global->fillColor(this->_semantic_layer + 2);
42 } else {
43 return super::background_color();
44 }
45 }
46
47 [[nodiscard]] bool accepts_keyboard_focus(keyboard_focus_group group) const noexcept
48 {
49 tt_axiom(gui_system_mutex.recurse_lock_count());
50 return is_normal(group) && *enabled;
51 }
52
53 [[nodiscard]] bool handle_event(command command) noexcept
54 {
55 ttlet lock = std::scoped_lock(gui_system_mutex);
56
57 if (*enabled) {
58 switch (command) {
59 case command::gui_activate: this->_notifier(); return true;
60 case command::gui_enter:
61 this->_notifier();
62 this->window.update_keyboard_target(
63 this->shared_from_this(), keyboard_focus_group::normal, keyboard_focus_direction::forward);
64 return true;
65 default:;
66 }
67 }
68
69 return super::handle_event(command);
70 }
71
72 [[nodiscard]] bool handle_event(mouse_event const &event) noexcept final
73 {
74 ttlet lock = std::scoped_lock(gui_system_mutex);
75 auto handled = super::handle_event(event);
76
77 if (event.cause.leftButton) {
78 handled = true;
79 if (*enabled) {
80 if (compare_then_assign(_pressed, static_cast<bool>(event.down.leftButton))) {
81 request_redraw();
82 }
83
84 if (event.type == mouse_event::Type::ButtonUp && rectangle().contains(event.position)) {
85 handled |= handle_event(command::gui_activate);
86 }
87 }
88 }
89 return handled;
90 }
91
92 [[nodiscard]] hit_box hitbox_test(point2 position) const noexcept final
93 {
94 tt_axiom(gui_system_mutex.recurse_lock_count());
95
96 if (_visible_rectangle.contains(position)) {
97 return hit_box{weak_from_this(), _draw_layer, *enabled ? hit_box::Type::Button : hit_box::Type::Default};
98 } else {
99 return hit_box{};
100 }
101 }
102
106 template<typename Callback>
107 [[nodiscard]] callback_ptr_type subscribe(Callback &&callback) noexcept
108 {
109 return _notifier.subscribe(std::forward<Callback>(callback));
110 }
111
115 void unsubscribe(callback_ptr_type &callback_ptr) noexcept
116 {
117 return _notifier.unsubscribe(callback_ptr);
118 }
119
120protected:
123 bool _pressed = false;
124
125private:
126 notifier_type _notifier;
127};
128
129} // namespace tt
This is a RGBA floating point color.
Definition color.hpp:39
Class which represents an rectangle.
Definition rectangle.hpp:16
Definition gui_window.hpp:37
void update_keyboard_target(std::shared_ptr< tt::widget > widget, keyboard_focus_group group=keyboard_focus_group::normal) noexcept
Change the keyboard focus to the given widget.
Definition hit_box.hpp:15
Definition mouse_event.hpp:15
Definition observable.hpp:20
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
An abstract button widget.
Definition abstract_button_widget.hpp:16
callback_ptr_type subscribe(Callback &&callback) noexcept
Subscribe a callback to call when the button is activated.
Definition abstract_button_widget.hpp:107
hit_box hitbox_test(point2 position) const noexcept final
Find the widget that is under the mouse cursor.
Definition abstract_button_widget.hpp:92
bool accepts_keyboard_focus(keyboard_focus_group group) const noexcept
Check if the widget will accept keyboard focus.
Definition abstract_button_widget.hpp:47
bool handle_event(command command) noexcept
Handle command.
Definition abstract_button_widget.hpp:53
void unsubscribe(callback_ptr_type &callback_ptr) noexcept
Unsubscribe a callback.
Definition abstract_button_widget.hpp:115
bool handle_event(mouse_event const &event) noexcept final
Definition abstract_button_widget.hpp:72
Definition widget.hpp:97
observable< bool > enabled
The widget is enabled.
Definition widget.hpp:105
widget(gui_window &window, std::shared_ptr< abstract_container_widget > parent) noexcept
virtual bool handle_event(command command) noexcept
Handle command.
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 move(T... args)