Doxygen Samurai Engine 0.0.1
Doxygen Samurai Engine Documentation
Loading...
Searching...
No Matches
shortcutApi.cpp
Go to the documentation of this file.
1#include "shortcutApi.h"
3#include <iostream>
4#include <set>
5#include <imgui.h>
6
7struct Mapping
8{
9 short normal = 0;
10 short imgui = 0;
11};
12
13//todo remove global things that allocate memory
14std::unordered_map<std::string, Mapping> buttonMapping;
15
17{
18#if !SAMURAI_SDL
20 {
21 {"a", {Button::A, ImGuiKey_A}},
22 { "b", {Button::B, ImGuiKey_B} },
23 { "c", {Button::C, ImGuiKey_C} },
24 { "d", {Button::D, ImGuiKey_D} },
25 { "e", {Button::E, ImGuiKey_E} },
26 { "f", {Button::F, ImGuiKey_F} },
27 { "g", {Button::G, ImGuiKey_G} },
28 { "h", {Button::H, ImGuiKey_H} },
29 { "i", {Button::I, ImGuiKey_I} },
30 { "j", {Button::J, ImGuiKey_J} },
31 { "k", {Button::K, ImGuiKey_K} },
32 { "l", {Button::L, ImGuiKey_L} },
33 { "m", {Button::M, ImGuiKey_M} },
34 { "n", {Button::N, ImGuiKey_N} },
35 { "o", {Button::O, ImGuiKey_O} },
36 { "p", {Button::P, ImGuiKey_P} },
37 { "q", {Button::Q, ImGuiKey_Q} },
38 { "r", {Button::R, ImGuiKey_R} },
39 { "s", {Button::S, ImGuiKey_S} },
40 { "t", {Button::T, ImGuiKey_T} },
41 { "u", {Button::U, ImGuiKey_U} },
42 { "v", {Button::V, ImGuiKey_V} },
43 { "w", {Button::W, ImGuiKey_W} },
44 { "x", {Button::X, ImGuiKey_X} },
45 { "y", {Button::Y, ImGuiKey_Y} },
46 { "z", {Button::Z, ImGuiKey_Z} },
47 { "0", {Button::NR0, ImGuiKey_0}}, { "1", {Button::NR1, ImGuiKey_1} }, { "2", {Button::NR2, ImGuiKey_2} }, { "3", {Button::NR3, ImGuiKey_3} },
48 { "4", {Button::NR4, ImGuiKey_0}}, { "5", {Button::NR5, ImGuiKey_5} }, { "6", {Button::NR6, ImGuiKey_6} }, { "7", {Button::NR7, ImGuiKey_7} },
49 { "8", {Button::NR8, ImGuiKey_8}}, { "9", {Button::NR9, ImGuiKey_9} },
50 { "space", {Button::Space , ImGuiKey_Space}},
51 { "enter", {Button::Enter, ImGuiKey_Enter} },
52 { "escape", {Button::Escape, ImGuiKey_Escape} },
53 { "esc", {Button::Escape, ImGuiKey_Escape} },
54 { "up", {Button::Up, ImGuiKey_UpArrow} },
55 { "down", {Button::Down , ImGuiKey_DownArrow}},
56 { "left", {Button::Left , ImGuiKey_LeftArrow}},
57 { "right", {Button::Right , ImGuiKey_RightArrow}},
58 { "ctrl", {Button::LeftCtrl , ImGuiKey_LeftCtrl}},
59 { "tab", {Button::Tab , ImGuiKey_Tab}},
60 { "alt", {Button::LeftAlt , ImGuiKey_LeftAlt}},
61
62 };
63#else
65
66 };
67#endif
68}
69
70
71
72namespace samurai
73{
74
75std::vector<std::string> tokenizeShortcutSimple(const char *shortcut)
76{
77 char data[256] = {};
78 samurai::removeCharacters(data, shortcut, "\n \t\r\v", sizeof(data));
79 samurai::toLower(data, data, sizeof(data));
80
81 auto token = samurai::split(data, '+');
82
83 return token;
84};
85
86
87std::vector<std::string> tokenizeShortcutNormalized(const char *shortcut)
88{
89
90 auto token = tokenizeShortcutSimple(shortcut);
91
92 std::set<std::string> tokenSet;
93
94 for (auto &i : token)
95 {
96
97 auto it = buttonMapping.find(i);
98
99 if (it != buttonMapping.end())
100 {
101 tokenSet.insert(it->first);
102 }
103 }
104
105 std::vector<std::string> ret;
106 ret.reserve(tokenSet.size());
107
108 for (auto &i : tokenSet)
109 {
110 ret.push_back(std::move(i));
111 }
112
113 return ret;
114
115}
116
117std::string normalizeShortcutName(const char *shortcut)
118{
120
121 std::string ret = "";
122 for (int i = 0; i < t.size(); i++)
123 {
124 t[i][0] = std::toupper(t[i][0]);
125
126 ret += t[i];
127
128 if (i < t.size()-1)
129 {
130 ret += "+";
131 }
132 }
133
134 return ret;
135}
136
137
138
139//todo shortcut should rely on glfw backend when imgui is disabeled in production build
140bool shortcut(const samurai::Input &input, const char *shortcut)
141{
142 auto token = tokenizeShortcutSimple(shortcut);
143
144 if (token.empty()) { return 0; }
145
146
147 bool pressed = false;
148
149 if (0)
150 { //noraml implementation
151 for (auto &t : token)
152 {
153 auto it = buttonMapping.find(t);
154 if (it != buttonMapping.end())
155 {
156 if (input.buttons[it->second.normal].pressed())
157 {
158 pressed = true;
159 }
160 else if (!input.buttons[it->second.normal].held())
161 {
162 return false;
163 }
164 }
165 }
166 }
167 else
168 { //imgui backend
169 for (auto &t : token)
170 {
171 auto it = buttonMapping.find(t);
172 if (it != buttonMapping.end())
173 {
174 if (ImGui::IsKeyPressed(static_cast<ImGuiKey>(it->second.imgui), false))
175 {
176 pressed = true;
177 }
178 else if (!ImGui::IsKeyDown(static_cast<ImGuiKey>(it->second.imgui)))
179 {
180 return false;
181 }
182 }
183 }
184 }
185
186
187
188 return pressed;
189}
190
191bool MenuItem(const samurai::Input &input, const char *label, const char *shortcut, bool *p_selected, bool enabled)
192{
193 if (samurai::shortcut(input, shortcut))
194 {
195 *p_selected = !*p_selected;
196 }
197
198 return ImGui::MenuItem(label, shortcut, p_selected, enabled);
199}
200
201
202
204{
205 for (auto &i : registeredShortcuts)
206 {
207 if (shortcut(input, i.second.shortcut.c_str()))
208 {
209 *i.second.toggle = !*i.second.toggle;
210 }
211 }
212
213}
214
215bool ShortcutManager::registerShortcut(const char *name, const char *s, bool *toggle, bool editable)
216{
217
218 if (registeredShortcuts.find(name) != registeredShortcuts.end())
219 {
220 //todo log error
221 return 0;
222 }
223 else
224 {
226 = Shortcut{std::move(normalizeShortcutName(s)), toggle, editable};
227 return 1;
228 }
229
230}
231
232const char *ShortcutManager::getShortcut(const char *name)
233{
234 auto it = registeredShortcuts.find(name);
235
236 if (it == registeredShortcuts.end()) { return ""; }
237 else
238 { return it->second.shortcut.c_str(); };
239
240}
241
242}
void toLower(char *dest, const char *source, size_t size)
bool MenuItem(const samurai::Input &input, const char *label, const char *shortcut, bool *p_selected, bool enabled)
std::vector< std::string > tokenizeShortcutSimple(const char *shortcut)
std::vector< std::string > tokenizeShortcutNormalized(const char *shortcut)
void removeCharacters(char *dest, const char *source, const char *charsToRemove, size_t destSize)
bool shortcut(const samurai::Input &input, const char *shortcut)
std::string normalizeShortcutName(const char *shortcut)
void initShortcutApi()
std::vector< std::string > split(const char *source, char c)
std::unordered_map< std::string, Mapping > buttonMapping
short imgui
short normal
Button buttons[Button::BUTTONS_COUNT]
Definition input.h:69
void update(const samurai::Input &input)
bool registerShortcut(const char *name, const char *s, bool *toggle, bool editable=1)
const char * getShortcut(const char *name)
std::unordered_map< std::string, Shortcut > registeredShortcuts
Definition shortcutApi.h:22