all repos — mgba @ 609d5314ec8090c5ede27cb07d0d1569463a570a

mGBA Game Boy Advance Emulator

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}