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 {DISASM_RUN_TO_ADDR, ImGuiMod_Ctrl | ImGuiKey_R, ALWAYS_LOCAL, false, "disasm_run_to_address", "Debugger: run to a specific address"},
33 {DISASM_TOGGLE_BREAKPOINT,ImGuiMod_Ctrl | ImGuiKey_B, ALWAYS_LOCAL, false, "disasm_toggle_breakpoint","Debugger: toggle breakpoint at current address"},
34});
35static_assert(allShortcutInfo.size() == to_underlying(Shortcuts::ID::NUM));
36
37static constexpr auto defaultShortcuts = []{
39 for (int i = 0; i < to_underlying(Shortcuts::ID::NUM); ++i) {
40 const auto& all = allShortcutInfo[i];
41 auto id = static_cast<Shortcuts::ID>(i);
42 assert(all.id == id); // verify that rows are in-order
43 result[id].keyChord = all.keyChord;
44 result[id].type = all.type;
45 }
46 return result;
47}();
48
49static constexpr auto shortcutRepeats = []{
51 for (int i = 0; i < to_underlying(Shortcuts::ID::NUM); ++i) {
52 auto id = static_cast<Shortcuts::ID>(i);
53 result[id] = allShortcutInfo[i].repeat;
54 }
55 return result;
56}();
57
58static constexpr auto shortcutNames = []{
60 for (int i = 0; i < to_underlying(Shortcuts::ID::NUM); ++i) {
61 auto id = static_cast<Shortcuts::ID>(i);
62 result[id] = allShortcutInfo[i].name;
63 }
64 return result;
65}();
66
67static constexpr auto shortcutDescriptions = []{
69 for (int i = 0; i < to_underlying(Shortcuts::ID::NUM); ++i) {
70 auto id = static_cast<Shortcuts::ID>(i);
71 result[id] = allShortcutInfo[i].description;
72 }
73 return result;
74}();
75
80
82{
83 shortcuts = defaultShortcuts; // this can overwrite the 'type' field
84}
85
87{
88 return defaultShortcuts[id];
89}
90
92{
93 return shortcuts[id];
94}
95
96void Shortcuts::setShortcut(ID id, const Shortcut& shortcut)
97{
98 auto oldType = shortcuts[id].type;
99 shortcuts[id] = shortcut;
101 // cannot change this
102 shortcuts[id].type = oldType;
103 }
104}
105
107{
108 return shortcutRepeats[id];
109}
110
112{
113 return shortcutNames[id];
114}
115
116std::optional<Shortcuts::ID> Shortcuts::parseShortcutName(std::string_view name)
117{
118 auto it = ranges::find(shortcutNames, name);
119 if (it == shortcutNames.end()) return {};
120 return static_cast<Shortcuts::ID>(std::distance(shortcutNames.begin(), it));
121}
122
123std::optional<Shortcuts::Type> Shortcuts::parseType(std::string_view name)
124{
125 if (name == "global") return GLOBAL;
126 if (name == "local") return LOCAL;
127 return {};
128}
129
131{
132 return shortcutDescriptions[id];
133}
134
136{
137 assert(shortcut.keyChord != ImGuiKey_None);
138 auto flags = (shortcut.type == one_of(GLOBAL, ALWAYS_GLOBAL) ? (ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteUnlessBgFocused) : 0)
139 | (shortcut.repeat ? ImGuiInputFlags_Repeat : 0);
140 return ImGui::Shortcut(shortcut.keyChord, flags, 0);
141}
142
144{
145 const auto& shortcut = shortcuts[id];
146 if (shortcut.keyChord == ImGuiKey_None) return false;
147 return checkShortcut({shortcut.keyChord, shortcut.type, getShortcutRepeat(id)});
148}
149
150} // namespace openmsx
uintptr_t id
static zstring_view getShortcutName(ID id)
Definition Shortcuts.cc:111
void setDefaultShortcuts()
Definition Shortcuts.cc:81
static const Shortcut & getDefaultShortcut(ID id)
Definition Shortcuts.cc:86
static zstring_view getShortcutDescription(ID id)
Definition Shortcuts.cc:130
bool checkShortcut(const ShortcutWithRepeat &shortcut) const
Definition Shortcuts.cc:135
static std::optional< ID > parseShortcutName(std::string_view name)
Definition Shortcuts.cc:116
static std::optional< Type > parseType(std::string_view name)
Definition Shortcuts.cc:123
void setShortcut(ID id, const Shortcut &shortcut)
Definition Shortcuts.cc:96
const Shortcut & getShortcut(ID id) const
Definition Shortcuts.cc:91
static bool getShortcutRepeat(ID id)
Definition Shortcuts.cc:106
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
constexpr auto to_underlying(E e) noexcept
Definition stl.hh:468
Shortcuts::Type type
Definition Shortcuts.cc:17
zstring_view description
Definition Shortcuts.cc:20
ImGuiKeyChord keyChord
Definition Shortcuts.cc:16