yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
shortcut_manager.cc
Go to the documentation of this file.
1#include "shortcut_manager.h"
2
3#include <algorithm>
4#include <cstddef>
5#include <functional>
6#include <string>
7#include <utility>
8#include <vector>
9
10#include "app/gui/core/input.h"
11#include "imgui/imgui.h"
12
13namespace yaze {
14namespace editor {
15
16namespace {
17constexpr std::pair<ImGuiKey, const char*> kKeyNames[] = {
18 {ImGuiKey_Tab, "Tab"},
19 {ImGuiKey_LeftArrow, "Left"},
20 {ImGuiKey_RightArrow, "Right"},
21 {ImGuiKey_UpArrow, "Up"},
22 {ImGuiKey_DownArrow, "Down"},
23 {ImGuiKey_PageUp, "PageUp"},
24 {ImGuiKey_PageDown, "PageDown"},
25 {ImGuiKey_Home, "Home"},
26 {ImGuiKey_End, "End"},
27 {ImGuiKey_Insert, "Insert"},
28 {ImGuiKey_Delete, "Delete"},
29 {ImGuiKey_Backspace, "Backspace"},
30 {ImGuiKey_Space, "Space"},
31 {ImGuiKey_Enter, "Enter"},
32 {ImGuiKey_Escape, "Escape"},
33 {ImGuiMod_Ctrl, "Ctrl"},
34 {ImGuiMod_Shift, "Shift"},
35 {ImGuiMod_Alt, "Alt"},
36 {ImGuiMod_Super, "Super"},
37 {ImGuiKey_A, "A"},
38 {ImGuiKey_B, "B"},
39 {ImGuiKey_C, "C"},
40 {ImGuiKey_D, "D"},
41 {ImGuiKey_E, "E"},
42 {ImGuiKey_F, "F"},
43 {ImGuiKey_G, "G"},
44 {ImGuiKey_H, "H"},
45 {ImGuiKey_I, "I"},
46 {ImGuiKey_J, "J"},
47 {ImGuiKey_K, "K"},
48 {ImGuiKey_L, "L"},
49 {ImGuiKey_M, "M"},
50 {ImGuiKey_N, "N"},
51 {ImGuiKey_O, "O"},
52 {ImGuiKey_P, "P"},
53 {ImGuiKey_Q, "Q"},
54 {ImGuiKey_R, "R"},
55 {ImGuiKey_S, "S"},
56 {ImGuiKey_T, "T"},
57 {ImGuiKey_U, "U"},
58 {ImGuiKey_V, "V"},
59 {ImGuiKey_W, "W"},
60 {ImGuiKey_X, "X"},
61 {ImGuiKey_Y, "Y"},
62 {ImGuiKey_Z, "Z"},
63 {ImGuiKey_F1, "F1"},
64 {ImGuiKey_F2, "F2"},
65 {ImGuiKey_F3, "F3"},
66 {ImGuiKey_F4, "F4"},
67 {ImGuiKey_F5, "F5"},
68 {ImGuiKey_F6, "F6"},
69 {ImGuiKey_F7, "F7"},
70 {ImGuiKey_F8, "F8"},
71 {ImGuiKey_F9, "F9"},
72 {ImGuiKey_F10, "F10"},
73 {ImGuiKey_F11, "F11"},
74 {ImGuiKey_F12, "F12"},
75 {ImGuiKey_F13, "F13"},
76 {ImGuiKey_F14, "F14"},
77 {ImGuiKey_F15, "F15"},
78};
79
80constexpr const char* GetKeyName(ImGuiKey key) {
81 for (const auto& pair : kKeyNames) {
82 if (pair.first == key) {
83 return pair.second;
84 }
85 }
86 return "";
87}
88} // namespace
89
90std::string PrintShortcut(const std::vector<ImGuiKey>& keys) {
91 std::string shortcut;
92 for (size_t i = keys.size(); i > 0; --i) {
93 shortcut += GetKeyName(keys[i - 1]);
94 if (i > 1) {
95 shortcut += "+";
96 }
97 }
98 return shortcut;
99}
100
101const static std::string kCtrlKey = "Ctrl";
102const static std::string kAltKey = "Alt";
103const static std::string kShiftKey = "Shift";
104const static std::string kSuperKey = "Super";
105
106std::vector<ImGuiKey> ParseShortcut(const std::string& shortcut) {
107 std::vector<ImGuiKey> shortcuts;
108 // Search for special keys and the + symbol to combine with the
109 // MapKeyToImGuiKey function
110 size_t start = 0;
111 size_t end = shortcut.find(kCtrlKey);
112 if (end != std::string::npos) {
113 shortcuts.push_back(ImGuiMod_Ctrl);
114 start = end + kCtrlKey.size();
115 }
116
117 end = shortcut.find(kAltKey, start);
118 if (end != std::string::npos) {
119 shortcuts.push_back(ImGuiMod_Alt);
120 start = end + kAltKey.size();
121 }
122
123 end = shortcut.find(kShiftKey, start);
124 if (end != std::string::npos) {
125 shortcuts.push_back(ImGuiMod_Shift);
126 start = end + kShiftKey.size();
127 }
128
129 end = shortcut.find(kSuperKey, start);
130 if (end != std::string::npos) {
131 shortcuts.push_back(ImGuiMod_Super);
132 start = end + kSuperKey.size();
133 }
134
135 // Parse the rest of the keys
136 while (start < shortcut.size()) {
137 shortcuts.push_back(gui::MapKeyToImGuiKey(shortcut[start]));
138 start++;
139 }
140
141 return shortcuts;
142}
143
144void ExecuteShortcuts(const ShortcutManager& shortcut_manager) {
145 // Check for keyboard shortcuts using the shortcut manager
146 for (const auto& shortcut : shortcut_manager.GetShortcuts()) {
147 bool modifiers_held = true;
148 bool key_pressed = false;
149 ImGuiKey main_key = ImGuiKey_None;
150
151 // Separate modifiers from main key
152 for (const auto& key : shortcut.second.keys) {
153 if (key == ImGuiMod_Ctrl || key == ImGuiMod_Alt ||
154 key == ImGuiMod_Shift || key == ImGuiMod_Super) {
155 // Check if modifier is held
156 if (key == ImGuiMod_Ctrl) {
157 modifiers_held &= ImGui::GetIO().KeyCtrl;
158 } else if (key == ImGuiMod_Alt) {
159 modifiers_held &= ImGui::GetIO().KeyAlt;
160 } else if (key == ImGuiMod_Shift) {
161 modifiers_held &= ImGui::GetIO().KeyShift;
162 } else if (key == ImGuiMod_Super) {
163 modifiers_held &= ImGui::GetIO().KeySuper;
164 }
165 } else {
166 // This is the main key - use IsKeyPressed for single trigger
167 main_key = key;
168 }
169 }
170
171 // Check if main key was pressed (not just held)
172 if (main_key != ImGuiKey_None) {
173 key_pressed = ImGui::IsKeyPressed(main_key, false); // false = no repeat
174 }
175
176 // Execute if modifiers held and key pressed
177 if (modifiers_held && key_pressed && shortcut.second.callback) {
178 shortcut.second.callback();
179 }
180 }
181}
182
183} // namespace editor
184} // namespace yaze
185
186// Implementation in header file (inline methods)
187namespace yaze {
188namespace editor {
189
191 std::function<void()> save_callback,
192 std::function<void()> open_callback,
193 std::function<void()> close_callback,
194 std::function<void()> find_callback,
195 std::function<void()> settings_callback) {
196
197 // Ctrl+S - Save
198 if (save_callback) {
199 RegisterShortcut("save", {ImGuiMod_Ctrl, ImGuiKey_S}, save_callback);
200 }
201
202 // Ctrl+O - Open
203 if (open_callback) {
204 RegisterShortcut("open", {ImGuiMod_Ctrl, ImGuiKey_O}, open_callback);
205 }
206
207 // Ctrl+W - Close
208 if (close_callback) {
209 RegisterShortcut("close", {ImGuiMod_Ctrl, ImGuiKey_W}, close_callback);
210 }
211
212 // Ctrl+F - Find
213 if (find_callback) {
214 RegisterShortcut("find", {ImGuiMod_Ctrl, ImGuiKey_F}, find_callback);
215 }
216
217 // Ctrl+, - Settings
218 if (settings_callback) {
219 RegisterShortcut("settings", {ImGuiMod_Ctrl, ImGuiKey_Comma}, settings_callback);
220 }
221
222 // Ctrl+Tab - Next tab (placeholder for now)
223 // Ctrl+Shift+Tab - Previous tab (placeholder for now)
224}
225
227 std::function<void()> focus_left,
228 std::function<void()> focus_right,
229 std::function<void()> focus_up,
230 std::function<void()> focus_down,
231 std::function<void()> close_window,
232 std::function<void()> split_horizontal,
233 std::function<void()> split_vertical) {
234
235 // Ctrl+Arrow keys for window navigation
236 if (focus_left) {
237 RegisterShortcut("focus_left", {ImGuiMod_Ctrl, ImGuiKey_LeftArrow}, focus_left);
238 }
239
240 if (focus_right) {
241 RegisterShortcut("focus_right", {ImGuiMod_Ctrl, ImGuiKey_RightArrow}, focus_right);
242 }
243
244 if (focus_up) {
245 RegisterShortcut("focus_up", {ImGuiMod_Ctrl, ImGuiKey_UpArrow}, focus_up);
246 }
247
248 if (focus_down) {
249 RegisterShortcut("focus_down", {ImGuiMod_Ctrl, ImGuiKey_DownArrow}, focus_down);
250 }
251
252 // Ctrl+W, C - Close current window
253 if (close_window) {
254 RegisterShortcut("close_window", {ImGuiMod_Ctrl, ImGuiKey_W, ImGuiKey_C}, close_window);
255 }
256
257 // Ctrl+W, S - Split horizontal
258 if (split_horizontal) {
259 RegisterShortcut("split_horizontal", {ImGuiMod_Ctrl, ImGuiKey_W, ImGuiKey_S}, split_horizontal);
260 }
261
262 // Ctrl+W, V - Split vertical
263 if (split_vertical) {
264 RegisterShortcut("split_vertical", {ImGuiMod_Ctrl, ImGuiKey_W, ImGuiKey_V}, split_vertical);
265 }
266}
267
268} // namespace editor
269} // namespace yaze
void RegisterStandardShortcuts(std::function< void()> save_callback, std::function< void()> open_callback, std::function< void()> close_callback, std::function< void()> find_callback, std::function< void()> settings_callback)
void RegisterWindowNavigationShortcuts(std::function< void()> focus_left, std::function< void()> focus_right, std::function< void()> focus_up, std::function< void()> focus_down, std::function< void()> close_window, std::function< void()> split_horizontal, std::function< void()> split_vertical)
void RegisterShortcut(const std::string &name, const std::vector< ImGuiKey > &keys)
constexpr std::pair< ImGuiKey, const char * > kKeyNames[]
std::vector< ImGuiKey > ParseShortcut(const std::string &shortcut)
std::string PrintShortcut(const std::vector< ImGuiKey > &keys)
void ExecuteShortcuts(const ShortcutManager &shortcut_manager)
ImGuiKey MapKeyToImGuiKey(char key)
Definition input.cc:343
Main namespace for the application.
Definition controller.cc:20