13 std::shared_ptr<Core::Window> window,
16 : m_layer(
std::move(layer))
17 , m_window(
std::move(window))
18 , m_event_manager(event_manager)
19 , m_name(
std::move(name))
35 m_callbacks[id].press[
static_cast<int>(btn)] = std::move(fn);
40 m_callbacks[id].release[
static_cast<int>(btn)] = std::move(fn);
50 m_callbacks[id].drag[
static_cast<int>(btn)] = std::move(fn);
70 const int key_code =
static_cast<int>(key);
71 m_callbacks[id].key_press[key_code] = std::move(fn);
74 const std::string key_name = std::to_string(key_code);
76 std::make_shared<Vruta::Event>(
79 m_name +
"_key_press_" + key_name);
86 const int key_code =
static_cast<int>(key);
87 m_callbacks[id].key_release[key_code] = std::move(fn);
90 const std::string key_name = std::to_string(key_code);
92 std::make_shared<Vruta::Event>(
95 m_name +
"_key_release_" + key_name);
102 const int key_code =
static_cast<int>(key);
103 m_callbacks[id].key_held[key_code] = std::move(fn);
106 const std::string key_name = std::to_string(key_code);
108 std::make_shared<Vruta::Event>(
111 m_name +
"_key_held_" + key_name);
130 if (it !=
m_callbacks.end() && it->second.focus_lost)
140 if (it !=
m_callbacks.end() && it->second.focus_lost)
141 it->second.focus_lost(
id);
150 return m_window->get_event_source();
162 on_held(
id, decrease, [state, delta, clamp_min, clamp_max](uint32_t) {
163 state->write(std::clamp(state->value - delta, clamp_min, clamp_max));
166 on_held(
id, increase, [state, delta, clamp_min, clamp_max](uint32_t) {
167 state->write(std::clamp(state->value + delta, clamp_min, clamp_max));
180 std::make_shared<Vruta::Event>(
182 [
this](
double px,
double py) {
handle_move(px, py); })),
186 std::make_shared<Vruta::Event>(
192 std::make_shared<Vruta::Event>(
195 m_name +
"_release_left");
198 std::make_shared<Vruta::Event>(
204 std::make_shared<Vruta::Event>(
207 m_name +
"_release_right");
210 std::make_shared<Vruta::Event>(
216 std::make_shared<Vruta::Event>(
222 std::make_shared<Vruta::Event>(
230 for (
const char* suffix : {
232 "_press_left",
"_release_left",
233 "_press_right",
"_release_right",
235 "_drag_left",
"_drag_right" }) {
240 const std::string key_name = std::to_string(key_code);
241 if (handlers.has_press)
243 if (handlers.has_release)
245 if (handlers.has_held)
256 const auto& s = m_window->get_state();
258 (
static_cast<float>(px) /
static_cast<float>(s.current_width)) * 2.0F - 1.0F,
259 1.0F - (
static_cast<float>(py) /
static_cast<float>(s.current_height)) * 2.0F
265 const glm::vec2 ndc =
to_ndc(px, py);
266 const auto hit =
m_layer->hit_test(ndc);
277 it->second.enter(*hit);
285 it->second.move(*hit, ndc);
291 const glm::vec2 ndc =
to_ndc(px, py);
292 const auto hit =
m_layer->hit_test(ndc);
294 const int btn_idx =
static_cast<int>(btn);
299 if (it !=
m_callbacks.end() && it->second.focus_lost)
307 if (it !=
m_callbacks.end() && it->second.focus_gained)
308 it->second.focus_gained(*hit);
318 if (it !=
m_callbacks.end() && it->second.press.count(btn_idx))
319 it->second.press[btn_idx](*hit, ndc);
325 const int btn_idx =
static_cast<int>(btn);
328 const glm::vec2 ndc =
to_ndc(px, py);
329 const auto hit =
m_layer->hit_test(ndc);
337 auto btn_it = it->second.release.find(
static_cast<int>(btn));
338 if (btn_it != it->second.release.end() && btn_it->second)
339 btn_it->second(*hit, ndc);
344 const glm::vec2 ndc =
to_ndc(px, py);
345 const int btn_idx =
static_cast<int>(btn);
348 const auto hit =
m_layer->hit_test(ndc);
356 if (it !=
m_callbacks.end() && it->second.drag.count(btn_idx))
357 it->second.drag[btn_idx](*
m_dragging[btn_idx], ndc);
369 const auto [px, py] =
m_window->get_event_source().get_mouse_position();
386 const int key_code =
static_cast<int>(key);
387 auto key_it = it->second.key_press.find(key_code);
388 if (key_it != it->second.key_press.end())
401 const int key_code =
static_cast<int>(key);
402 auto key_it = it->second.key_release.find(key_code);
403 if (key_it != it->second.key_release.end())
416 const int key_code =
static_cast<int>(key);
417 auto key_it = it->second.key_held.find(key_code);
418 if (key_it != it->second.key_held.end())
std::function< void(uint32_t id)> KeyFn
std::unordered_map< int, KeyHandlerState > m_registered_keys
std::optional< uint32_t > m_dragging[3]
void handle_key_release(IO::Keys key)
std::shared_ptr< Layer > m_layer
void on_scroll(uint32_t id, ScrollFn fn)
Called on scroll while the cursor is over an element.
void handle_move(double px, double py)
void on_focus_gained(uint32_t id, EnterFn fn)
Called once when an element gains keyboard focus (via click).
void handle_key_press(IO::Keys key)
void on_enter(uint32_t id, EnterFn fn)
Called once when the cursor enters an element's region.
std::function< void(uint32_t id, glm::vec2 ndc)> MoveFn
Context(std::shared_ptr< Layer > layer, std::shared_ptr< Core::Window > window, Vruta::EventManager &event_manager, std::string name)
Construct and immediately register event coroutines.
void handle_key_held(IO::Keys key)
void unbind(uint32_t id)
Remove all callbacks registered for an element id.
std::function< void(uint32_t id, glm::vec2 ndc, double dx, double dy)> ScrollFn
Vruta::EventManager & m_event_manager
std::shared_ptr< Core::Window > m_window
std::function< void(uint32_t id, glm::vec2 ndc)> PressFn
void handle_release(double px, double py, IO::MouseButtons btn)
const Vruta::WindowEventSource & event_source() const
void handle_drag(double px, double py, IO::MouseButtons btn)
std::function< void(uint32_t id)> LeaveFn
void on_focus_lost(uint32_t id, LeaveFn fn)
Called once when an element loses keyboard focus.
void on_move(uint32_t id, MoveFn fn)
Called each move event while the cursor is over an element.
glm::vec2 to_ndc(double px, double py) const noexcept
std::unordered_map< uint32_t, ElementCallbacks > m_callbacks
void on_release(uint32_t id, IO::MouseButtons btn, PressFn fn)
Called when a mouse button is released over an element.
void on_press(uint32_t id, IO::MouseButtons btn, PressFn fn)
Called when a mouse button is pressed over an element.
void on_drag(uint32_t id, IO::MouseButtons btn, MoveFn fn)
Called on each mouse-move event while btn is held, tracking the element where the drag began even whe...
std::optional< uint32_t > m_hovered
void on_leave(uint32_t id, LeaveFn fn)
Called once when the cursor leaves an element's region.
std::function< void(uint32_t id)> EnterFn
void handle_press(double px, double py, IO::MouseButtons btn)
void handle_scroll(double dx, double dy)
Context & key_step(uint32_t id, std::shared_ptr< MappedState< float > > state, IO::Keys decrease, IO::Keys increase, float delta, float clamp_min=0.0F, float clamp_max=1.0F)
Attach key-delta handlers to a Mapped<float> element.
void on_held(uint32_t id, IO::Keys key, KeyFn fn)
Called repeatedly while a key is held and the element has focus.
void clear_focus()
Clear keyboard focus (no element focused).
~Context()
Cancel all registered event coroutines.
std::optional< uint32_t > m_focused
Event wiring between a Layer and a window surface.
void add_event(const std::shared_ptr< Event > &event, const std::string &name="")
Add a event to the manager.
bool cancel_event(const std::shared_ptr< Event > &event)
Cancels and removes a event from the manager.
Awaitable stream of GLFW window input events.
MouseButtons
Enumeration for mouse buttons.
Vruta::Event key_released(std::shared_ptr< Core::Window > window, IO::Keys key, std::function< void()> callback)
Creates an Event coroutine that triggers on specific key release.
Vruta::Event key_pressed(std::shared_ptr< Core::Window > window, IO::Keys key, std::function< void()> callback)
Creates an Event coroutine that triggers on specific key press.
Vruta::Event mouse_moved(std::shared_ptr< Core::Window > window, std::function< void(double, double)> callback)
Creates an Event coroutine that triggers on mouse movement.
Vruta::Event mouse_scrolled(std::shared_ptr< Core::Window > window, std::function< void(double, double)> callback)
Creates an Event coroutine that triggers on mouse scroll.
Vruta::Event key_held(std::shared_ptr< Core::Window > window, IO::Keys key, std::function< void()> callback)
Creates an Event coroutine that triggers on key press and repeats while held.
Vruta::Event mouse_released(std::shared_ptr< Core::Window > window, IO::MouseButtons button, std::function< void(double, double)> callback)
Creates an Event coroutine that triggers on specific mouse button release.
Vruta::Event mouse_pressed(std::shared_ptr< Core::Window > window, IO::MouseButtons button, std::function< void(double, double)> callback)
Creates an Event coroutine that triggers on specific mouse button press.
Vruta::Event mouse_dragged(std::shared_ptr< Core::Window > window, IO::MouseButtons button, std::function< void(double, double)> callback)
Creates an Event coroutine that triggers on mouse drag with specific button.