CYD-UI
A C++ library for building native graphic user interfaces
Loading...
Searching...
No Matches
component_event_handler.cppm
Go to the documentation of this file.
1// Copyright (c) 2024, Víctor Castillo Agüero.
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4module;
6
8
9export import std;
10
11export import cydui.components.base;
12export import cydui.components.anchors;
13
14export import cydui.events;
15export import cydui.graphics;
16
17
18#define TO_STRING(...) #__VA_ARGS__
19#define ANCHOR(PREFIX, NAME) \
20 struct NAME { \
21 static constexpr dimension_parameter_t x{TO_STRING(PREFIX##_##NAME##_x)}; \
22 static constexpr dimension_parameter_t y{TO_STRING(PREFIX##_##NAME##_y)}; \
23 }
24
25#define CYDUI_INTERNAL_EV_HANDLER_DECL(NAME) void on_##NAME CYDUI_INTERNAL_EV_##NAME##_ARGS
26
27#define CYDUI_INTERNAL_EV_HANDLER_DECL_W_RET(NAME) \
28 CYDUI_INTERNAL_EV_##NAME##_RETURN on_##NAME CYDUI_INTERNAL_EV_##NAME##_ARGS
29
30
31export {
32 namespace cydui::components {
33
34
35#pragma clang diagnostic push
36#pragma ide diagnostic ignored "OCUnusedMacroInspection"
37
40 private:
41 component_base_t* component = nullptr;
42
43 public:
44 const std::list<std::shared_ptr<component_base_t>>& $children;
45 static constexpr bool handles_text_input = false;
46
48 component_base_t* comp, const std::list<std::shared_ptr<component_base_t>>& $children_
49 )
50 : component(comp),
51 $children($children_) {}
52
53 // virtual ~event_handler_t() {}
54
56 return {};
57 }
58
59#define DIMENSIONAL_ARGS \
60 $x, $y, $width, $height, $padding_top, $padding_bottom, $padding_left, $padding_right
61
62 // ? MOUSE EVENTS
63#define CYDUI_INTERNAL_EV_button_PROPAGATE(NAME) \
64 if (component->parent.has_value()) \
65 component->parent.value()->get_event_dispatcher()->dispatch_button_##NAME( \
66 button, x + $x, y + $y \
67 );
68#define CYDUI_INTERNAL_EV_mouse_PROPAGATE(NAME) \
69 if (component->parent.has_value()) \
70 component->parent.value()->get_event_dispatcher()->dispatch_mouse_##NAME(x + $x, y + $y);
71
72 // * button press
76 // * button release
80 // * mouse enter
82 }
83 // * mouse exit
86 // * mouse motion
90 // * mouse scroll
92 if (component->parent.has_value())
93 component->parent.value()->get_event_dispatcher()->dispatch_scroll(dx, dy);
94 }
95
96 // ? KEYBOARD EVENTS
97 // * key press
99 if (component->parent.has_value())
100 component->parent.value()->get_event_dispatcher()->dispatch_key_press(ev);
101 }
102 // * key release
104 if (component->parent.has_value())
105 component->parent.value()->get_event_dispatcher()->dispatch_key_release(ev);
106 }
107
108 // * text input
110
111 // * focus changed input
113
115 };
116
117#pragma clang diagnostic pop
118
119 template <typename Component>
122 Component& component_,
123 const std::list<std::shared_ptr<component_base_t>>& children_,
124 const std::shared_ptr<typename Component::state_t>& state_,
125 const std::shared_ptr<fabric::async::async_bus_t>& window_,
126 typename Component::props_t& props_,
128 typename Component::style_t& style_
129 )
130 : event_handler_t(&component_, children_),
131 component(component_),
132 state(*state_),
133 window(*static_cast<typename Component::window_type*>(window_.get())),
134 props(props_),
135 attrs(attrs_),
136 style(style_) {}
137
138 Component& component;
139 typename Component::state_t& state;
140 typename Component::window_type& window;
141 typename Component::props_t& props;
143 typename Component::style_t& style;
144
148 };
149 } // namespace cydui::components
150
151 template <typename Event>
153 public:
155 fabric::async::async_bus_t* window,
156 std::function<fabric::task<>(const Event&)> callback,
157 std::function<fabric::task<>()> post
158 )
159 : window_(window),
160 callback_(callback),
161 post_(post) {
162 start_listening();
163 }
164
166 stop_listening();
167 }
168
170 : window_(other.window_),
171 callback_(other.callback_),
172 post_(other.post_) {
173 start_listening();
174 }
176 stop_listening();
177 this->window_ = other.window_;
178 this->callback_ = other.callback_;
179 this->post_ = other.post_;
180 start_listening();
181 return *this;
182 }
183
185 : window_(other.window_),
186 callback_(other.callback_),
187 post_(other.post_) {
188 other.stop_listening();
189 start_listening();
190 }
192 stop_listening();
193 this->window_ = other.window_;
194 this->callback_ = other.callback_;
195 this->post_ = other.post_;
196 other.stop_listening();
197 start_listening();
198 return *this;
199 }
200
201 private:
202 void start_listening() {
203 stop_listening();
204
205 listener_ = window_->on_event([&](const Event& ev) -> fabric::task<> {
206 co_await callback_(ev);
207 co_await post_();
208 co_return;
209 });
210 }
211 void stop_listening() {
212 if (listener_.has_value()) {
213 listener_.value().remove();
214 listener_ = std::nullopt;
215 }
216 }
217
218 private:
219 fabric::async::async_bus_t* window_;
220 std::function<fabric::task<>(const Event&)> callback_;
221 std::function<fabric::task<>()> post_;
222 std::optional<fabric::async::listener<Event>> listener_{std::nullopt};
223 };
224}
custom_event_listener & operator=(custom_event_listener &&other)
custom_event_listener(custom_event_listener &&other) noexcept
custom_event_listener(fabric::async::async_bus_t *window, std::function< fabric::task<>(const Event &)> callback, std::function< fabric::task<>()> post)
custom_event_listener(const custom_event_listener &other)
custom_event_listener & operator=(const custom_event_listener &other)
#define CYDUI_INTERNAL_EV_mouse_PROPAGATE(NAME)
#define CYDUI_INTERNAL_EV_HANDLER_DECL(NAME)
#define CYDUI_INTERNAL_EV_HANDLER_DECL_W_RET(NAME)
#define CYDUI_INTERNAL_EV_button_PROPAGATE(NAME)
#define CYDUI_INTERNAL_EV_fragment_ARGS
event_handler_data_t(Component &component_, const std::list< std::shared_ptr< component_base_t > > &children_, const std::shared_ptr< typename Component::state_t > &state_, const std::shared_ptr< fabric::async::async_bus_t > &window_, typename Component::props_t &props_, attrs_component< Component > &attrs_, typename Component::style_t &style_)
event_handler_t(component_base_t *comp, const std::list< std::shared_ptr< component_base_t > > & $children_)
const std::list< std::shared_ptr< component_base_t > > & $children
void draw_fragment(vg::fragment_t &fragment, const cydui::dimension_t::value_type & $x, const cydui::dimension_t::value_type & $y, const cydui::dimension_t::value_type & $width, const cydui::dimension_t::value_type & $height, const cydui::dimension_t::value_type & $padding_top, const cydui::dimension_t::value_type & $padding_bottom, const cydui::dimension_t::value_type & $padding_left, const cydui::dimension_t::value_type & $padding_right)