Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.24
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
KeyMappingManager.hpp
1#pragma once
2
3#include <Core/Utils/Index.hpp>
4#include <Core/Utils/Log.hpp>
5#include <Core/Utils/Observable.hpp>
6#include <Core/Utils/Singleton.hpp>
7#include <Core/Utils/StdOptional.hpp>
8#include <Gui/RaGui.hpp>
9#include <QXmlStreamWriter>
10#include <QtGui/QKeyEvent>
11#include <QtGui/QMouseEvent>
12#include <QtXml/QtXml>
13#include <functional>
14#include <map>
15#include <optional>
16#include <string>
17#include <utility>
18#include <vector>
19
20namespace Ra {
21namespace Gui {
26class RA_GUI_API KeyMappingManager : public Ra::Core::Utils::ObservableVoid
27{
28 RA_SINGLETON_INTERFACE( KeyMappingManager );
29
30 public:
33 {
34 public:
38 EventBinding() = default;
39
44 EventBinding( Qt::MouseButtons buttons,
45 Qt::KeyboardModifiers modifiers,
46 int key,
47 bool wheel = false ) :
48 m_buttons { buttons }, m_modifiers { modifiers }, m_key { key }, m_wheel { wheel } {}
49
53 explicit EventBinding( Qt::MouseButtons buttons,
54 Qt::KeyboardModifiers modifiers = Qt::NoModifier ) :
55 m_buttons { buttons }, m_modifiers { modifiers } {}
56
60 explicit EventBinding( int key, Qt::KeyboardModifiers modifiers = Qt::NoModifier ) :
61 m_modifiers { modifiers }, m_key { key } {}
62
66 explicit EventBinding( bool wheel, Qt::KeyboardModifiers modifiers = Qt::NoModifier ) :
67 m_modifiers { modifiers }, m_wheel { wheel } {}
68
69 bool isMouseEvent() { return m_buttons != Qt::NoButton; }
70 bool isWheelEvent() { return m_wheel; }
71 bool isKeyEvent() { return !isMouseEvent() && !isWheelEvent(); }
72 bool operator<( const EventBinding& b ) const;
73
74 // public data member, since there isn't any write access getter from KeyMappingManager
75 Qt::MouseButtons m_buttons { Qt::NoButton };
76 Qt::KeyboardModifiers m_modifiers { Qt::NoModifier };
77 // only one key
78 int m_key { -1 };
79 bool m_wheel { false };
80 };
81
82 using KeyMappingAction = Ra::Core::Utils::Index;
83 using Context = Ra::Core::Utils::Index;
84
87 void loadConfiguration( const std::string& filename = {} );
88
92 bool saveConfiguration( const std::string& filename = {} );
93
95 void reloadConfiguration();
96
97 std::string getLoadedFilename() { return m_file->fileName().toStdString(); }
98
105 KeyMappingAction getAction( const Context& context,
106 const Qt::MouseButtons& buttons,
107 const Qt::KeyboardModifiers& modifiers,
108 int key,
109 bool wheel = false );
110 KeyMappingAction
111 getAction( const Context& context, const QEvent* event, int key, bool wheel = false );
112 KeyMappingAction getAction( const Context& context, const EventBinding& binding );
113
116 std::optional<EventBinding> getBinding( const Context& context, KeyMappingAction action );
117
120 KeyMappingAction addAction( const Context& context, const std::string& actionName );
121
124 KeyMappingAction
125 addAction( const Context& context, const EventBinding& binding, const std::string& actionName );
126
130 void setActionBinding( const Context& context,
131 const EventBinding& binding,
132 const KeyMappingAction& action );
133
140 Context addContext( const std::string& contextName );
141
145 Context getContext( const std::string& contextName );
146
152 KeyMappingAction getAction( const Context& context, const std::string& actionName );
153
155 std::string getActionName( const Context& context, const KeyMappingAction& action );
156
158 std::string getContextName( const Context& context );
159
161 int addListener( Observable::Observer callback );
162
165 void removeListener( int callbackId );
166
168 std::string getHelpText();
169
172 static std::string enumNamesFromMouseButtons( const Qt::MouseButtons& buttons );
173
176 static std::string enumNamesFromKeyboardModifiers( const Qt::KeyboardModifiers& modifiers );
177
181 static EventBinding createEventBindingFromStrings( const std::string& buttonsString = "",
182 const std::string& modifiersString = "",
183 const std::string& keyString = "",
184 const std::string& wheelString = "" );
185
186 private:
187 KeyMappingManager();
188 ~KeyMappingManager();
189
191 void saveNode( QXmlStreamWriter& stream, const QDomNode& domNode );
192 void saveKeymap( QXmlStreamWriter& stream );
193
194 void loadConfigurationInternal( const QDomDocument& domDocument );
195 void loadConfigurationTagsInternal( QDomElement& node );
196 KeyMappingAction loadConfigurationMappingInternal( const std::string& context,
197 const std::string& keyString,
198 const std::string& modifiersString,
199 const std::string& buttonsString,
200 const std::string& wheelString,
201 const std::string& actionName );
202
206 static Qt::KeyboardModifiers getQtModifiersValue( const std::string& modifierString );
207
211 static Qt::MouseButtons getQtMouseButtonsValue( const std::string& buttonsString );
212 static int getKeyCode( const std::string& keyString );
213
214 std::string m_defaultConfigFile;
215 QFile* m_file;
216
217 using EventBindingMap = std::map<EventBinding, KeyMappingAction>;
218 using ContextNameMap = std::map<std::string, Context>;
220
221 ContextNameMap m_contextNameToIndex;
222 std::vector<ActionNameMap> m_actionNameToIndex;
223 std::vector<EventBindingMap> m_bindingToAction;
224};
225
242template <typename T>
244{
245 public:
246 static inline KeyMappingManager::Context getContext() { return m_keyMappingContext; }
247
251 static inline void configureKeyMapping() { T::configureKeyMapping_impl(); }
252
253 protected:
254 T& self() { return static_cast<T&>( *this ); }
255 static inline void setContext( const KeyMappingManager::Context& c ) {
256 m_keyMappingContext = c;
257 }
258
259 private:
260 static KeyMappingManager::Context m_keyMappingContext;
261};
262
264template <typename T>
265KeyMappingManager::Context KeyMappingManageable<T>::m_keyMappingContext;
266
274{
275 public:
276 using Context = KeyMappingManager::Context;
277 using KeyMappingAction = KeyMappingManager::KeyMappingAction;
278 using Callback = std::function<void( QEvent* )>;
279
283 inline explicit KeyMappingCallbackManager( Context context );
284
288 inline void addEventCallback( KeyMappingAction action, Callback callback );
289
295 addActionAndCallback( const std::string& actionName,
296 const KeyMappingManager::EventBinding& binding,
297 Callback callback );
298
302 inline bool triggerEventCallback( QEvent* event, int key, bool wheel = false );
303
307 inline bool triggerEventCallback( KeyMappingAction action, QEvent* event );
308
309 private:
310 std::map<KeyMappingAction, Callback> m_keymappingCallbacks;
311 Context m_context;
312};
313
314/******************************************************************************/
315/* inlines ********************************************************************/
316/******************************************************************************/
317
318inline bool KeyMappingManager::EventBinding::operator<( const EventBinding& b ) const {
319 return ( m_buttons < b.m_buttons ) ||
320 ( ( m_buttons == b.m_buttons ) && ( m_modifiers < b.m_modifiers ) ) ||
321 ( ( m_buttons == b.m_buttons ) && ( m_modifiers == b.m_modifiers ) &&
322 ( m_key < b.m_key ) ) ||
323 ( ( m_buttons == b.m_buttons ) && ( m_modifiers == b.m_modifiers ) &&
324 ( m_key == b.m_key ) && ( m_wheel < b.m_wheel ) );
325}
326
328 m_context { context } {}
329
330inline void KeyMappingCallbackManager::addEventCallback( KeyMappingAction action,
331 Callback callback ) {
332 m_keymappingCallbacks[action] = callback;
333}
334
337 const KeyMappingManager::EventBinding& binding,
338 Callback callback ) {
339
340 auto mgr = KeyMappingManager::getInstance();
341 auto action = mgr->addAction( m_context, binding, actionName );
342 addEventCallback( action, callback );
343 return action;
344}
345
346inline bool KeyMappingCallbackManager::triggerEventCallback( KeyMappingAction actionIndex,
347 QEvent* event ) {
348 auto itr = m_keymappingCallbacks.find( actionIndex );
349 if ( itr == m_keymappingCallbacks.end() ) return false;
350 itr->second( event );
351 return true;
352}
353
354inline bool KeyMappingCallbackManager::triggerEventCallback( QEvent* event, int key, bool wheel ) {
355 auto mgr = KeyMappingManager::getInstance();
356 auto actionIndex = mgr->getAction( m_context, event, key, wheel );
357 return triggerEventCallback( actionIndex, event );
358}
359
360} // namespace Gui
361} // namespace Ra
This class manage a collection of binding/callback associated with a context.
bool triggerEventCallback(QEvent *event, int key, bool wheel=false)
void addEventCallback(KeyMappingAction action, Callback callback)
KeyMappingManager::KeyMappingAction addActionAndCallback(const std::string &actionName, const KeyMappingManager::EventBinding &binding, Callback callback)
KeyMappingManageable decorator to use as CRTP.
Inner class to store event binding.
EventBinding(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, int key, bool wheel=false)
EventBinding(bool wheel, Qt::KeyboardModifiers modifiers=Qt::NoModifier)
EventBinding(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers=Qt::NoModifier)
EventBinding(int key, Qt::KeyboardModifiers modifiers=Qt::NoModifier)
An utility class used to map a (combination of) key / modifiers / mouse buttons to a specific action....
Ra::Core::Utils::Index KeyMappingAction
handle to an action
Ra::Core::Utils::Index Context
handle to a Context
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:4