src/platform/qt/ShortcutController.h (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#ifndef QGBA_SHORTCUT_MODEL
7#define QGBA_SHORTCUT_MODEL
8
9#include "GamepadAxisEvent.h"
10
11#include <QAbstractItemModel>
12#include <QKeySequence>
13
14#include <functional>
15
16class QAction;
17class QKeyEvent;
18class QMenu;
19class QString;
20
21namespace QGBA {
22
23class ConfigController;
24class InputProfile;
25
26class ShortcutController : public QAbstractItemModel {
27Q_OBJECT
28
29private:
30 constexpr static const char* const KEY_SECTION = "shortcutKey";
31 constexpr static const char* const BUTTON_SECTION = "shortcutButton";
32 constexpr static const char* const AXIS_SECTION = "shortcutAxis";
33 constexpr static const char* const BUTTON_PROFILE_SECTION = "shortcutProfileButton.";
34 constexpr static const char* const AXIS_PROFILE_SECTION = "shortcutProfileAxis.";
35
36 class ShortcutItem {
37 public:
38 typedef QPair<std::function<void ()>, std::function<void ()>> Functions;
39
40 ShortcutItem(QAction* action, const QString& name, ShortcutItem* parent = nullptr);
41 ShortcutItem(Functions functions, const QKeySequence& shortcut, const QString& visibleName, const QString& name,
42 ShortcutItem* parent = nullptr);
43 ShortcutItem(QMenu* action, ShortcutItem* parent = nullptr);
44
45 QAction* action() { return m_action; }
46 const QAction* action() const { return m_action; }
47 const QKeySequence& shortcut() const { return m_shortcut; }
48 Functions functions() const { return m_functions; }
49 QMenu* menu() { return m_menu; }
50 const QMenu* menu() const { return m_menu; }
51 const QString& visibleName() const { return m_visibleName; }
52 const QString& name() const { return m_name; }
53 QList<ShortcutItem>& items() { return m_items; }
54 const QList<ShortcutItem>& items() const { return m_items; }
55 ShortcutItem* parent() { return m_parent; }
56 const ShortcutItem* parent() const { return m_parent; }
57 void addAction(QAction* action, const QString& name);
58 void addFunctions(Functions functions, const QKeySequence& shortcut, const QString& visibleName,
59 const QString& name);
60 void addSubmenu(QMenu* menu);
61 int button() const { return m_button; }
62 void setShortcut(const QKeySequence& sequence);
63 void setButton(int button) { m_button = button; }
64 int axis() const { return m_axis; }
65 GamepadAxisEvent::Direction direction() const { return m_direction; }
66 void setAxis(int axis, GamepadAxisEvent::Direction direction);
67
68 bool operator==(const ShortcutItem& other) const {
69 return m_menu == other.m_menu && m_action == other.m_action;
70 }
71
72 private:
73 QAction* m_action;
74 QKeySequence m_shortcut;
75 QMenu* m_menu;
76 Functions m_functions;
77 QString m_name;
78 QString m_visibleName;
79 int m_button;
80 int m_axis;
81 GamepadAxisEvent::Direction m_direction;
82 QList<ShortcutItem> m_items;
83 ShortcutItem* m_parent;
84 };
85
86public:
87 ShortcutController(QObject* parent = nullptr);
88
89 void setConfigController(ConfigController* controller);
90 void setProfile(const QString& profile);
91
92 virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
93 virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
94
95 virtual QModelIndex index(int row, int column, const QModelIndex& parent) const override;
96 virtual QModelIndex parent(const QModelIndex& index) const override;
97
98 virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override;
99 virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
100
101 void addAction(QMenu* menu, QAction* action, const QString& name);
102 void addFunctions(QMenu* menu, std::function<void()> press, std::function<void()> release,
103 const QKeySequence& shortcut, const QString& visibleName, const QString& name);
104 void addMenu(QMenu* menu, QMenu* parent = nullptr);
105
106 QKeySequence shortcutAt(const QModelIndex& index) const;
107 bool isMenuAt(const QModelIndex& index) const;
108
109 void updateKey(const QModelIndex& index, const QKeySequence& keySequence);
110 void updateButton(const QModelIndex& index, int button);
111 void updateAxis(const QModelIndex& index, int axis, GamepadAxisEvent::Direction direction);
112
113 void clearKey(const QModelIndex& index);
114 void clearButton(const QModelIndex& index);
115
116 static QKeySequence keyEventToSequence(const QKeyEvent*);
117
118public slots:
119 void loadProfile(const QString& profile);
120
121protected:
122 bool eventFilter(QObject*, QEvent*) override;
123
124private:
125 ShortcutItem* itemAt(const QModelIndex& index);
126 const ShortcutItem* itemAt(const QModelIndex& index) const;
127 void loadShortcuts(ShortcutItem*);
128 void loadGamepadShortcuts(ShortcutItem*);
129 void onSubitems(ShortcutItem*, std::function<void(ShortcutItem*)> func);
130
131 ShortcutItem m_rootMenu;
132 QMap<QMenu*, ShortcutItem*> m_menuMap;
133 QMap<int, ShortcutItem*> m_buttons;
134 QMap<QPair<int, GamepadAxisEvent::Direction>, ShortcutItem*> m_axes;
135 QMap<QKeySequence, ShortcutItem*> m_heldKeys;
136 ConfigController* m_config;
137 QString m_profileName;
138 const InputProfile* m_profile;
139};
140
141}
142
143#endif