lxgui
Loading...
Searching...
No Matches
input_dispatcher.cpp
1#include "lxgui/input_dispatcher.hpp"
2
3#include "lxgui/gui_event_emitter.hpp"
4#include "lxgui/gui_event_receiver.hpp"
5#include "lxgui/gui_out.hpp"
6#include "lxgui/input_source.hpp"
7#include "lxgui/utils_exception.hpp"
8#include "lxgui/utils_std.hpp"
9#include "lxgui/utils_string.hpp"
10
11#include <iostream>
12
13namespace lxgui::input {
14
15dispatcher::dispatcher(source& src) : source_(src) {
16 connections_.push_back(src.on_key_pressed.connect([&](key key_id) {
17 // Record press time
18 key_pressed_time_[static_cast<std::size_t>(key_id)] = timer::now();
19 // Forward
20 on_key_pressed(key_pressed_data{key_id});
21 }));
22
23 connections_.push_back(src.on_key_pressed_repeat.connect([&](key key_id) {
24 // Forward
25 on_key_pressed_repeat(key_pressed_repeat_data{key_id});
26 }));
27
28 connections_.push_back(src.on_key_released.connect([&](key key_id) {
29 // Forward
30 on_key_released(key_released_data{key_id});
31 }));
32
33 connections_.push_back(src.on_text_entered.connect([&](std::uint32_t c) {
34 // Forward
35 on_text_entered(text_entered_data{c});
36 }));
37
38 connections_.push_back(
39 src.on_mouse_pressed.connect([&](mouse_button button_id, gui::vector2f mouse_pos) {
40 // Apply scaling factor to mouse coordinates
41 mouse_pos /= scaling_factor_;
42
43 // Record press time
44 auto time_last = mouse_pressed_time_[static_cast<std::size_t>(button_id)];
45 auto time_now = timer::now();
46 mouse_pressed_time_[static_cast<std::size_t>(button_id)] = time_now;
47 double click_time = std::chrono::duration<double>(time_now - time_last).count();
48
49 // Forward
50 on_mouse_pressed(mouse_pressed_data{button_id, mouse_pos});
51
52 if (click_time < double_click_time_)
53 on_mouse_double_clicked(mouse_double_clicked_data{button_id, mouse_pos});
54 }));
55
56 connections_.push_back(
57 src.on_mouse_released.connect([&](mouse_button button_id, gui::vector2f mouse_pos) {
58 // Apply scaling factor to mouse coordinates
59 mouse_pos /= scaling_factor_;
60
61 // Forward
62 bool was_dragged = is_mouse_dragged_ && button_id == mouse_drag_button_;
63 on_mouse_released(mouse_released_data{button_id, mouse_pos, was_dragged});
64
65 if (was_dragged) {
66 is_mouse_dragged_ = false;
67 on_mouse_drag_stop(mouse_drag_stop_data{button_id, mouse_pos});
68 }
69 }));
70
71 connections_.push_back(src.on_mouse_wheel.connect([&](float wheel, gui::vector2f mouse_pos) {
72 // Apply scaling factor to mouse coordinates
73 mouse_pos /= scaling_factor_;
74 // Forward
75 on_mouse_wheel(mouse_wheel_data{wheel, mouse_pos});
76 }));
77
78 connections_.push_back(
79 src.on_mouse_moved.connect([&](gui::vector2f movement, gui::vector2f mouse_pos) {
80 // Apply scaling factor to mouse coordinates
81 movement /= scaling_factor_;
82 mouse_pos /= scaling_factor_;
83
84 // Forward
85 on_mouse_moved(mouse_moved_data{movement, mouse_pos});
86
87 if (!is_mouse_dragged_) {
88 std::size_t mouse_button_pressed = std::numeric_limits<std::size_t>::max();
89 for (std::size_t i = 0; i < mouse_button_number; ++i) {
90 if (mouse_is_down(static_cast<mouse_button>(i))) {
91 mouse_button_pressed = i;
92 break;
93 }
94 }
95
96 if (mouse_button_pressed != std::numeric_limits<std::size_t>::max()) {
97 is_mouse_dragged_ = true;
98 mouse_drag_button_ = static_cast<mouse_button>(mouse_button_pressed);
99 on_mouse_drag_start(mouse_drag_start_data{mouse_drag_button_, mouse_pos});
100 }
101 }
102 }));
103}
104
105bool dispatcher::any_key_is_down() const {
106 const auto& is_key_down = source_.get_key_state().is_key_down;
107 for (std::size_t i = 1; i < key_number; ++i) {
108 if (is_key_down[i])
109 return true;
110 }
111
112 return false;
113}
114
115bool dispatcher::key_is_down(key key_id) const {
116 return source_.get_key_state().is_key_down[static_cast<std::size_t>(key_id)];
117}
118
119double dispatcher::get_key_down_duration(key key_id) const {
120 if (!key_is_down(key_id))
121 return 0.0;
122
123 return std::chrono::duration<double>(
124 timer::now() - key_pressed_time_[static_cast<std::size_t>(key_id)])
125 .count();
126}
127
128bool dispatcher::mouse_is_down(mouse_button button_id) const {
129 return source_.get_mouse_state().is_button_down[static_cast<std::size_t>(button_id)];
130}
131
132double dispatcher::get_mouse_down_duration(mouse_button button_id) const {
133 if (!mouse_is_down(button_id))
134 return 0.0;
135
136 return std::chrono::duration<double>(
137 timer::now() - mouse_pressed_time_[static_cast<std::size_t>(button_id)])
138 .count();
139}
140
141void dispatcher::set_doubleclick_time(double double_click_time) {
142 double_click_time_ = double_click_time;
143}
144
145double dispatcher::get_doubleclick_time() const {
146 return double_click_time_;
147}
148
149bool dispatcher::alt_is_pressed() const {
150 return key_is_down(key::k_lmenu) || key_is_down(key::k_rmenu);
151}
152
153bool dispatcher::shift_is_pressed() const {
154 return key_is_down(key::k_lshift) || key_is_down(key::k_rshift);
155}
156
157bool dispatcher::ctrl_is_pressed() const {
158 return key_is_down(key::k_lcontrol) || key_is_down(key::k_rcontrol);
159}
160
161gui::vector2f dispatcher::get_mouse_position() const {
162 return source_.get_mouse_state().position / scaling_factor_;
163}
164
165float dispatcher::get_mouse_wheel() const {
166 return source_.get_mouse_state().wheel;
167}
168
169const source& dispatcher::get_source() const {
170 return source_;
171}
172
173source& dispatcher::get_source() {
174 return source_;
175}
176
177void dispatcher::set_interface_scaling_factor(float scaling_factor) {
178 scaling_factor_ = scaling_factor;
179}
180
181float dispatcher::get_interface_scaling_factor() const {
182 return scaling_factor_;
183}
184
185} // namespace lxgui::input
dispatcher(source &src)
Initializes this dispatcher with a chosen input source.
The base class for input source implementation.
utils::signal< void(input::key)> on_key_pressed
Signal triggered when a keyboard key is pressed.
connection connect(function_type function)
Connect a new slot to this signal.
vector2< float > vector2f
Holds 2D coordinates (as floats)
constexpr std::size_t key_number
constexpr std::size_t mouse_button_number
Data for on_key_pressed_repeat signal.