7#include <tracy/Tracy.hpp>
8#define SDL_MAIN_HANDLED
16import fabric.profiling;
22export namespace cydui {
23#define INSTANCE_EV_HANDLER(STATE_PTR) \
24 if (STATE_PTR->component_instance.has_value()) \
25 STATE_PTR->component_instance.value()->get_event_dispatcher()
28 std::vector<fabric::async::raw_listener::sptr> Layout::make_event_listeners() {
29 ZoneScopedN(
"Layout:make_event_listeners");
30 std::vector<fabric::async::raw_listener::sptr> listeners{};
32 static auto make_listener = [&](
auto&& fun) {
return win->on_event(fun).raw(); };
35 make_listener([&](
const RequestComponentFocus& ev) -> fabric::task<> {
36 const auto& target = ev.component;
37 if (
nullptr == target) {
40 if (focused != target->state()) {
42 focused->focused =
false;
44 if (focused->is_text_input()) {
45 SDL_StopTextInput(win->native()->window);
47 if (focused->component_instance.has_value()) {
48 component_stylist->apply_style(focused->component_instance.value());
50 focused->mark_dirty();
53 focused = target->state();
54 focused->focused =
true;
56 if (focused->is_text_input()) {
57 SDL_StartTextInput(win->native()->window);
59 if (focused->component_instance.has_value()) {
60 component_stylist->apply_style(focused->component_instance.value());
62 focused->mark_dirty();
68 make_listener([&](
const WindowClosed& ev) -> fabric::task<> {
72 make_listener([&](
const RedrawEvent& ev) -> fabric::task<> {
73 ZoneScopedN(
"Redraw Event");
74 auto _pev = this->win->profiling_ctx.scope_event(
"Redraw");
76 components::component_state_t* target_state =
77 ((components::component_state_t*)ev.component);
78 if (target_state->component_instance.has_value()) {
86 component_renderer->render(*win->native(), root);
89 make_listener([&](
const KeyEvent& ev) -> fabric::task<> {
90 ZoneScopedN(
"Key Event");
91 auto _pev = this->win->profiling_ctx.scope_event(
"Key");
92 if (ev.keysym.code == SDLK_F12 && ev.pressed && not ev.holding) {
93 LOG::print{INFO}(
"Pressed Debug Key");
96 if (focused && focused->component_instance) {
97 if (focused->focused) {
100 }
else if (ev.released) {
110 make_listener([&](
const TextInputEvent& ev) -> fabric::task<> {
111 ZoneScopedN(
"Key Event");
112 auto _pev = this->win->profiling_ctx.scope_event(
"Key");
113 if (focused && focused->component_instance) {
114 if (focused->focused) {
123 make_listener([&](
const ButtonEvent& ev) -> fabric::task<> {
124 ZoneScopedN(
"Button Event");
125 auto _pev = this->win->profiling_ctx.scope_event(
"Button");
127 components::component_base_t* target = root.get();
128 components::component_base_t* specified_target =
find_by_coords(ev.x, ev.y);
129 if (specified_target) {
130 target = specified_target;
133 auto dim = target->get_dimensional_relations();
134 auto& int_rel = target->get_internal_relations();
138 if (focused != target->state()) {
140 focused->focused =
false;
142 if (focused->is_text_input()) {
143 SDL_StopTextInput(win->native()->window);
145 if (focused->component_instance.has_value()) {
146 component_stylist->apply_style(focused->component_instance.value());
148 focused->mark_dirty();
151 focused = target->state();
152 focused->focused =
true;
154 if (focused->is_text_input()) {
155 SDL_StartTextInput(win->native()->window);
157 if (focused->component_instance.has_value()) {
158 component_stylist->apply_style(focused->component_instance.value());
160 focused->mark_dirty();
165 target->get_event_dispatcher()->dispatch_button_press((
Button)ev.button, rel_x, rel_y);
167 target->get_event_dispatcher()->dispatch_button_release((
Button)ev.button, rel_x, rel_y);
172 make_listener([&](
const ScrollEvent& ev) -> fabric::task<> {
173 ZoneScopedN(
"Scroll Event");
174 auto _pev = this->win->profiling_ctx.scope_event(
"Scroll");
175 components::component_base_t* target = root.get();
176 components::component_base_t* specified_target =
find_by_coords(ev.x, ev.y);
177 if (specified_target) {
178 target = specified_target;
181 target->get_event_dispatcher()->dispatch_scroll(ev.dx, ev.dy);
186 make_listener([&](
const MotionEvent& ev) -> fabric::task<> {
187 auto _pev = this->win->profiling_ctx.scope_event(
"Motion");
188 ZoneScopedN(
"MotionEvent");
193 components::component_base_t* target = root.get();
194 components::component_base_t* specified_target =
find_by_coords(ev.x, ev.y);
195 if (specified_target)
196 target = specified_target;
199 auto& int_rel = target->get_internal_relations();
202 target->get_event_dispatcher()->dispatch_mouse_motion(rel_x, rel_y);
246 make_listener([&](
const ResizeEvent& ev) -> fabric::task<> {
247 ZoneScopedN(
"Resize Event");
248 auto _pev = this->win->profiling_ctx.scope_event(
"Resize");
250 auto dim = root->get_dimensional_relations();
251 static const auto* width_field =
252 refl::type_info::from<components::style_base_t>()
253 .field_by_offset(offsetof(components::style_base_t, width))
255 static const auto* height_field =
256 refl::type_info::from<components::style_base_t>()
257 .field_by_offset(offsetof(components::style_base_t, height))
259 root->get_style_data().set_base_field_override(width_field,
dimension_t{ev.w});
260 root->get_style_data().set_base_field_override(height_field,
dimension_t{ev.h});
bool render_if_dirty(const components::component_base_t::sptr &c)
bool set_hovering_flag(components::component_state_t *state, const MotionEvent &ev, bool clear_children=true)
void update_component(const components::component_base_t::sptr &target)
void clear_hovering_flag(const components::component_state_ref &state, const MotionEvent &ev)
components::component_base_t * find_by_coords(dimensions::screen_measure x, dimensions::screen_measure y)
#define INSTANCE_EV_HANDLER(STATE_PTR)
const S & get_value(dimension< S > &dimension)
quantify::quantity_t< screen::pixel, double > screen_measure
dimensions::dimension< dimensions::screen_measure > dimension_t