lxgui
Loading...
Searching...
No Matches
gui_key_binder.cpp
1#include "lxgui/gui_key_binder.hpp"
2
3#include "lxgui/gui_event_emitter.hpp"
4#include "lxgui/gui_out.hpp"
5#include "lxgui/input_dispatcher.hpp"
6#include "lxgui/utils_std.hpp"
7#include "lxgui/utils_string.hpp"
8
9#include <lxgui/extern_sol2_state.hpp>
10
11namespace lxgui::gui {
12
13utils::connection
14key_binder::register_key_binding(std::string_view name, sol::protected_function lua_function) {
15 auto function = [lua_function = std::move(lua_function)]() {
16 // Call function
17 auto result = lua_function();
18
19 // Handle errors
20 if (!result.valid()) {
21 throw gui::exception(result.get<sol::error>().what());
22 }
23 };
24
25 return register_key_binding(name, std::move(function));
26}
27
29 auto iter =
30 utils::find_if(key_bindings_, [&](const auto& binding) { return binding.name == name; });
31
32 if (iter == key_bindings_.end()) {
33 gui::out << gui::error << "key_binder: a binding already exists with name '" << name << "'."
34 << std::endl;
35 return {};
36 }
37
38 key_binding binding;
39 binding.name = std::string(name);
40 auto connection = binding.signal.connect(std::move(function));
41 key_bindings_.push_back(std::move(binding));
42
43 return connection;
44}
45
47 std::string_view name,
48 input::key key_id,
49 bool shift_is_pressed,
50 bool ctrl_is_pressed,
51 bool alt_is_pressed) {
52 auto iter =
53 utils::find_if(key_bindings_, [&](const auto& binding) { return binding.name == name; });
54
55 if (iter == key_bindings_.end()) {
56 gui::out << gui::error << "key_binder: no binding with name '" << name << "'." << std::endl;
57 return;
58 }
59
60 iter->key_id = key_id;
61 iter->shift_is_pressed =
62 shift_is_pressed || key_id == input::key::k_lshift || key_id == input::key::k_rshift;
63 iter->ctrl_is_pressed =
64 ctrl_is_pressed || key_id == input::key::k_lcontrol || key_id == input::key::k_rcontrol;
65 iter->alt_is_pressed =
66 alt_is_pressed || key_id == input::key::k_lmenu || key_id == input::key::k_rmenu;
67}
68
69void key_binder::set_key_binding(std::string_view name, std::string_view key_name) {
70 bool shift_is_pressed = false;
71 bool ctrl_is_pressed = false;
72 bool alt_is_pressed = false;
73
74 const auto tokens = utils::cut(key_name, "-");
75 for (auto token : tokens) {
76 if (token == "Shift")
77 shift_is_pressed = true;
78 else if (token == "Ctrl")
79 ctrl_is_pressed = true;
80 else if (token == "Alt")
81 alt_is_pressed = true;
82 }
83
85 name, input::get_key_from_codename(tokens.back()), shift_is_pressed, ctrl_is_pressed,
86 alt_is_pressed);
87}
88
89void key_binder::remove_key_binding(std::string_view name) {
90 auto iter =
91 utils::find_if(key_bindings_, [&](const auto& binding) { return binding.name == name; });
92
93 if (iter == key_bindings_.end()) {
94 gui::out << gui::error << "key_binder: no binding with name '" << name << "'." << std::endl;
95 return;
96 }
97
98 key_bindings_.erase(iter);
99}
100
101key_binder::key_binding* key_binder::find_binding_(
102 input::key key_id, bool shift_is_pressed, bool ctrl_is_pressed, bool alt_is_pressed) {
103 auto iter = utils::find_if(key_bindings_, [&](const auto& binding) {
104 return binding.key_id == key_id && binding.shift_is_pressed == shift_is_pressed &&
105 binding.ctrl_is_pressed == ctrl_is_pressed &&
106 binding.alt_is_pressed == alt_is_pressed;
107 });
108
109 if (iter == key_bindings_.end())
110 return nullptr;
111
112 return &*iter;
113}
114
116 input::key key_id, bool shift_is_pressed, bool ctrl_is_pressed, bool alt_is_pressed) {
117 auto* binding = find_binding_(key_id, shift_is_pressed, ctrl_is_pressed, alt_is_pressed);
118 if (!binding)
119 return false;
120
121 try {
122 binding->signal();
123 } catch (const std::exception& e) {
124 throw std::runtime_error("Bound action: " + binding->name + ": " + std::string(e.what()));
125 }
126
127 return true;
128}
129
130} // namespace lxgui::gui
Exception to be thrown by GUI code.
void set_key_binding(std::string_view name, std::string_view key_name)
Binds an action to a key.
signal_type::function_type function_type
Type of a keybinding callback.
utils::connection register_key_binding(std::string_view name, sol::protected_function lua_function)
Registers an action as a possible key binding.
void remove_key_binding(std::string_view name)
Unbinds an action.
bool on_key_down(input::key key_id, bool shift_is_pressed, bool ctrl_is_pressed, bool alt_is_pressed)
Called when a key is pressed.
Object representing the connection between a slot and a signal.
std::ostream out
const std::string error
Definition gui_out.cpp:7
@ k_lcontrol
Enter on main keyboard.
@ k_rshift
/ on main keyboard
@ k_rcontrol
Enter on numeric keypad.
key get_key_from_codename(std::string_view key_name)
Returns the key code from the standard English name of a key.
auto find_if(C &v, T &&f)
Definition utils_std.hpp:19