CYD-UI
A C++ library for building native graphic user interfaces
Loading...
Searching...
No Matches
component_event_dispatcher.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;
5#include <tracy/Tracy.hpp>
6
8
9import std;
10
11import fabric.logging;
12import fabric.memory.lazy_alloc;
13import fabric.async;
14export import fabric.wiring.signals;
15
17
18export using children_list = std::vector<cydui::components::component_holder_t>;
19
20namespace cydui::components {
21 export template <typename ComponentType, typename EventHandler>
23 public:
24 explicit event_dispatcher_t(component_base_t *component): component_(component) {
25 ZoneScopedN("event_dispatcher_t");
26 auto &style = *static_cast<typename ComponentType::style_t *>(&component_->get_style_data().as_base());
27 event_handler_ = std::make_shared<EventHandler>(event_handler_data_t<ComponentType> {
28 *static_cast<ComponentType*>(component_),
29 component_->children,
30 std::dynamic_pointer_cast<typename ComponentType::state_t>(component_->state()),
31 (std::dynamic_pointer_cast<typename ComponentType::state_t>(component_->state()))->window,
32 static_cast<ComponentType*>(component_)->props,
33 *static_cast<attrs_component<ComponentType>*>(static_cast<ComponentType*>(component_)),
34 style
35 });
36
37 if constexpr (refl::Reflected<EventHandler>) {
38 static constexpr std::size_t field_count = refl::field_count<EventHandler>;
39
40 configure_event_handler_fields(std::make_index_sequence<field_count> { });
41 }
42 }
43
44 std::vector<component_holder_t> update(StyleArchive& style_archive, component_builder_t& content_children_builder) override {
45 ZoneScopedN("Update - Component EV");
46 auto eh = static_cast<EventHandler*>(event_handler_.get());
47 auto [at, ir] = component_data();
48 return eh->on_redraw(
49 at.x,
50 at.y,
51 ir.cw,
52 ir.ch,
53 at.padding_top,
54 at.padding_bottom,
55 at.padding_left,
56 at.padding_right,
57 content_children_builder
58 );
59 }
60 void paint_fragment(vg::fragment_t &fragment) override {
61 ZoneScopedN("Paint Fragment - Component EV");
62 auto eh = static_cast<EventHandler*>(event_handler_.get());
63 auto [at, ir] = component_data();
64 eh->draw_fragment(
65 fragment,
70 dimensions::get_value(at.padding_top),
71 dimensions::get_value(at.padding_bottom),
72 dimensions::get_value(at.padding_left),
73 dimensions::get_value(at.padding_right)
74 );
75 }
76
77 void dispatch_key_press(const KeyEvent &ev) override {
78 ZoneScopedN("Key Press - Component EV");
79 auto eh = static_cast<EventHandler*>(event_handler_.get());
80 auto [at, ir] = component_data();
81 eh->on_key_press(
82 ev,
87 dimensions::get_value(at.padding_top),
88 dimensions::get_value(at.padding_bottom),
89 dimensions::get_value(at.padding_left),
90 dimensions::get_value(at.padding_right)
91 );
92 }
93
94 void dispatch_key_release(const KeyEvent &ev) override {
95 ZoneScopedN("Key Release - Component EV");
96 auto eh = static_cast<EventHandler*>(event_handler_.get());
97 auto [at, ir] = component_data();
98 eh->on_key_release(
99 ev,
104 dimensions::get_value(at.padding_top),
105 dimensions::get_value(at.padding_bottom),
106 dimensions::get_value(at.padding_left),
107 dimensions::get_value(at.padding_right)
108 );
109 }
110
111 void dispatch_text_input(const TextInputEvent &ev) override {
112 ZoneScopedN("Text Input - Component EV");
113 auto eh = static_cast<EventHandler*>(event_handler_.get());
114 auto [at, ir] = component_data();
115 eh->on_text_input(
116 ev,
121 dimensions::get_value(at.padding_top),
122 dimensions::get_value(at.padding_bottom),
123 dimensions::get_value(at.padding_left),
124 dimensions::get_value(at.padding_right)
125 );
126 }
127
129 const Button &button,
132 ) override {
133 ZoneScopedN("Button Press - Component EV");
134 auto eh = static_cast<EventHandler*>(event_handler_.get());
135 auto [at, ir] = component_data();
136 eh->on_button_press(
137 button,
138 x,
139 y,
144 dimensions::get_value(at.padding_top),
145 dimensions::get_value(at.padding_bottom),
146 dimensions::get_value(at.padding_left),
147 dimensions::get_value(at.padding_right)
148 );
149 }
150
152 const Button &button,
155 ) override {
156 ZoneScopedN("Button Release - Component EV");
157 auto eh = static_cast<EventHandler*>(event_handler_.get());
158 auto [at, ir] = component_data();
159 eh->on_button_release(
160 button,
161 x,
162 y,
167 dimensions::get_value(at.padding_top),
168 dimensions::get_value(at.padding_bottom),
169 dimensions::get_value(at.padding_left),
170 dimensions::get_value(at.padding_right)
171 );
172 }
173
175 ZoneScopedN("Mouse Enter - Component EV");
176 auto eh = static_cast<EventHandler*>(event_handler_.get());
177 auto [at, ir] = component_data();
178 eh->on_mouse_enter(
179 x,
180 y,
185 dimensions::get_value(at.padding_top),
186 dimensions::get_value(at.padding_bottom),
187 dimensions::get_value(at.padding_left),
188 dimensions::get_value(at.padding_right)
189 );
190 }
191
193 ZoneScopedN("Mouse Exit - Component EV");
194 auto eh = static_cast<EventHandler*>(event_handler_.get());
195 auto [at, ir] = component_data();
196 eh->on_mouse_exit(
197 x,
198 y,
203 dimensions::get_value(at.padding_top),
204 dimensions::get_value(at.padding_bottom),
205 dimensions::get_value(at.padding_left),
206 dimensions::get_value(at.padding_right)
207 );
208 }
209
211 ZoneScopedN("Mouse Motion - Component EV");
212 auto eh = static_cast<EventHandler*>(event_handler_.get());
213 auto [at, ir] = component_data();
214 eh->on_mouse_motion(
215 x,
216 y,
221 dimensions::get_value(at.padding_top),
222 dimensions::get_value(at.padding_bottom),
223 dimensions::get_value(at.padding_left),
224 dimensions::get_value(at.padding_right)
225 );
226 }
227
229 ZoneScopedN("Scroll - Component EV");
230 auto eh = static_cast<EventHandler*>(event_handler_.get());
231 auto [at, ir] = component_data();
232 eh->on_scroll(
233 dx,
234 dy,
239 dimensions::get_value(at.padding_top),
240 dimensions::get_value(at.padding_bottom),
241 dimensions::get_value(at.padding_left),
242 dimensions::get_value(at.padding_right)
243 );
244 }
245
246 void dispatch_focus_changed() override {
247 ZoneScopedN("Scroll - Component EV");
248 auto eh = static_cast<EventHandler*>(event_handler_.get());
249 auto [at, ir] = component_data();
250 eh->on_focus_changed(
255 dimensions::get_value(at.padding_top),
256 dimensions::get_value(at.padding_bottom),
257 dimensions::get_value(at.padding_left),
258 dimensions::get_value(at.padding_right)
259 );
260 }
261
262 private:
263 std::pair<component_dimensional_relations_t, internal_relations_t&> component_data() {
264 return {component_->get_dimensional_relations(), component_->get_internal_relations()};
265 }
266
267 template<std::size_t... I>
268 void configure_event_handler_fields(std::index_sequence<I...>) {
269 ZoneScopedN("Configure Fields");
270 (configure_event_handler_field<I>(), ...);
271 }
272
273 template<std::size_t FieldI>
274 void configure_event_handler_field() {
275 using field = refl::field<EventHandler, FieldI>;
276 using field_type = typename field::type;
277 ZoneScopedN(field::name);
278 auto* eh = static_cast<EventHandler*>(event_handler_.get());
279
280 if constexpr (packtl::is_type<use_context, field_type>::value) {
281 using context_type = typename field_type::context_type;
282 using ret_context_type = typename field_type::ret_context_type;
283
284 use_context<ret_context_type> &ctx_ref = field::from_instance(*eh);
285
286 auto ctx = component_->find_context<context_type>();
287
288 if (ctx.has_value()) {
289 use_context_delegate::set_context(&ctx_ref, ctx.value());
291 } else {
292 use_context_delegate::set_context(&ctx_ref, new context_type{});
294 }
295
296 use_context_delegate::set_state(&ctx_ref, component_->state());
298 } else if constexpr (packtl::is_type<provide_context, field_type>::value) {
299 using context_type = typename field_type::context_type;
300
301 provide_context<context_type> &ctx_ref = field::from_instance(*eh);
302 provide_context_delegate::set_state(&ctx_ref, component_->state());
303 }
304 }
305
306 private:
307 component_base_t* component_{};
308 std::shared_ptr<event_handler_t> event_handler_{};
309 };
310}
virtual component_dimensional_relations_t get_dimensional_relations()=0
internal_relations_t & get_internal_relations()
void paint_fragment(vg::fragment_t &fragment) override
void dispatch_button_release(const Button &button, dimension_t::value_type x, dimension_t::value_type y) override
void dispatch_mouse_motion(dimension_t::value_type x, dimension_t::value_type y) override
std::vector< component_holder_t > update(StyleArchive &style_archive, component_builder_t &content_children_builder) override
void dispatch_scroll(dimension_t::value_type dx, dimension_t::value_type dy) override
void dispatch_key_press(const KeyEvent &ev) override
void dispatch_mouse_exit(dimension_t::value_type x, dimension_t::value_type y) override
void dispatch_button_press(const Button &button, dimension_t::value_type x, dimension_t::value_type y) override
void dispatch_text_input(const TextInputEvent &ev) override
void dispatch_key_release(const KeyEvent &ev) override
void dispatch_mouse_enter(dimension_t::value_type x, dimension_t::value_type y) override
std::vector< cydui::components::component_holder_t > children_list
const S & get_value(dimension< S > &dimension)
Definition api.cppm:24
static void set_state(provide_context< ContextType > *it, const components::component_state_ref &state)
static void set_context(use_context< ContextType > *it, ContextType *ctx)
static void set_state(use_context< ContextType > *it, const cydui::components::component_state_ref &state)
static void set_owns_context(use_context< ContextType > *it, bool value)
static void start_listening(use_context< ContextType > *it)