openMSX
HotKey.hh
Go to the documentation of this file.
1#ifndef HOTKEY_HH
2#define HOTKEY_HH
3
4#include "RTSchedulable.hh"
5#include "EventListener.hh"
6#include "Command.hh"
7#include "Event.hh"
8#include "TclObject.hh"
9#include <map>
10#include <string_view>
11#include <vector>
12#include <string>
13
14namespace openmsx {
15
16class RTScheduler;
17class GlobalCommandController;
18class EventDistributor;
19
20class HotKey final : public RTSchedulable, public EventListener
21{
22public:
23 struct HotKeyInfo {
24 HotKeyInfo(Event event_, std::string command_,
25 bool repeat_ = false, bool passEvent_ = false)
26 : event(std::move(event_)), command(std::move(command_))
27 , repeat(repeat_)
28 , passEvent(passEvent_) {}
30 std::string command;
31 bool repeat;
32 bool passEvent; // whether to pass event with args back to command
33 };
34 using BindMap = std::vector<HotKeyInfo>; // unsorted
35 using KeySet = std::vector<Event>; // unsorted
36
37 HotKey(RTScheduler& rtScheduler,
38 GlobalCommandController& commandController,
39 EventDistributor& eventDistributor);
40 ~HotKey();
41
42 void loadInit();
43 void loadBind(std::string_view key, std::string_view cmd, bool repeat, bool event);
44 void loadUnbind(std::string_view key);
45
46 template<typename XmlStream>
47 void saveBindings(XmlStream& xml) const
48 {
49 xml.begin("bindings");
50 // add explicit bind's
51 for (const auto& k : boundKeys) {
52 xml.begin("bind");
53 xml.attribute("key", toString(k));
54 const auto& info = *find_unguarded(cmdMap, k, &HotKeyInfo::event);
55 if (info.repeat) {
56 xml.attribute("repeat", "true");
57 }
58 if (info.passEvent) {
59 xml.attribute("event", "true");
60 }
61 xml.data(info.command);
62 xml.end("bind");
63 }
64 // add explicit unbinds
65 for (const auto& k : unboundKeys) {
66 xml.begin("unbind");
67 xml.attribute("key", toString(k));
68 xml.end("unbind");
69 }
70 xml.end("bindings");
71 }
72
73private:
74 struct LayerInfo {
75 std::string layer;
76 bool blocking;
77 };
78
79 void initDefaultBindings();
80 void bind (HotKeyInfo&& info);
81 void unbind (const Event& event);
82 void bindDefault (HotKeyInfo&& info);
83 void unbindDefault(const Event& event);
84 void bindLayer (HotKeyInfo&& info, const std::string& layer);
85 void unbindLayer (const Event& event, const std::string& layer);
86 void unbindFullLayer(const std::string& layer);
87 void activateLayer (std::string layer, bool blocking);
88 void deactivateLayer(std::string_view layer);
89
90 int executeEvent(const Event& event);
91 void executeBinding(const Event& event, const HotKeyInfo& info);
92 void startRepeat (const Event& event);
93 void stopRepeat();
94
95 // EventListener
96 int signalEvent(const Event& event) override;
97 // RTSchedulable
98 void executeRT() override;
99
100private:
101 class BindCmd final : public Command {
102 public:
103 BindCmd(CommandController& commandController, HotKey& hotKey,
104 bool defaultCmd);
105 void execute(std::span<const TclObject> tokens, TclObject& result) override;
106 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
107 private:
108 HotKey& hotKey;
109 const bool defaultCmd;
110 };
111 BindCmd bindCmd;
112 BindCmd bindDefaultCmd;
113
114 class UnbindCmd final : public Command {
115 public:
116 UnbindCmd(CommandController& commandController, HotKey& hotKey,
117 bool defaultCmd);
118 void execute(std::span<const TclObject> tokens, TclObject& result) override;
119 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
120 private:
121 HotKey& hotKey;
122 const bool defaultCmd;
123 };
124 UnbindCmd unbindCmd;
125 UnbindCmd unbindDefaultCmd;
126
127 struct ActivateCmd final : Command {
128 explicit ActivateCmd(CommandController& commandController);
129 void execute(std::span<const TclObject> tokens, TclObject& result) override;
130 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
131 } activateCmd;
132
133 struct DeactivateCmd final : Command {
134 explicit DeactivateCmd(CommandController& commandController);
135 void execute(std::span<const TclObject> tokens, TclObject& result) override;
136 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
137 } deactivateCmd;
138
139 BindMap cmdMap;
140 BindMap defaultMap;
141 std::map<std::string, BindMap> layerMap;
142 std::vector<LayerInfo> activeLayers;
143 KeySet boundKeys;
144 KeySet unboundKeys;
145 GlobalCommandController& commandController;
146 EventDistributor& eventDistributor;
147 Event lastEvent;
148};
149
150} // namespace openmsx
151
152#endif
HotKey(RTScheduler &rtScheduler, GlobalCommandController &commandController, EventDistributor &eventDistributor)
Definition: HotKey.cc:38
void loadUnbind(std::string_view key)
Definition: HotKey.cc:190
void saveBindings(XmlStream &xml) const
Definition: HotKey.hh:47
std::vector< HotKeyInfo > BindMap
Definition: HotKey.hh:34
void loadBind(std::string_view key, std::string_view cmd, bool repeat, bool event)
Definition: HotKey.cc:184
void loadInit()
Definition: HotKey.cc:176
std::vector< Event > KeySet
Definition: HotKey.hh:35
This file implemented 3 utility functions:
Definition: Autofire.cc:9
std::string toString(const Event &event)
Get a string representation of this event.
Definition: Event.cc:180
STL namespace.
ITER find_unguarded(ITER first, ITER last, const VAL &val, Proj proj={})
Faster alternative to 'find' when it's guaranteed that the value will be found (if not the behavior i...
Definition: stl.hh:63
HotKeyInfo(Event event_, std::string command_, bool repeat_=false, bool passEvent_=false)
Definition: HotKey.hh:24
constexpr void repeat(T n, Op op)
Repeat the given operation 'op' 'n' times.
Definition: xrange.hh:147