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#pragma once
7
8#include "GamepadAxisEvent.h"
9
10#include <QAbstractItemModel>
11
12#include <functional>
13
14class QAction;
15class QKeyEvent;
16class QMenu;
17class QString;
18
19namespace QGBA {
20
21class ConfigController;
22class InputProfile;
23
24class ShortcutController : public QAbstractItemModel {
25Q_OBJECT
26
27private:
28 constexpr static const char* const KEY_SECTION = "shortcutKey";
29 constexpr static const char* const BUTTON_SECTION = "shortcutButton";
30 constexpr static const char* const AXIS_SECTION = "shortcutAxis";
31 constexpr static const char* const BUTTON_PROFILE_SECTION = "shortcutProfileButton.";
32 constexpr static const char* const AXIS_PROFILE_SECTION = "shortcutProfileAxis.";
33
34 class ShortcutItem {
35 public:
36 typedef QPair<std::function<void ()>, std::function<void ()>> Functions;
37
38 ShortcutItem(QAction* action, const QString& name, ShortcutItem* parent = nullptr);
39 ShortcutItem(Functions functions, int shortcut, const QString& visibleName, const QString& name,
40 ShortcutItem* parent = nullptr);
41 ShortcutItem(QMenu* action, ShortcutItem* parent = nullptr);
42
43 QAction* action() { return m_action; }
44 const QAction* action() const { return m_action; }
45 const int shortcut() const { return m_shortcut; }
46 Functions functions() const { return m_functions; }
47 QMenu* menu() { return m_menu; }
48 const QMenu* menu() const { return m_menu; }
49 const QString& visibleName() const { return m_visibleName; }
50 const QString& name() const { return m_name; }
51 QList<ShortcutItem>& items() { return m_items; }
52 const QList<ShortcutItem>& items() const { return m_items; }
53 ShortcutItem* parent() { return m_parent; }
54 const ShortcutItem* parent() const { return m_parent; }
55 void addAction(QAction* action, const QString& name);
56 void addFunctions(Functions functions, int shortcut, const QString& visibleName,
57 const QString& name);
58 void addSubmenu(QMenu* menu);
59 int button() const { return m_button; }
60 void setShortcut(int sequence);
61 void setButton(int button) { m_button = button; }
62 int axis() const { return m_axis; }
63 GamepadAxisEvent::Direction direction() const { return m_direction; }
64 void setAxis(int axis, GamepadAxisEvent::Direction direction);
65
66 bool operator==(const ShortcutItem& other) const {
67 return m_menu == other.m_menu && m_action == other.m_action;
68 }
69
70 private:
71 QAction* m_action = nullptr;
72 int m_shortcut = 0;
73 QMenu* m_menu = nullptr;
74 Functions m_functions;
75 QString m_name;
76 QString m_visibleName;
77 int m_button = -1;
78 int m_axis = -1;
79 GamepadAxisEvent::Direction m_direction;
80 QList<ShortcutItem> m_items;
81 ShortcutItem* m_parent;
82 };
83
84public:
85 ShortcutController(QObject* parent = nullptr);
86
87 void setConfigController(ConfigController* controller);
88 void setProfile(const QString& profile);
89
90 virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
91 virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
92
93 virtual QModelIndex index(int row, int column, const QModelIndex& parent) const override;
94 virtual QModelIndex parent(const QModelIndex& index) const override;
95
96 virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override;
97 virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
98
99 void addAction(QMenu* menu, QAction* action, const QString& name);
100 void addFunctions(QMenu* menu, std::function<void()> press, std::function<void()> release,
101 int shortcut, const QString& visibleName, 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 QAction* getAction(const QString& name);
107 int shortcutAt(const QModelIndex& index) const;
108 bool isMenuAt(const QModelIndex& index) const;
109
110 void updateKey(const QModelIndex& index, int keySequence);
111 void updateButton(const QModelIndex& index, int button);
112 void updateAxis(const QModelIndex& index, int axis, GamepadAxisEvent::Direction direction);
113
114 void clearKey(const QModelIndex& index);
115 void clearButton(const QModelIndex& index);
116
117 static int toModifierShortcut(const QString& shortcut);
118 static bool isModifierKey(int key);
119 static int toModifierKey(int key);
120
121public slots:
122 void loadProfile(const QString& profile);
123
124protected:
125 bool eventFilter(QObject*, QEvent*) override;
126
127private:
128 ShortcutItem* itemAt(const QModelIndex& index);
129 const ShortcutItem* itemAt(const QModelIndex& index) const;
130 bool loadShortcuts(ShortcutItem*);
131 void loadGamepadShortcuts(ShortcutItem*);
132 void onSubitems(ShortcutItem*, std::function<void(ShortcutItem*)> func);
133 void updateKey(ShortcutItem* item, int keySequence);
134
135 ShortcutItem m_rootMenu{nullptr};
136 QMap<QMenu*, ShortcutItem*> m_menuMap;
137 QMap<int, ShortcutItem*> m_buttons;
138 QMap<QPair<int, GamepadAxisEvent::Direction>, ShortcutItem*> m_axes;
139 QMap<int, ShortcutItem*> m_heldKeys;
140 ConfigController* m_config = nullptr;
141 QString m_profileName;
142 const InputProfile* m_profile = nullptr;
143};
144
145}