openMSX
Shortcuts.cc
Go to the documentation of this file.
1#include "Shortcuts.hh"
2
3#include "one_of.hh"
4
5#include "imgui_internal.h"
6
7#include <array>
8
9namespace openmsx {
10
11// When adding a new shortcut:
12// * Add a new value in 'enum Shortcuts::ID'
13// * Add a single line in this table
16 ImGuiKeyChord keyChord;
18 bool repeat;
19 zstring_view name; // used in settings.xml
20 zstring_view description; // shown in GUI
21};
22using enum Shortcuts::ID;
23using enum Shortcuts::Type;
24static constexpr auto allShortcutInfo = std::to_array<AllShortcutInfo>({
25 {HEX_GOTO_ADDR, ImGuiKey_G | ImGuiMod_Ctrl, ALWAYS_LOCAL, false, "hex_editor_goto_address", "Go to address in hex viewer"},
26 {DEBUGGER_STEP_IN, ImGuiKey_F7, LOCAL, true, "step-in", "Debugger: step-in"},
27 {DEBUGGER_STEP_OVER, ImGuiKey_F8, LOCAL, true, "step-over", "Debugger: step-over"},
28 {DEBUGGER_STEP_OUT, ImGuiKey_F7 | ImGuiMod_Shift, LOCAL, true, "step-out", "Debugger: step-out"},
29 {DEBUGGER_STEP_BACK, ImGuiKey_F8 | ImGuiMod_Shift, LOCAL, true, "step-back", "Debugger: step-back"},
30 {DEBUGGER_BREAK_CONTINUE, ImGuiKey_F5, LOCAL, false, "break-continue", "Debugger: toggle break / continue"},
31 {DISASM_GOTO_ADDR, ImGuiMod_Ctrl | ImGuiKey_G, ALWAYS_LOCAL, false, "disasm_goto_address", "Scroll to address in disassembler"},
32});
33static_assert(allShortcutInfo.size() == Shortcuts::ID::NUM_SHORTCUTS);
34
35static constexpr auto defaultShortcuts = []{
36 std::array<Shortcuts::Shortcut, Shortcuts::ID::NUM_SHORTCUTS> result = {};
37 for (int i = 0; i < Shortcuts::ID::NUM_SHORTCUTS; ++i) {
38 const auto& all = allShortcutInfo[i];
39 assert(all.id == i); // verify that rows are in-order
40 result[i].keyChord = all.keyChord;
41 result[i].type = all.type;
42 }
43 return result;
44}();
45
46static constexpr auto shortcutRepeats = []{
47 std::array<bool, Shortcuts::ID::NUM_SHORTCUTS> result = {};
48 for (int i = 0; i < Shortcuts::ID::NUM_SHORTCUTS; ++i) {
49 result[i] = allShortcutInfo[i].repeat;
50 }
51 return result;
52}();
53
54static constexpr auto shortcutNames = []{
55 std::array<zstring_view, Shortcuts::ID::NUM_SHORTCUTS> result = {};
56 for (int i = 0; i < Shortcuts::ID::NUM_SHORTCUTS; ++i) {
57 result[i] = allShortcutInfo[i].name;
58 }
59 return result;
60}();
61
62static constexpr auto shortcutDescriptions = []{
63 std::array<zstring_view, Shortcuts::ID::NUM_SHORTCUTS> result = {};
64 for (int i = 0; i < Shortcuts::ID::NUM_SHORTCUTS; ++i) {
65 result[i] = allShortcutInfo[i].description;
66 }
67 return result;
68}();
69
74
76{
77 shortcuts = defaultShortcuts; // this can overwrite the 'type' field
78}
79
81{
82 assert(id < ID::NUM_SHORTCUTS);
83 return defaultShortcuts[id];
84}
85
87{
88 assert(id < ID::NUM_SHORTCUTS);
89 return shortcuts[id];
90}
91
92void Shortcuts::setShortcut(ID id, const Shortcut& shortcut)
93{
94 assert(id < ID::NUM_SHORTCUTS);
95 auto oldType = shortcuts[id].type;
96 shortcuts[id] = shortcut;
98 // cannot change this
99 shortcuts[id].type = oldType;
100 }
101}
102
104{
105 assert(id < ID::NUM_SHORTCUTS);
106 return shortcutRepeats[id];
107}
108
110{
111 assert(id < ID::NUM_SHORTCUTS);
112 return shortcutNames[id];
113}
114
115std::optional<Shortcuts::ID> Shortcuts::parseShortcutName(std::string_view name)
116{
117 auto it = ranges::find(shortcutNames, name);
118 if (it == shortcutNames.end()) return {};
119 return static_cast<Shortcuts::ID>(std::distance(shortcutNames.begin(), it));
120}
121
122std::optional<Shortcuts::Type> Shortcuts::parseType(std::string_view name)
123{
124 if (name == "global") return GLOBAL;
125 if (name == "local") return LOCAL;
126 return {};
127}
128
130{
131 assert(id < ID::NUM_SHORTCUTS);
132 return shortcutDescriptions[id];
133}
134
136{
137 assert(shortcut.keyChord != ImGuiKey_None);
138 auto flags = (shortcut.type == one_of(GLOBAL, ALWAYS_GLOBAL) ? ImGuiInputFlags_RouteGlobalLow : 0)
139 | ImGuiInputFlags_RouteUnlessBgFocused
140 | (shortcut.repeat ? ImGuiInputFlags_Repeat : 0);
141 return ImGui::Shortcut(shortcut.keyChord, 0, flags);
142}
143
145{
146 assert(id < ID::NUM_SHORTCUTS);
147 const auto& shortcut = shortcuts[id];
148 if (shortcut.keyChord == ImGuiKey_None) return false;
149 return checkShortcut({shortcut.keyChord, shortcut.type, getShortcutRepeat(id)});
150}
151
152} // namespace openmsx
uintptr_t id
static zstring_view getShortcutName(ID id)
Definition Shortcuts.cc:109
void setDefaultShortcuts()
Definition Shortcuts.cc:75
static const Shortcut & getDefaultShortcut(ID id)
Definition Shortcuts.cc:80
static zstring_view getShortcutDescription(ID id)
Definition Shortcuts.cc:129
bool checkShortcut(const ShortcutWithRepeat &shortcut) const
Definition Shortcuts.cc:135
static std::optional< ID > parseShortcutName(std::string_view name)
Definition Shortcuts.cc:115
static std::optional< Type > parseType(std::string_view name)
Definition Shortcuts.cc:122
void setShortcut(ID id, const Shortcut &shortcut)
Definition Shortcuts.cc:92
const Shortcut & getShortcut(ID id) const
Definition Shortcuts.cc:86
static bool getShortcutRepeat(ID id)
Definition Shortcuts.cc:103
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
This file implemented 3 utility functions:
Definition Autofire.cc:11
auto find(InputRange &&range, const T &value)
Definition ranges.hh:162
Shortcuts::Type type
Definition Shortcuts.cc:17
zstring_view description
Definition Shortcuts.cc:20
ImGuiKeyChord keyChord
Definition Shortcuts.cc:16