36 constexpr explicit operator bool()
const {
return value != 0; }
95 m_modeNames.push_back(
"Default");
96 m_byMode.emplace_back();
103 for (uint32_t i = 0; i < uint32_t(m_modeNames.size()); i++)
105 m_modeNames.emplace_back(name);
106 m_byMode.emplace_back();
113 uint32_t index = uint32_t(mode);
114 return (index < m_modeNames.size()) ? std::string_view(m_modeNames[index]) : std::string_view{};
123 m_currentMode = mode;
134 std::function<
void()> callback, std::string_view description = {})
141 s.description = std::string(description);
142 s.callback = std::move(callback);
147 const CommandID
id{ uint32_t(m_commands.size()) + 1 };
148 m_commands.push_back({
149 mode, icon, key, modifiers,
151 std::string(description),
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);
164 std::function<
void()> callback, std::string_view description = {})
171 std::function<
void()> callback, std::string_view description = {})
178 std::function<
void()> callback, std::string_view description = {})
185 std::function<
void()> callback, std::string_view description = {})
192 std::function<
void()> callback, std::string_view description = {})
200 std::function<
void()> onBegin, std::function<
void()> onEnd,
201 std::string_view description = {})
204 At(
id).
onEnd = std::move(onEnd);
210 std::function<
void()> onBegin, std::function<
void()> onEnd,
211 std::string_view description = {})
214 std::move(onBegin), std::move(onEnd), description);
219 std::function<
void()> onBegin, std::function<
void()> onEnd,
220 std::string_view description = {})
223 std::move(onBegin), std::move(onEnd), description);
231 const uint32_t modeIdx = uint32_t(mode);
232 if (modeIdx >= m_byMode.size())
return {};
233 for (
const CommandID id : m_byMode[modeIdx])
246 const uint32_t modeIdx = uint32_t(mode);
247 if (modeIdx >= m_byMode.size())
return {};
248 for (
const CommandID id : m_byMode[modeIdx])
265 std::function<
void()> callback, std::string_view description = {})
270 s.description = std::string(description);
271 s.callback = std::move(callback);
275 const CommandID
id{ uint32_t(m_commands.size()) + 1 };
276 m_commands.push_back({
279 std::string(description),
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);
306 const std::vector<Command>&
GetCommands()
const {
return m_commands; }
313 return (
id.value >= 1 &&
id.value <= m_commands.size()) ? &m_commands[
id.value - 1] :
nullptr;
319 static const std::vector<CommandID> empty;
320 uint32_t index = uint32_t(mode);
321 return (index < m_byMode.size()) ? m_byMode[index] : empty;
345 if (existing && existing !=
id)
384 auto addMod = [&](
KeyModifier bit,
const char* name)
388 if (!out.empty()) out +=
'+';
398 if (!out.empty()) out +=
'+';
438 return std::string(1,
char(
'A' + (uint32_t(k) - uint32_t(
KeyCode::KeyA))));
440 return std::string(1,
char(
'0' + (uint32_t(k) - uint32_t(
KeyCode::Key0))));
442 return "F" + std::to_string(1 +
int(uint32_t(k) - uint32_t(
KeyCode::F1)));
453 static bool IsModifierKey(
KeyCode k)
461 Command& At(CommandID
id) {
return m_commands[
id.value - 1]; }
462 const Command& At(CommandID
id)
const {
return m_commands[
id.value - 1]; }
476 if (IsModifierKey(state.
lastKey))
return false;
489 if (IsModifierKey(state.
lastKey))
return false;
491 KeyChord pending = m_pendingChord;
497 if (TryCompleteChord(m_currentMode, pending, state))
return true;
505 if (TryDispatchMode(m_currentMode, state))
return true;
527 for (
size_t j = 0; j < m_activeHeld.size(); )
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);
542 uint32_t index = uint32_t(mode);
543 if (index >= m_byMode.size())
return false;
544 for (
const CommandID i : m_byMode[index])
547 if (s.IsChord())
continue;
559 void BeginCommand(CommandID i)
564 if (IsHeldActive(i))
return;
565 m_activeHeld.push_back({ s.key, i });
567 if (s.callback) s.callback();
570 bool IsHeldActive(CommandID cmd)
const
572 for (
const HeldActive& h : m_activeHeld)
573 if (h.cmd == cmd)
return true;
577 bool TryCompleteChord(
CommandMode mode, KeyChord prefix,
const InputState& state)
579 uint32_t index = uint32_t(mode);
580 if (index >= m_byMode.size())
return false;
581 for (
const CommandID i : m_byMode[index])
584 if (!s.IsChord())
continue;
585 if (s.key == prefix.key && s.modifiers == prefix.mods
586 && s.chord2Key == state.lastKey && s.chord2Mods == state.modifiers)
588 if (s.callback) s.callback();
597 uint32_t index = uint32_t(mode);
598 if (index >= m_byMode.size())
return false;
599 for (
const CommandID i : m_byMode[index])
602 if (s.IsChord() && s.key == key && s.modifiers == mods)
608 UndoHistory m_history;
609 struct HeldActive {
KeyCode key; CommandID cmd; };
611 std::vector<std::string> m_modeNames;
612 std::vector<Command> m_commands;
613 std::vector<std::vector<CommandID>> m_byMode;
615 CommandID m_rebinding;
616 KeyChord m_pendingChord {};
617 std::vector<HeldActive> m_activeHeld;
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
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