TachyonUI 0.1.0
High-performance UI for building tools.
Loading...
Searching...
No Matches
gui_command_manager.h
Go to the documentation of this file.
1#pragma once
2
8#include <gui_core/style/gui_style_text.h> // IconID
9
10#include <stdint.h>
11#include <functional>
12#include <string>
13#include <string_view>
14#include <vector>
15
16namespace tachyon
17{
20
24 enum class CommandMode : uint32_t
25 {
27 };
28
31 struct CommandID
32 {
33 uint32_t value = 0;
34
35 constexpr bool IsValid() const { return value != 0; }
36 constexpr explicit operator bool() const { return value != 0; }
37 constexpr bool operator==(const CommandID&) const = default;
38 static constexpr CommandID Invalid() { return {}; }
39 };
40
58 {
59 public:
61 struct Command
62 {
70 std::string description;
71 std::string displayString;
75 std::function<void()> callback;
76 std::function<void()> onEnd;
81
82 bool IsChord() const { return chord2Key != KeyCode::None; }
83 bool HasShortcut() const { return key != KeyCode::None; }
84 bool IsHeld() const { return static_cast<bool>(onEnd); }
86 bool IsRebound() const { return key != defaultKey || modifiers != defaultModifiers; }
87 };
88
90 UndoHistory& History() { return m_history; }
91 const UndoHistory& History() const { return m_history; }
92
94 {
95 m_modeNames.push_back("Default");
96 m_byMode.emplace_back(); // bucket for Default
97 }
98
101 CommandMode RegisterMode(std::string_view name)
102 {
103 for (uint32_t i = 0; i < uint32_t(m_modeNames.size()); i++)
104 if (m_modeNames[i] == name) return CommandMode(i);
105 m_modeNames.emplace_back(name);
106 m_byMode.emplace_back();
107 return CommandMode(m_modeNames.size() - 1);
108 }
109
111 std::string_view GetModeName(CommandMode mode) const
112 {
113 uint32_t index = uint32_t(mode);
114 return (index < m_modeNames.size()) ? std::string_view(m_modeNames[index]) : std::string_view{};
115 }
116
117 uint32_t GetModeCount() const { return uint32_t(m_modeNames.size()); }
118
122 {
123 m_currentMode = mode;
124 m_pendingChord.key = KeyCode::None;
125 m_pendingChord.mods = KeyModifier::None;
126 }
127 CommandMode GetMode() const { return m_currentMode; }
128
134 std::function<void()> callback, std::string_view description = {})
135 {
136 if (const CommandID existing = FindCommand(mode, key, modifiers))
137 {
138 TACHYON_LOG_DEBUG(::tachyon::Diagnostics::MakeLogCategory("input"), "updating existing command: {}", description);
139 Command& s = At(existing);
140 s.icon = icon;
141 s.description = std::string(description);
142 s.callback = std::move(callback);
143 s.onEnd = {}; // re-registering as instant drops any prior held delegate
144 return existing;
145 }
146
147 const CommandID id{ uint32_t(m_commands.size()) + 1 };
148 m_commands.push_back({
149 mode, icon, key, modifiers,
150 KeyCode::None, KeyModifier::None, // single-key: no chord2
151 std::string(description),
152 FormatShortcut(key, modifiers),
153 std::move(callback)
154 });
155 m_commands.back().defaultKey = key;
156 m_commands.back().defaultModifiers = modifiers;
157 if (uint32_t(mode) < m_byMode.size())
158 m_byMode[uint32_t(mode)].push_back(id);
159 return id;
160 }
161
164 std::function<void()> callback, std::string_view description = {})
165 {
166 return RegisterCommand(CommandMode::Default, icon, key, modifiers, std::move(callback), description);
167 }
168
171 std::function<void()> callback, std::string_view description = {})
172 {
173 return RegisterCommand(mode, IconID::Invalid, key, modifiers, std::move(callback), description);
174 }
175
178 std::function<void()> callback, std::string_view description = {})
179 {
180 return RegisterCommand(CommandMode::Default, IconID::Invalid, key, modifiers, std::move(callback), description);
181 }
182
185 std::function<void()> callback, std::string_view description = {})
186 {
187 return RegisterCommand(mode, icon, KeyCode::None, KeyModifier::None, std::move(callback), description);
188 }
189
192 std::function<void()> callback, std::string_view description = {})
193 {
194 return RegisterCommand(CommandMode::Default, icon, KeyCode::None, KeyModifier::None, std::move(callback), description);
195 }
196
200 std::function<void()> onBegin, std::function<void()> onEnd,
201 std::string_view description = {})
202 {
203 const CommandID id = RegisterCommand(mode, icon, key, modifiers, std::move(onBegin), description);
204 At(id).onEnd = std::move(onEnd);
205 return id;
206 }
207
210 std::function<void()> onBegin, std::function<void()> onEnd,
211 std::string_view description = {})
212 {
214 std::move(onBegin), std::move(onEnd), description);
215 }
216
219 std::function<void()> onBegin, std::function<void()> onEnd,
220 std::string_view description = {})
221 {
222 return RegisterHeldCommand(mode, IconID::Invalid, key, modifiers,
223 std::move(onBegin), std::move(onEnd), description);
224 }
225
229 {
230 if (key == KeyCode::None) return {};
231 const uint32_t modeIdx = uint32_t(mode);
232 if (modeIdx >= m_byMode.size()) return {};
233 for (const CommandID id : m_byMode[modeIdx])
234 {
235 const Command& s = At(id);
236 if (!s.IsChord() && s.key == key && s.modifiers == modifiers) return id;
237 }
238 return {};
239 }
240
243 KeyCode k2, KeyModifier m2) const
244 {
245 if (k1 == KeyCode::None || k2 == KeyCode::None) return {};
246 const uint32_t modeIdx = uint32_t(mode);
247 if (modeIdx >= m_byMode.size()) return {};
248 for (const CommandID id : m_byMode[modeIdx])
249 {
250 const Command& s = At(id);
251 if (s.IsChord()
252 && s.key == k1 && s.modifiers == m1
253 && s.chord2Key == k2 && s.chord2Mods == m2)
254 return id;
255 }
256 return {};
257 }
258
263 KeyCode key1, KeyModifier mods1,
264 KeyCode key2, KeyModifier mods2,
265 std::function<void()> callback, std::string_view description = {})
266 {
267 if (const CommandID existing = FindChord(mode, key1, mods1, key2, mods2))
268 {
269 Command& s = At(existing);
270 s.description = std::string(description);
271 s.callback = std::move(callback);
272 return existing;
273 }
274
275 const CommandID id{ uint32_t(m_commands.size()) + 1 };
276 m_commands.push_back({
277 mode, IconID::Invalid, key1, mods1,
278 key2, mods2,
279 std::string(description),
280 FormatChordShortcut(key1, mods1, key2, mods2),
281 std::move(callback)
282 });
283 m_commands.back().defaultKey = key1;
284 m_commands.back().defaultModifiers = mods1;
285 if (uint32_t(mode) < m_byMode.size())
286 m_byMode[uint32_t(mode)].push_back(id);
287 return id;
288 }
289
294 {
295 return [this](ElementEvent&& event) -> bool
296 {
297 if (event.type == EventType::KeyDown) return ProcessInput(event.state);
298 if (event.type == EventType::KeyUp) return ProcessKeyUp(event.state);
299 return false;
300 };
301 }
302
303 // --- Inspection API (for command/shortcut viewer UI) ---
304
306 const std::vector<Command>& GetCommands() const { return m_commands; }
307 static CommandID IDAt(size_t index) { return CommandID{ uint32_t(index) + 1 }; }
308 static size_t IndexOf(CommandID id) { return size_t(id.value) - 1; } // a valid ID's index
309
311 const Command* GetCommand(CommandID id) const
312 {
313 return (id.value >= 1 && id.value <= m_commands.size()) ? &m_commands[id.value - 1] : nullptr;
314 }
315
317 const std::vector<CommandID>& GetCommandsForMode(CommandMode mode) const
318 {
319 static const std::vector<CommandID> empty;
320 uint32_t index = uint32_t(mode);
321 return (index < m_byMode.size()) ? m_byMode[index] : empty;
322 }
323
324 // --- Rebind mode ---
325
328 void BeginRebind(CommandID id) { m_rebinding = GetCommand(id) ? id : CommandID{}; }
329 void CancelRebind() { m_rebinding = {}; }
330 bool IsRebinding() const { return m_rebinding.IsValid(); }
331 CommandID RebindTarget() const { return m_rebinding; }
332
336 void SetShortcut(CommandID id, KeyCode key, KeyModifier modifiers)
337 {
338 if (!GetCommand(id)) return;
339 Command& s = At(id);
340
341 // Most recent wins: another command in this mode owning (key, mods) becomes unbound.
342 if (key != KeyCode::None)
343 {
344 const CommandID existing = FindCommand(s.mode, key, modifiers);
345 if (existing && existing != id)
346 {
347 Command& other = At(existing);
348 other.key = KeyCode::None;
351 }
352 }
353
354 s.key = key;
355 s.modifiers = key != KeyCode::None ? modifiers : KeyModifier::None;
358 }
359
361 bool IsChordPending() const { return m_pendingChord.key != KeyCode::None; }
362
365 static std::string FormatChordShortcut(KeyCode k1, KeyModifier m1,
366 KeyCode k2, KeyModifier m2)
367 {
368 if (k1 == KeyCode::None) return "(unbound)";
369 std::string out = FormatShortcut(k1, m1);
370 if (k2 != KeyCode::None)
371 {
372 out += ' ';
373 out += FormatShortcut(k2, m2);
374 }
375 return out;
376 }
377
380 static std::string FormatShortcut(KeyCode key, KeyModifier modifiers)
381 {
382 if (key == KeyCode::None) return "(unbound)";
383 std::string out;
384 auto addMod = [&](KeyModifier bit, const char* name)
385 {
386 if ((modifiers & bit) != KeyModifier::None)
387 {
388 if (!out.empty()) out += '+';
389 out += name;
390 }
391 };
392 addMod(KeyModifier::Control, "Ctrl");
393 addMod(KeyModifier::Shift, "Shift");
394 addMod(KeyModifier::Alt, "Alt");
395 addMod(KeyModifier::Command, "Cmd");
396 addMod(KeyModifier::Option, "Opt");
397
398 if (!out.empty()) out += '+';
399 out += KeyCodeName(key);
400 return out;
401 }
402
404 static std::string KeyCodeName(KeyCode k)
405 {
406 switch (k)
407 {
408 case KeyCode::None: return "(none)";
409 case KeyCode::Return: return "Enter";
410 case KeyCode::Escape: return "Esc";
411 case KeyCode::Backspace: return "Backspace";
412 case KeyCode::Tab: return "Tab";
413 case KeyCode::Space: return "Space";
414 case KeyCode::Comma: return ",";
415 case KeyCode::Minus: return "-";
416 case KeyCode::Period: return ".";
417 case KeyCode::Slash: return "/";
418 case KeyCode::Semicolon: return ";";
419 case KeyCode::Equals: return "=";
420 case KeyCode::LeftBracket: return "[";
421 case KeyCode::Backslash: return "\\";
422 case KeyCode::RightBracket:return "]";
423 case KeyCode::Backquote: return "`";
424 case KeyCode::Quote: return "'";
425 case KeyCode::Insert: return "Insert";
426 case KeyCode::Home: return "Home";
427 case KeyCode::PageUp: return "PageUp";
428 case KeyCode::Delete: return "Delete";
429 case KeyCode::End: return "End";
430 case KeyCode::PageDown: return "PageDown";
431 case KeyCode::Right: return "Right";
432 case KeyCode::Left: return "Left";
433 case KeyCode::Down: return "Down";
434 case KeyCode::Up: return "Up";
435 default: break;
436 }
437 if (k >= KeyCode::KeyA && k <= KeyCode::KeyZ)
438 return std::string(1, char('A' + (uint32_t(k) - uint32_t(KeyCode::KeyA))));
439 if (k >= KeyCode::Key0 && k <= KeyCode::Key9)
440 return std::string(1, char('0' + (uint32_t(k) - uint32_t(KeyCode::Key0))));
441 if (k >= KeyCode::F1 && k <= KeyCode::F12)
442 return "F" + std::to_string(1 + int(uint32_t(k) - uint32_t(KeyCode::F1)));
443 return "?";
444 }
445
446 private:
447 struct KeyChord
448 {
451 };
452
453 static bool IsModifierKey(KeyCode k)
454 {
457 || k == KeyCode::LeftAlt || k == KeyCode::RightAlt
459 }
460
461 Command& At(CommandID id) { return m_commands[id.value - 1]; }
462 const Command& At(CommandID id) const { return m_commands[id.value - 1]; }
463
464 public:
468 bool ProcessInput(const InputState& state)
469 {
470 if (state.lastKey == KeyCode::None)
471 return false;
472
473 // Before the state.consumed check so a focused textbox can't swallow the rebind key.
474 if (m_rebinding)
475 {
476 if (IsModifierKey(state.lastKey)) return false;
477 if (state.lastKey != KeyCode::Escape)
478 SetShortcut(m_rebinding, state.lastKey, state.modifiers);
479 m_rebinding = {};
480 return true;
481 }
482
483 if (state.consumed)
484 return false;
485
486 // The next non-modifier key completes the chord or cancels it.
487 if (m_pendingChord.key != KeyCode::None)
488 {
489 if (IsModifierKey(state.lastKey)) return false;
490
491 KeyChord pending = m_pendingChord;
492 m_pendingChord = {};
493
494 if (state.lastKey == KeyCode::Escape)
495 return true;
496
497 if (TryCompleteChord(m_currentMode, pending, state)) return true;
498 if (m_currentMode != CommandMode::Default
499 && TryCompleteChord(CommandMode::Default, pending, state)) return true;
500
501 // Swallow a non-completing key so it doesn't fire an unrelated command.
502 return true;
503 }
504
505 if (TryDispatchMode(m_currentMode, state)) return true;
506 if (m_currentMode != CommandMode::Default
507 && TryDispatchMode(CommandMode::Default, state)) return true;
508
509 // A chord prefix enters pending state.
510 if (HasChordPrefix(m_currentMode, state.lastKey, state.modifiers)
511 || (m_currentMode != CommandMode::Default
512 && HasChordPrefix(CommandMode::Default, state.lastKey, state.modifiers)))
513 {
514 m_pendingChord = { state.lastKey, state.modifiers };
515 return true;
516 }
517
518 return false;
519 }
520
523 bool ProcessKeyUp(const InputState& state)
524 {
525 if (state.lastKey == KeyCode::None) return false;
526 bool fired = false;
527 for (size_t j = 0; j < m_activeHeld.size(); )
528 {
529 if (m_activeHeld[j].key != state.lastKey) { ++j; continue; }
530 const CommandID cmd = m_activeHeld[j].cmd;
531 m_activeHeld.erase(m_activeHeld.begin() + j);
532 if (const Command* c = GetCommand(cmd); c && c->onEnd)
533 c->onEnd();
534 fired = true;
535 }
536 return fired;
537 }
538
539 private:
540 bool TryDispatchMode(CommandMode mode, const InputState& state)
541 {
542 uint32_t index = uint32_t(mode);
543 if (index >= m_byMode.size()) return false;
544 for (const CommandID i : m_byMode[index])
545 {
546 const Command& s = At(i);
547 if (s.IsChord()) continue; // chord commands only fire via the pending-prefix path
548 if (s.key == state.lastKey && s.modifiers == state.modifiers)
549 {
550 BeginCommand(i);
551 return true;
552 }
553 }
554 return false;
555 }
556
559 void BeginCommand(CommandID i)
560 {
561 const Command& s = At(i);
562 if (s.IsHeld())
563 {
564 if (IsHeldActive(i)) return;
565 m_activeHeld.push_back({ s.key, i });
566 }
567 if (s.callback) s.callback();
568 }
569
570 bool IsHeldActive(CommandID cmd) const
571 {
572 for (const HeldActive& h : m_activeHeld)
573 if (h.cmd == cmd) return true;
574 return false;
575 }
576
577 bool TryCompleteChord(CommandMode mode, KeyChord prefix, const InputState& state)
578 {
579 uint32_t index = uint32_t(mode);
580 if (index >= m_byMode.size()) return false;
581 for (const CommandID i : m_byMode[index])
582 {
583 const Command& s = At(i);
584 if (!s.IsChord()) continue;
585 if (s.key == prefix.key && s.modifiers == prefix.mods
586 && s.chord2Key == state.lastKey && s.chord2Mods == state.modifiers)
587 {
588 if (s.callback) s.callback();
589 return true;
590 }
591 }
592 return false;
593 }
594
595 bool HasChordPrefix(CommandMode mode, KeyCode key, KeyModifier mods) const
596 {
597 uint32_t index = uint32_t(mode);
598 if (index >= m_byMode.size()) return false;
599 for (const CommandID i : m_byMode[index])
600 {
601 const Command& s = At(i);
602 if (s.IsChord() && s.key == key && s.modifiers == mods)
603 return true;
604 }
605 return false;
606 }
607
608 UndoHistory m_history;
609 struct HeldActive { KeyCode key; CommandID cmd; };
610
611 std::vector<std::string> m_modeNames;
612 std::vector<Command> m_commands;
613 std::vector<std::vector<CommandID>> m_byMode;
614 CommandMode m_currentMode = CommandMode::Default;
615 CommandID m_rebinding;
616 KeyChord m_pendingChord {};
617 std::vector<HeldActive> m_activeHeld;
618 };
619
621} // namespace tachyon
UndoHistory & History()
The app's undo history (text fields push their edits to it).
Definition gui_command_manager.h:90
CommandID RegisterHeldCommand(KeyCode key, KeyModifier modifiers, std::function< void()> onBegin, std::function< void()> onEnd, std::string_view description={})
RegisterHeldCommand in the Default mode, without an icon.
Definition gui_command_manager.h:209
CommandID RebindTarget() const
Definition gui_command_manager.h:331
EventHandler MakeHandler()
An EventHandler to push onto the InputManager as a global handler.
Definition gui_command_manager.h:293
CommandMode RegisterMode(std::string_view name)
Registers a named mode and returns the CommandMode to use when registering commands or calling SetMod...
Definition gui_command_manager.h:101
CommandID RegisterCommand(CommandMode mode, KeyCode key, KeyModifier modifiers, std::function< void()> callback, std::string_view description={})
RegisterCommand without an icon.
Definition gui_command_manager.h:170
CommandID RegisterHeldCommand(CommandMode mode, IconID icon, KeyCode key, KeyModifier modifiers, std::function< void()> onBegin, std::function< void()> onEnd, std::string_view description={})
Registers a hold-to-act command (pan, orbit): onBegin on press, onEnd on release.
Definition gui_command_manager.h:199
CommandID FindCommand(CommandMode mode, KeyCode key, KeyModifier modifiers) const
The single-key command bound to (mode, key, modifiers); Invalid if none.
Definition gui_command_manager.h:228
bool ProcessInput(const InputState &state)
Runs a keydown InputState through rebind / chord / shortcut dispatch; true when it handled the key.
Definition gui_command_manager.h:468
bool ProcessKeyUp(const InputState &state)
Fires onEnd of every active held command on the released key (modifiers are ignored); true if any fir...
Definition gui_command_manager.h:523
void CancelRebind()
Definition gui_command_manager.h:329
void BeginRebind(CommandID id)
Makes the next non-modifier keydown the shortcut of id instead of firing anything.
Definition gui_command_manager.h:328
const UndoHistory & History() const
Definition gui_command_manager.h:91
bool IsChordPending() const
True while a chord prefix was pressed and awaits its second key.
Definition gui_command_manager.h:361
CommandID RegisterChord(CommandMode mode, KeyCode key1, KeyModifier mods1, KeyCode key2, KeyModifier mods2, std::function< void()> callback, std::string_view description={})
Registers a 2-key chord command (e.g.
Definition gui_command_manager.h:262
static std::string FormatShortcut(KeyCode key, KeyModifier modifiers)
Formats a (key, modifiers) combo as a human-readable string like "Ctrl+Shift+D".
Definition gui_command_manager.h:380
CommandMode GetMode() const
Definition gui_command_manager.h:127
CommandID FindChord(CommandMode mode, KeyCode k1, KeyModifier m1, KeyCode k2, KeyModifier m2) const
The chord command in mode bound to exactly k1+m1 then k2+m2; Invalid if none.
Definition gui_command_manager.h:242
void SetShortcut(CommandID id, KeyCode key, KeyModifier modifiers)
Gives id the shortcut (key, modifiers), as a rebind does: another command in its mode that had it is ...
Definition gui_command_manager.h:336
CommandID RegisterHeldCommand(CommandMode mode, KeyCode key, KeyModifier modifiers, std::function< void()> onBegin, std::function< void()> onEnd, std::string_view description={})
RegisterHeldCommand without an icon.
Definition gui_command_manager.h:218
std::string_view GetModeName(CommandMode mode) const
The name mode was registered with; empty for an unknown mode.
Definition gui_command_manager.h:111
CommandID RegisterCommand(IconID icon, std::function< void()> callback, std::string_view description={})
RegisterCommand in the Default mode, without a shortcut key.
Definition gui_command_manager.h:191
const std::vector< CommandID > & GetCommandsForMode(CommandMode mode) const
Handles for a given mode, in registration order.
Definition gui_command_manager.h:317
const Command * GetCommand(CommandID id) const
The command, or null for an invalid or unknown ID.
Definition gui_command_manager.h:311
CommandID RegisterCommand(IconID icon, KeyCode key, KeyModifier modifiers, std::function< void()> callback, std::string_view description={})
RegisterCommand in the Default mode.
Definition gui_command_manager.h:163
CommandID RegisterCommand(KeyCode key, KeyModifier modifiers, std::function< void()> callback, std::string_view description={})
RegisterCommand in the Default mode, without an icon.
Definition gui_command_manager.h:177
CommandID RegisterCommand(CommandMode mode, IconID icon, std::function< void()> callback, std::string_view description={})
RegisterCommand without a shortcut key.
Definition gui_command_manager.h:184
const std::vector< Command > & GetCommands() const
Every command, in registration order: the one at index i has CommandID{ i + 1 }.
Definition gui_command_manager.h:306
static size_t IndexOf(CommandID id)
Definition gui_command_manager.h:308
void SetMode(CommandMode mode)
Makes mode the active mode, whose shortcuts are tried before Default.
Definition gui_command_manager.h:121
static std::string KeyCodeName(KeyCode k)
A short human-readable key name, e.g. "A", "F5", "Enter", "["; "?" for unknown keys.
Definition gui_command_manager.h:404
CommandManager()
Definition gui_command_manager.h:93
static CommandID IDAt(size_t index)
Definition gui_command_manager.h:307
bool IsRebinding() const
Definition gui_command_manager.h:330
static std::string FormatChordShortcut(KeyCode k1, KeyModifier m1, KeyCode k2, KeyModifier m2)
Formats a chord shortcut as "Ctrl+K Ctrl+S"; the single-key form when k2 is None, "(unbound)" when k1...
Definition gui_command_manager.h:365
CommandID RegisterCommand(CommandMode mode, IconID icon, KeyCode key, KeyModifier modifiers, std::function< void()> callback, std::string_view description={})
Registers callback in mode; description names it in menus and shortcut lists.
Definition gui_command_manager.h:133
uint32_t GetModeCount() const
Definition gui_command_manager.h:117
The app's undo history: steps that each undo and redo one change.
Definition gui_undo_history.h:18
constexpr LogCategory MakeLogCategory(std::string_view staticName)
A category named staticName, which must be a static string.
Definition gui_logging.h:41
KeyCode
Keys by what the keyboard layout makes them, not by position.
Definition gui_input_enums.h:106
std::function< bool(ElementEvent &&input)> EventHandler
Element-level input handler used by the immediate-mode dispatcher; returns true when it consumed the ...
Definition gui_input_handler_func.h:35
CommandMode
A set of shortcuts that is active while the app says so (e.g.
Definition gui_command_manager.h:25
KeyModifier
Modifier keys held, combined with |.
Definition gui_input_enums.h:26
@ Escape
Definition gui_input_enums.h:110
@ Down
Definition gui_input_enums.h:206
@ Equals
Definition gui_input_enums.h:142
@ Period
Definition gui_input_enums.h:127
@ Backquote
Definition gui_input_enums.h:152
@ Up
Definition gui_input_enums.h:207
@ Key9
Definition gui_input_enums.h:138
@ RightShift
Definition gui_input_enums.h:324
@ Slash
Definition gui_input_enums.h:128
@ Minus
Definition gui_input_enums.h:126
@ RightBracket
Definition gui_input_enums.h:149
@ LeftBracket
Definition gui_input_enums.h:147
@ RightCommand
Definition gui_input_enums.h:326
@ Comma
Definition gui_input_enums.h:125
@ Tab
Definition gui_input_enums.h:112
@ LeftControl
Definition gui_input_enums.h:319
@ KeyA
Definition gui_input_enums.h:153
@ None
Definition gui_input_enums.h:107
@ RightControl
Definition gui_input_enums.h:323
@ End
Definition gui_input_enums.h:202
@ Home
Definition gui_input_enums.h:199
@ LeftCommand
Definition gui_input_enums.h:322
@ Right
Definition gui_input_enums.h:204
@ KeyZ
Definition gui_input_enums.h:178
@ Left
Definition gui_input_enums.h:205
@ LeftAlt
Definition gui_input_enums.h:321
@ Semicolon
Definition gui_input_enums.h:140
@ LeftShift
Definition gui_input_enums.h:320
@ Return
Definition gui_input_enums.h:109
@ PageUp
Definition gui_input_enums.h:200
@ Insert
Definition gui_input_enums.h:198
@ Key0
Definition gui_input_enums.h:129
@ Quote
Definition gui_input_enums.h:120
@ Backspace
Definition gui_input_enums.h:111
@ Space
Definition gui_input_enums.h:113
@ RightAlt
Definition gui_input_enums.h:325
@ F1
Definition gui_input_enums.h:182
@ F12
Definition gui_input_enums.h:193
@ PageDown
Definition gui_input_enums.h:203
@ Delete
Definition gui_input_enums.h:201
@ Backslash
Definition gui_input_enums.h:148
@ KeyUp
Definition gui_input_enums.h:82
@ KeyDown
Definition gui_input_enums.h:81
@ Default
Definition gui_command_manager.h:26
@ Option
Definition gui_input_enums.h:31
@ None
Definition gui_input_enums.h:27
@ Shift
Definition gui_input_enums.h:28
@ Control
Definition gui_input_enums.h:29
@ Alt
Definition gui_input_enums.h:30
@ Command
Definition gui_input_enums.h:32
IconID
Handle for an icon registered with ITextSystem::RegisterIconFromSVG / RegisterIconFromSVGFile.
Definition gui_style_text.h:15
@ Invalid
Definition gui_style_text.h:15
#define TACHYON_LOG_DEBUG(category,...)
Definition gui_logging.h:183
Definition gui_logging.h:24
Handle to a registered command, stable for the manager's lifetime.
Definition gui_command_manager.h:32
uint32_t value
Definition gui_command_manager.h:33
static constexpr CommandID Invalid()
Definition gui_command_manager.h:38
constexpr bool operator==(const CommandID &) const =default
constexpr bool IsValid() const
Definition gui_command_manager.h:35
A registered command.
Definition gui_command_manager.h:62
KeyCode chord2Key
Second key of a 2-key chord (e.g. Ctrl+K then Ctrl+S); None = single-key.
Definition gui_command_manager.h:68
bool HasShortcut() const
Definition gui_command_manager.h:83
KeyModifier defaultModifiers
Definition gui_command_manager.h:80
KeyCode defaultKey
The shortcut it was registered with (the first key, for a chord).
Definition gui_command_manager.h:79
bool IsRebound() const
True when its shortcut isn't the one it was registered with.
Definition gui_command_manager.h:86
KeyCode key
Definition gui_command_manager.h:65
KeyModifier modifiers
Definition gui_command_manager.h:66
std::function< void()> callback
Instant: callback fires on press, onEnd is empty.
Definition gui_command_manager.h:75
std::string description
Definition gui_command_manager.h:70
std::string displayString
cached "Ctrl+Shift+D" or "Ctrl+K Ctrl+S"
Definition gui_command_manager.h:71
CommandMode mode
Definition gui_command_manager.h:63
bool IsHeld() const
Definition gui_command_manager.h:84
IconID icon
optional
Definition gui_command_manager.h:64
std::function< void()> onEnd
Instant: callback fires on press, onEnd is empty.
Definition gui_command_manager.h:76
KeyModifier chord2Mods
Definition gui_command_manager.h:69
bool IsChord() const
Definition gui_command_manager.h:82
An input event delivered to an element's EventHandler.
Definition gui_input_handler_func.h:20
Snapshot of input state for a single recorded OS event.
Definition gui_input_state.h:17
bool consumed
True when the event was already handled (e.g. Tab by tab navigation).
Definition gui_input_state.h:45
tachyon::KeyCode lastKey
Definition gui_input_state.h:29
tachyon::KeyModifier modifiers
Definition gui_input_state.h:25