Qt: Begin refactoring shortcut controller
jump to
@@ -83,6 +83,8 @@ GamepadButtonEvent.cpp
GamepadHatEvent.cpp IOViewer.cpp InputController.cpp + InputItem.cpp + InputModel.cpp InputProfile.cpp KeyEditor.cpp LoadSaveState.cpp@@ -100,7 +102,6 @@ SavestateButton.cpp
SensorView.cpp SettingsView.cpp ShaderSelector.cpp - ShortcutController.cpp ShortcutView.cpp Swatch.cpp TilePainter.cpp
@@ -0,0 +1,81 @@
+/* Copyright (c) 2013-2017 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "InputItem.h" + +#include <QMenu> + +using namespace QGBA; + +InputItem::InputItem(QAction* action, const QString& name, InputItem* parent) + : m_action(action) + , m_shortcut(action->shortcut().isEmpty() ? 0 : action->shortcut()[0]) + , m_menu(nullptr) + , m_name(name) + , m_button(-1) + , m_axis(-1) + , m_direction(GamepadAxisEvent::NEUTRAL) + , m_parent(parent) +{ + m_visibleName = action->text() + .remove(QRegExp("&(?!&)")) + .remove("..."); +} + +InputItem::InputItem(InputItem::Functions functions, int shortcut, const QString& visibleName, const QString& name, InputItem* parent) + : m_action(nullptr) + , m_shortcut(shortcut) + , m_functions(functions) + , m_menu(nullptr) + , m_name(name) + , m_visibleName(visibleName) + , m_button(-1) + , m_axis(-1) + , m_direction(GamepadAxisEvent::NEUTRAL) + , m_parent(parent) +{ +} + +InputItem::InputItem(QMenu* menu, InputItem* parent) + : m_action(nullptr) + , m_shortcut(0) + , m_menu(menu) + , m_button(-1) + , m_axis(-1) + , m_direction(GamepadAxisEvent::NEUTRAL) + , m_parent(parent) +{ + if (menu) { + m_visibleName = menu->title() + .remove(QRegExp("&(?!&)")) + .remove("..."); + } +} + +void InputItem::addAction(QAction* action, const QString& name) { + m_items.append(InputItem(action, name, this)); +} + +void InputItem::addFunctions(InputItem::Functions functions, + int shortcut, const QString& visibleName, + const QString& name) { + m_items.append(InputItem(functions, shortcut, visibleName, name, this)); +} + +void InputItem::addSubmenu(QMenu* menu) { + m_items.append(InputItem(menu, this)); +} + +void InputItem::setShortcut(int shortcut) { + m_shortcut = shortcut; + if (m_action) { + m_action->setShortcut(QKeySequence(shortcut)); + } +} + +void InputItem::setAxis(int axis, GamepadAxisEvent::Direction direction) { + m_axis = axis; + m_direction = direction; +}
@@ -0,0 +1,67 @@
+/* Copyright (c) 2013-2017 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef QGBA_INPUT_ITEM +#define QGBA_INPUT_ITEM + +#include "GamepadAxisEvent.h" + +#include <QAction> + +namespace QGBA { + +class InputItem { +public: + typedef QPair<std::function<void ()>, std::function<void ()>> Functions; + + InputItem(QAction* action, const QString& name, InputItem* parent = nullptr); + InputItem(Functions functions, int shortcut, const QString& visibleName, + const QString& name, InputItem* parent = nullptr); + InputItem(QMenu* action, InputItem* parent = nullptr); + + QAction* action() { return m_action; } + const QAction* action() const { return m_action; } + const int shortcut() const { return m_shortcut; } + Functions functions() const { return m_functions; } + QMenu* menu() { return m_menu; } + const QMenu* menu() const { return m_menu; } + const QString& visibleName() const { return m_visibleName; } + const QString& name() const { return m_name; } + QList<InputItem>& items() { return m_items; } + const QList<InputItem>& items() const { return m_items; } + InputItem* parent() { return m_parent; } + const InputItem* parent() const { return m_parent; } + void addAction(QAction* action, const QString& name); + void addFunctions(Functions functions, int shortcut, const QString& visibleName, + const QString& name); + void addSubmenu(QMenu* menu); + int button() const { return m_button; } + void setShortcut(int sequence); + void setButton(int button) { m_button = button; } + int axis() const { return m_axis; } + GamepadAxisEvent::Direction direction() const { return m_direction; } + void setAxis(int axis, GamepadAxisEvent::Direction direction); + + bool operator==(const InputItem& other) const { + return m_menu == other.m_menu && m_action == other.m_action; + } + +private: + QAction* m_action; + int m_shortcut; + QMenu* m_menu; + Functions m_functions; + QString m_name; + QString m_visibleName; + int m_button; + int m_axis; + GamepadAxisEvent::Direction m_direction; + QList<InputItem> m_items; + InputItem* m_parent; +}; + +} + +#endif
@@ -0,0 +1,99 @@
+/* Copyright (c) 2013-2017 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef QGBA_INPUT_MODEL +#define QGBA_INPUT_MODEL + +#include "GamepadAxisEvent.h" +#include "InputItem.h" + +#include <QAbstractItemModel> + +#include <functional> + +class QAction; +class QKeyEvent; +class QMenu; +class QString; + +namespace QGBA { + +class ConfigController; +class InputProfile; + +class InputModel : public QAbstractItemModel { +Q_OBJECT + +private: + constexpr static const char* const KEY_SECTION = "shortcutKey"; + constexpr static const char* const BUTTON_SECTION = "shortcutButton"; + constexpr static const char* const AXIS_SECTION = "shortcutAxis"; + constexpr static const char* const BUTTON_PROFILE_SECTION = "shortcutProfileButton."; + constexpr static const char* const AXIS_PROFILE_SECTION = "shortcutProfileAxis."; + +public: + InputModel(QObject* parent = nullptr); + + void setConfigController(ConfigController* controller); + void setProfile(const QString& profile); + + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + virtual QModelIndex index(int row, int column, const QModelIndex& parent) const override; + virtual QModelIndex parent(const QModelIndex& index) const override; + + virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override; + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; + + void addAction(QMenu* menu, QAction* action, const QString& name); + void addFunctions(QMenu* menu, std::function<void()> press, std::function<void()> release, + int shortcut, const QString& visibleName, const QString& name); + void addFunctions(QMenu* menu, std::function<void()> press, std::function<void()> release, + const QKeySequence& shortcut, const QString& visibleName, const QString& name); + void addMenu(QMenu* menu, QMenu* parent = nullptr); + + QAction* getAction(const QString& name); + int shortcutAt(const QModelIndex& index) const; + bool isMenuAt(const QModelIndex& index) const; + + void updateKey(const QModelIndex& index, int keySequence); + void updateButton(const QModelIndex& index, int button); + void updateAxis(const QModelIndex& index, int axis, GamepadAxisEvent::Direction direction); + + void clearKey(const QModelIndex& index); + void clearButton(const QModelIndex& index); + + static int toModifierShortcut(const QString& shortcut); + static bool isModifierKey(int key); + static int toModifierKey(int key); + +public slots: + void loadProfile(const QString& profile); + +protected: + bool eventFilter(QObject*, QEvent*) override; + +private: + InputItem* itemAt(const QModelIndex& index); + const InputItem* itemAt(const QModelIndex& index) const; + bool loadShortcuts(InputItem*); + void loadGamepadShortcuts(InputItem*); + void onSubitems(InputItem*, std::function<void(InputItem*)> func); + void updateKey(InputItem* item, int keySequence); + + InputItem m_rootMenu; + QMap<QMenu*, InputItem*> m_menuMap; + QMap<int, InputItem*> m_buttons; + QMap<QPair<int, GamepadAxisEvent::Direction>, InputItem*> m_axes; + QMap<int, InputItem*> m_heldKeys; + ConfigController* m_config; + QString m_profileName; + const InputProfile* m_profile; +}; + +} + +#endif
@@ -7,7 +7,7 @@ #include "KeyEditor.h"
#include "GamepadAxisEvent.h" #include "GamepadButtonEvent.h" -#include "ShortcutController.h" +#include "InputModel.h" #include <QFontMetrics> #include <QKeyEvent>@@ -103,7 +103,7 @@ m_key = 0;
} m_lastKey.start(KEY_TIME); if (m_key) { - if (ShortcutController::isModifierKey(m_key)) { + if (InputModel::isModifierKey(m_key)) { switch (event->key()) { case Qt::Key_Shift: setValue(Qt::ShiftModifier);@@ -119,7 +119,7 @@ setValue(Qt::MetaModifier);
break; } } - if (ShortcutController::isModifierKey(event->key())) { + if (InputModel::isModifierKey(event->key())) { switch (event->key()) { case Qt::Key_Shift: setValue(m_key | Qt::ShiftModifier);
@@ -18,7 +18,7 @@ #include <mgba/internal/gba/gba.h>
using namespace QGBA; -SettingsView::SettingsView(ConfigController* controller, InputController* inputController, ShortcutController* shortcutController, QWidget* parent) +SettingsView::SettingsView(ConfigController* controller, InputController* inputController, InputModel* inputModel, QWidget* parent) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint) , m_controller(controller) {@@ -164,7 +164,7 @@ }
}); ShortcutView* shortcutView = new ShortcutView(); - shortcutView->setController(shortcutController); + shortcutView->setModel(inputModel); shortcutView->setInputController(inputController); m_ui.stackedWidget->addWidget(shortcutView); m_ui.tabs->addItem(tr("Shortcuts"));
@@ -16,13 +16,13 @@ namespace QGBA {
class ConfigController; class InputController; -class ShortcutController; +class InputModel; class SettingsView : public QDialog { Q_OBJECT public: - SettingsView(ConfigController* controller, InputController* inputController, ShortcutController* shortcutController, QWidget* parent = nullptr); + SettingsView(ConfigController* controller, InputController* inputController, InputModel* inputModel, QWidget* parent = nullptr); signals: void biosLoaded(int platform, const QString&);
@@ -3,7 +3,7 @@ *
* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "ShortcutController.h" +#include "InputModel.h" #include "ConfigController.h" #include "GamepadButtonEvent.h"@@ -15,7 +15,7 @@ #include <QMenu>
using namespace QGBA; -ShortcutController::ShortcutController(QObject* parent) +InputModel::InputModel(QObject* parent) : QAbstractItemModel(parent) , m_rootMenu(nullptr) , m_config(nullptr)@@ -23,16 +23,16 @@ , m_profile(nullptr)
{ } -void ShortcutController::setConfigController(ConfigController* controller) { +void InputModel::setConfigController(ConfigController* controller) { m_config = controller; } -QVariant ShortcutController::data(const QModelIndex& index, int role) const { +QVariant InputModel::data(const QModelIndex& index, int role) const { if (role != Qt::DisplayRole || !index.isValid()) { return QVariant(); } int row = index.row(); - const ShortcutItem* item = static_cast<const ShortcutItem*>(index.internalPointer()); + const InputItem* item = static_cast<const InputItem*>(index.internalPointer()); switch (index.column()) { case 0: return item->visibleName();@@ -57,7 +57,7 @@ }
return QVariant(); } -QVariant ShortcutController::headerData(int section, Qt::Orientation orientation, int role) const { +QVariant InputModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) { return QAbstractItemModel::headerData(section, orientation, role); }@@ -74,49 +74,49 @@ }
return section; } -QModelIndex ShortcutController::index(int row, int column, const QModelIndex& parent) const { - const ShortcutItem* pmenu = &m_rootMenu; +QModelIndex InputModel::index(int row, int column, const QModelIndex& parent) const { + const InputItem* pmenu = &m_rootMenu; if (parent.isValid()) { - pmenu = static_cast<ShortcutItem*>(parent.internalPointer()); + pmenu = static_cast<InputItem*>(parent.internalPointer()); } - return createIndex(row, column, const_cast<ShortcutItem*>(&pmenu->items()[row])); + return createIndex(row, column, const_cast<InputItem*>(&pmenu->items()[row])); } -QModelIndex ShortcutController::parent(const QModelIndex& index) const { +QModelIndex InputModel::parent(const QModelIndex& index) const { if (!index.isValid() || !index.internalPointer()) { return QModelIndex(); } - ShortcutItem* item = static_cast<ShortcutItem*>(index.internalPointer()); + InputItem* item = static_cast<InputItem*>(index.internalPointer()); if (!item->parent() || !item->parent()->parent()) { return QModelIndex(); } return createIndex(item->parent()->parent()->items().indexOf(*item->parent()), 0, item->parent()); } -int ShortcutController::columnCount(const QModelIndex& index) const { +int InputModel::columnCount(const QModelIndex& index) const { return 3; } -int ShortcutController::rowCount(const QModelIndex& index) const { +int InputModel::rowCount(const QModelIndex& index) const { if (!index.isValid()) { return m_rootMenu.items().count(); } - const ShortcutItem* item = static_cast<const ShortcutItem*>(index.internalPointer()); + const InputItem* item = static_cast<const InputItem*>(index.internalPointer()); return item->items().count(); } -void ShortcutController::addAction(QMenu* menu, QAction* action, const QString& name) { - ShortcutItem* smenu = m_menuMap[menu]; +void InputModel::addAction(QMenu* menu, QAction* action, const QString& name) { + InputItem* smenu = m_menuMap[menu]; if (!smenu) { return; } - ShortcutItem* pmenu = smenu->parent(); + InputItem* pmenu = smenu->parent(); int row = pmenu->items().indexOf(*smenu); QModelIndex parent = createIndex(row, 0, smenu); beginInsertRows(parent, smenu->items().count(), smenu->items().count()); smenu->addAction(action, name); endInsertRows(); - ShortcutItem* item = &smenu->items().last(); + InputItem* item = &smenu->items().last(); if (m_config) { loadShortcuts(item); }@@ -124,19 +124,19 @@ emit dataChanged(createIndex(smenu->items().count() - 1, 0, item),
createIndex(smenu->items().count() - 1, 2, item)); } -void ShortcutController::addFunctions(QMenu* menu, std::function<void()> press, std::function<void()> release, +void InputModel::addFunctions(QMenu* menu, std::function<void()> press, std::function<void()> release, int shortcut, const QString& visibleName, const QString& name) { - ShortcutItem* smenu = m_menuMap[menu]; + InputItem* smenu = m_menuMap[menu]; if (!smenu) { return; } - ShortcutItem* pmenu = smenu->parent(); + InputItem* pmenu = smenu->parent(); int row = pmenu->items().indexOf(*smenu); QModelIndex parent = createIndex(row, 0, smenu); beginInsertRows(parent, smenu->items().count(), smenu->items().count()); smenu->addFunctions(qMakePair(press, release), shortcut, visibleName, name); endInsertRows(); - ShortcutItem* item = &smenu->items().last(); + InputItem* item = &smenu->items().last(); bool loadedShortcut = false; if (m_config) { loadedShortcut = loadShortcuts(item);@@ -148,18 +148,18 @@ emit dataChanged(createIndex(smenu->items().count() - 1, 0, item),
createIndex(smenu->items().count() - 1, 2, item)); } -void ShortcutController::addFunctions(QMenu* menu, std::function<void()> press, std::function<void()> release, +void InputModel::addFunctions(QMenu* menu, std::function<void()> press, std::function<void()> release, const QKeySequence& shortcut, const QString& visibleName, const QString& name) { addFunctions(menu, press, release, shortcut[0], visibleName, name); } -void ShortcutController::addMenu(QMenu* menu, QMenu* parentMenu) { - ShortcutItem* smenu = m_menuMap[parentMenu]; +void InputModel::addMenu(QMenu* menu, QMenu* parentMenu) { + InputItem* smenu = m_menuMap[parentMenu]; if (!smenu) { smenu = &m_rootMenu; } QModelIndex parent; - ShortcutItem* pmenu = smenu->parent(); + InputItem* pmenu = smenu->parent(); if (pmenu) { int row = pmenu->items().indexOf(*smenu); parent = createIndex(row, 0, smenu);@@ -167,43 +167,43 @@ }
beginInsertRows(parent, smenu->items().count(), smenu->items().count()); smenu->addSubmenu(menu); endInsertRows(); - ShortcutItem* item = &smenu->items().last(); + InputItem* item = &smenu->items().last(); emit dataChanged(createIndex(smenu->items().count() - 1, 0, item), createIndex(smenu->items().count() - 1, 2, item)); m_menuMap[menu] = item; } -ShortcutController::ShortcutItem* ShortcutController::itemAt(const QModelIndex& index) { +InputItem* InputModel::itemAt(const QModelIndex& index) { if (!index.isValid()) { return nullptr; } - return static_cast<ShortcutItem*>(index.internalPointer()); + return static_cast<InputItem*>(index.internalPointer()); } -const ShortcutController::ShortcutItem* ShortcutController::itemAt(const QModelIndex& index) const { +const InputItem* InputModel::itemAt(const QModelIndex& index) const { if (!index.isValid()) { return nullptr; } - return static_cast<const ShortcutItem*>(index.internalPointer()); + return static_cast<const InputItem*>(index.internalPointer()); } -int ShortcutController::shortcutAt(const QModelIndex& index) const { - const ShortcutItem* item = itemAt(index); +int InputModel::shortcutAt(const QModelIndex& index) const { + const InputItem* item = itemAt(index); if (!item) { return 0; } return item->shortcut(); } -bool ShortcutController::isMenuAt(const QModelIndex& index) const { - const ShortcutItem* item = itemAt(index); +bool InputModel::isMenuAt(const QModelIndex& index) const { + const InputItem* item = itemAt(index); if (!item) { return false; } return item->menu(); } -void ShortcutController::updateKey(const QModelIndex& index, int keySequence) { +void InputModel::updateKey(const QModelIndex& index, int keySequence) { if (!index.isValid()) { return; }@@ -211,7 +211,7 @@ const QModelIndex& parent = index.parent();
if (!parent.isValid()) { return; } - ShortcutItem* item = itemAt(index); + InputItem* item = itemAt(index); updateKey(item, keySequence); if (m_config) { m_config->setQtOption(item->name(), QKeySequence(keySequence).toString(), KEY_SECTION);@@ -220,7 +220,7 @@ emit dataChanged(createIndex(index.row(), 0, index.internalPointer()),
createIndex(index.row(), 2, index.internalPointer())); } -void ShortcutController::updateKey(ShortcutItem* item, int keySequence) { +void InputModel::updateKey(InputItem* item, int keySequence) { int oldShortcut = item->shortcut(); if (item->functions().first) { if (oldShortcut > 0) {@@ -234,7 +234,7 @@
item->setShortcut(keySequence); } -void ShortcutController::updateButton(const QModelIndex& index, int button) { +void InputModel::updateButton(const QModelIndex& index, int button) { if (!index.isValid()) { return; }@@ -242,7 +242,7 @@ const QModelIndex& parent = index.parent();
if (!parent.isValid()) { return; } - ShortcutItem* item = itemAt(index); + InputItem* item = itemAt(index); int oldButton = item->button(); if (oldButton >= 0) { m_buttons.take(oldButton);@@ -262,7 +262,7 @@ emit dataChanged(createIndex(index.row(), 0, index.internalPointer()),
createIndex(index.row(), 2, index.internalPointer())); } -void ShortcutController::updateAxis(const QModelIndex& index, int axis, GamepadAxisEvent::Direction direction) { +void InputModel::updateAxis(const QModelIndex& index, int axis, GamepadAxisEvent::Direction direction) { if (!index.isValid()) { return; }@@ -270,7 +270,7 @@ const QModelIndex& parent = index.parent();
if (!parent.isValid()) { return; } - ShortcutItem* item = itemAt(index); + InputItem* item = itemAt(index); int oldAxis = item->axis(); GamepadAxisEvent::Direction oldDirection = item->direction(); if (oldAxis >= 0) {@@ -298,15 +298,15 @@ emit dataChanged(createIndex(index.row(), 0, index.internalPointer()),
createIndex(index.row(), 2, index.internalPointer())); } -void ShortcutController::clearKey(const QModelIndex& index) { +void InputModel::clearKey(const QModelIndex& index) { updateKey(index, 0); } -void ShortcutController::clearButton(const QModelIndex& index) { +void InputModel::clearButton(const QModelIndex& index) { updateButton(index, -1); } -bool ShortcutController::eventFilter(QObject*, QEvent* event) { +bool InputModel::eventFilter(QObject*, QEvent* event) { if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) { QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); if (keyEvent->isAutoRepeat()) {@@ -320,7 +320,7 @@ key = toModifierKey(key | (keyEvent->modifiers() & ~Qt::KeypadModifier));
} auto item = m_heldKeys.find(key); if (item != m_heldKeys.end()) { - ShortcutItem::Functions pair = item.value()->functions(); + auto pair = item.value()->functions(); if (event->type() == QEvent::KeyPress) { if (pair.first) { pair.first();@@ -343,7 +343,7 @@ QAction* action = item.value()->action();
if (action && action->isEnabled()) { action->trigger(); } - ShortcutItem::Functions pair = item.value()->functions(); + auto pair = item.value()->functions(); if (pair.first) { pair.first(); }@@ -355,7 +355,7 @@ auto item = m_buttons.find(static_cast<GamepadButtonEvent*>(event)->value());
if (item == m_buttons.end()) { return false; } - ShortcutItem::Functions pair = item.value()->functions(); + auto pair = item.value()->functions(); if (pair.second) { pair.second(); }@@ -374,7 +374,7 @@ if (action && action->isEnabled()) {
action->trigger(); } } - ShortcutItem::Functions pair = item.value()->functions(); + auto pair = item.value()->functions(); if (gae->isNew()) { if (pair.first) { pair.first();@@ -390,7 +390,7 @@ }
return false; } -bool ShortcutController::loadShortcuts(ShortcutItem* item) { +bool InputModel::loadShortcuts(InputItem* item) { if (item->name().isNull()) { return false; }@@ -407,7 +407,7 @@ }
return false; } -void ShortcutController::loadGamepadShortcuts(ShortcutItem* item) { +void InputModel::loadGamepadShortcuts(InputItem* item) { if (item->name().isNull()) { return; }@@ -462,22 +462,22 @@ }
} } -void ShortcutController::loadProfile(const QString& profile) { +void InputModel::loadProfile(const QString& profile) { m_profileName = profile; m_profile = InputProfile::findProfile(profile); - onSubitems(&m_rootMenu, [this](ShortcutItem* item) { + onSubitems(&m_rootMenu, [this](InputItem* item) { loadGamepadShortcuts(item); }); } -void ShortcutController::onSubitems(ShortcutItem* item, std::function<void(ShortcutItem*)> func) { - for (ShortcutItem& subitem : item->items()) { +void InputModel::onSubitems(InputItem* item, std::function<void(InputItem*)> func) { + for (InputItem& subitem : item->items()) { func(&subitem); onSubitems(&subitem, func); } } -int ShortcutController::toModifierShortcut(const QString& shortcut) { +int InputModel::toModifierShortcut(const QString& shortcut) { // Qt doesn't seem to work with raw modifier shortcuts! QStringList modifiers = shortcut.split('+'); int value = 0;@@ -502,7 +502,7 @@ }
return value; } -bool ShortcutController::isModifierKey(int key) { +bool InputModel::isModifierKey(int key) { switch (key) { case Qt::Key_Shift: case Qt::Key_Control:@@ -514,7 +514,7 @@ return false;
} } -int ShortcutController::toModifierKey(int key) { +int InputModel::toModifierKey(int key) { int modifiers = key & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier); key ^= modifiers; switch (key) {@@ -536,74 +536,3 @@ }
return modifiers; } - -ShortcutController::ShortcutItem::ShortcutItem(QAction* action, const QString& name, ShortcutItem* parent) - : m_action(action) - , m_shortcut(action->shortcut().isEmpty() ? 0 : action->shortcut()[0]) - , m_menu(nullptr) - , m_name(name) - , m_button(-1) - , m_axis(-1) - , m_direction(GamepadAxisEvent::NEUTRAL) - , m_parent(parent) -{ - m_visibleName = action->text() - .remove(QRegExp("&(?!&)")) - .remove("..."); -} - -ShortcutController::ShortcutItem::ShortcutItem(ShortcutController::ShortcutItem::Functions functions, int shortcut, const QString& visibleName, const QString& name, ShortcutItem* parent) - : m_action(nullptr) - , m_shortcut(shortcut) - , m_functions(functions) - , m_menu(nullptr) - , m_name(name) - , m_visibleName(visibleName) - , m_button(-1) - , m_axis(-1) - , m_direction(GamepadAxisEvent::NEUTRAL) - , m_parent(parent) -{ -} - -ShortcutController::ShortcutItem::ShortcutItem(QMenu* menu, ShortcutItem* parent) - : m_action(nullptr) - , m_shortcut(0) - , m_menu(menu) - , m_button(-1) - , m_axis(-1) - , m_direction(GamepadAxisEvent::NEUTRAL) - , m_parent(parent) -{ - if (menu) { - m_visibleName = menu->title() - .remove(QRegExp("&(?!&)")) - .remove("..."); - } -} - -void ShortcutController::ShortcutItem::addAction(QAction* action, const QString& name) { - m_items.append(ShortcutItem(action, name, this)); -} - -void ShortcutController::ShortcutItem::addFunctions(ShortcutController::ShortcutItem::Functions functions, - int shortcut, const QString& visibleName, - const QString& name) { - m_items.append(ShortcutItem(functions, shortcut, visibleName, name, this)); -} - -void ShortcutController::ShortcutItem::addSubmenu(QMenu* menu) { - m_items.append(ShortcutItem(menu, this)); -} - -void ShortcutController::ShortcutItem::setShortcut(int shortcut) { - m_shortcut = shortcut; - if (m_action) { - m_action->setShortcut(QKeySequence(shortcut)); - } -} - -void ShortcutController::ShortcutItem::setAxis(int axis, GamepadAxisEvent::Direction direction) { - m_axis = axis; - m_direction = direction; -}
@@ -1,148 +0,0 @@
-/* Copyright (c) 2013-2015 Jeffrey Pfau - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef QGBA_SHORTCUT_MODEL -#define QGBA_SHORTCUT_MODEL - -#include "GamepadAxisEvent.h" - -#include <QAbstractItemModel> - -#include <functional> - -class QAction; -class QKeyEvent; -class QMenu; -class QString; - -namespace QGBA { - -class ConfigController; -class InputProfile; - -class ShortcutController : public QAbstractItemModel { -Q_OBJECT - -private: - constexpr static const char* const KEY_SECTION = "shortcutKey"; - constexpr static const char* const BUTTON_SECTION = "shortcutButton"; - constexpr static const char* const AXIS_SECTION = "shortcutAxis"; - constexpr static const char* const BUTTON_PROFILE_SECTION = "shortcutProfileButton."; - constexpr static const char* const AXIS_PROFILE_SECTION = "shortcutProfileAxis."; - - class ShortcutItem { - public: - typedef QPair<std::function<void ()>, std::function<void ()>> Functions; - - ShortcutItem(QAction* action, const QString& name, ShortcutItem* parent = nullptr); - ShortcutItem(Functions functions, int shortcut, const QString& visibleName, const QString& name, - ShortcutItem* parent = nullptr); - ShortcutItem(QMenu* action, ShortcutItem* parent = nullptr); - - QAction* action() { return m_action; } - const QAction* action() const { return m_action; } - const int shortcut() const { return m_shortcut; } - Functions functions() const { return m_functions; } - QMenu* menu() { return m_menu; } - const QMenu* menu() const { return m_menu; } - const QString& visibleName() const { return m_visibleName; } - const QString& name() const { return m_name; } - QList<ShortcutItem>& items() { return m_items; } - const QList<ShortcutItem>& items() const { return m_items; } - ShortcutItem* parent() { return m_parent; } - const ShortcutItem* parent() const { return m_parent; } - void addAction(QAction* action, const QString& name); - void addFunctions(Functions functions, int shortcut, const QString& visibleName, - const QString& name); - void addSubmenu(QMenu* menu); - int button() const { return m_button; } - void setShortcut(int sequence); - void setButton(int button) { m_button = button; } - int axis() const { return m_axis; } - GamepadAxisEvent::Direction direction() const { return m_direction; } - void setAxis(int axis, GamepadAxisEvent::Direction direction); - - bool operator==(const ShortcutItem& other) const { - return m_menu == other.m_menu && m_action == other.m_action; - } - - private: - QAction* m_action; - int m_shortcut; - QMenu* m_menu; - Functions m_functions; - QString m_name; - QString m_visibleName; - int m_button; - int m_axis; - GamepadAxisEvent::Direction m_direction; - QList<ShortcutItem> m_items; - ShortcutItem* m_parent; - }; - -public: - ShortcutController(QObject* parent = nullptr); - - void setConfigController(ConfigController* controller); - void setProfile(const QString& profile); - - virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - virtual QModelIndex index(int row, int column, const QModelIndex& parent) const override; - virtual QModelIndex parent(const QModelIndex& index) const override; - - virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override; - virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; - - void addAction(QMenu* menu, QAction* action, const QString& name); - void addFunctions(QMenu* menu, std::function<void()> press, std::function<void()> release, - int shortcut, const QString& visibleName, const QString& name); - void addFunctions(QMenu* menu, std::function<void()> press, std::function<void()> release, - const QKeySequence& shortcut, const QString& visibleName, const QString& name); - void addMenu(QMenu* menu, QMenu* parent = nullptr); - - QAction* getAction(const QString& name); - int shortcutAt(const QModelIndex& index) const; - bool isMenuAt(const QModelIndex& index) const; - - void updateKey(const QModelIndex& index, int keySequence); - void updateButton(const QModelIndex& index, int button); - void updateAxis(const QModelIndex& index, int axis, GamepadAxisEvent::Direction direction); - - void clearKey(const QModelIndex& index); - void clearButton(const QModelIndex& index); - - static int toModifierShortcut(const QString& shortcut); - static bool isModifierKey(int key); - static int toModifierKey(int key); - -public slots: - void loadProfile(const QString& profile); - -protected: - bool eventFilter(QObject*, QEvent*) override; - -private: - ShortcutItem* itemAt(const QModelIndex& index); - const ShortcutItem* itemAt(const QModelIndex& index) const; - bool loadShortcuts(ShortcutItem*); - void loadGamepadShortcuts(ShortcutItem*); - void onSubitems(ShortcutItem*, std::function<void(ShortcutItem*)> func); - void updateKey(ShortcutItem* item, int keySequence); - - ShortcutItem m_rootMenu; - QMap<QMenu*, ShortcutItem*> m_menuMap; - QMap<int, ShortcutItem*> m_buttons; - QMap<QPair<int, GamepadAxisEvent::Direction>, ShortcutItem*> m_axes; - QMap<int, ShortcutItem*> m_heldKeys; - ConfigController* m_config; - QString m_profileName; - const InputProfile* m_profile; -}; - -} - -#endif
@@ -7,7 +7,7 @@ #include "ShortcutView.h"
#include "GamepadButtonEvent.h" #include "InputController.h" -#include "ShortcutController.h" +#include "InputModel.h" #include <QKeyEvent>@@ -41,9 +41,9 @@ ShortcutView::~ShortcutView() {
m_input->releaseFocus(this); } -void ShortcutView::setController(ShortcutController* controller) { - m_controller = controller; - m_ui.shortcutTable->setModel(controller); +void ShortcutView::setModel(InputModel* model) { + m_controller = model; + m_ui.shortcutTable->setModel(model); } void ShortcutView::setInputController(InputController* controller) {
@@ -15,7 +15,7 @@
namespace QGBA { class InputController; -class ShortcutController; +class InputModel; class ShortcutView : public QWidget { Q_OBJECT@@ -24,7 +24,7 @@ public:
ShortcutView(QWidget* parent = nullptr); ~ShortcutView(); - void setController(ShortcutController* controller); + void setModel(InputModel* controller); void setInputController(InputController* input); protected:@@ -40,7 +40,7 @@
private: Ui::ShortcutView m_ui; - ShortcutController* m_controller; + InputModel* m_controller; InputController* m_input; };
@@ -28,6 +28,7 @@ #include "GBAApp.h"
#include "GDBController.h" #include "GDBWindow.h" #include "GIFView.h" +#include "InputModel.h" #include "IOViewer.h" #include "LoadSaveState.h" #include "LogView.h"@@ -40,7 +41,6 @@ #include "ROMInfo.h"
#include "SensorView.h" #include "SettingsView.h" #include "ShaderSelector.h" -#include "ShortcutController.h" #include "TileView.h" #include "VideoView.h"@@ -81,7 +81,7 @@ #ifdef USE_DEBUGGERS
, m_console(nullptr) #endif , m_mruMenu(nullptr) - , m_shortcutController(new ShortcutController(this)) + , m_inputModel(new InputModel(this)) , m_fullscreenOnStart(false) , m_autoresume(false) , m_wasOpened(false)@@ -194,13 +194,13 @@ });
connect(m_display, &Display::showCursor, [this]() { m_screenWidget->unsetCursor(); }); - connect(&m_inputController, SIGNAL(profileLoaded(const QString&)), m_shortcutController, SLOT(loadProfile(const QString&))); + connect(&m_inputController, SIGNAL(profileLoaded(const QString&)), m_inputModel, SLOT(loadProfile(const QString&))); m_log.setLevels(mLOG_WARN | mLOG_ERROR | mLOG_FATAL); m_fpsTimer.setInterval(FPS_TIMER_INTERVAL); m_focusCheck.setInterval(200); - m_shortcutController->setConfigController(m_config); + m_inputModel->setConfigController(m_config); setupMenu(menuBar()); }@@ -476,7 +476,7 @@ }
} void Window::openSettingsWindow() { - SettingsView* settingsWindow = new SettingsView(m_config, &m_inputController, m_shortcutController); + SettingsView* settingsWindow = new SettingsView(m_config, &m_inputController, m_inputModel); connect(settingsWindow, SIGNAL(biosLoaded(int, const QString&)), m_controller, SLOT(loadBIOS(int, const QString&))); connect(settingsWindow, SIGNAL(audioDriverChanged()), m_controller, SLOT(reloadAudioDriver())); connect(settingsWindow, SIGNAL(displayDriverChanged()), this, SLOT(mustRestart()));@@ -922,8 +922,8 @@
void Window::setupMenu(QMenuBar* menubar) { menubar->clear(); QMenu* fileMenu = menubar->addMenu(tr("&File")); - m_shortcutController->addMenu(fileMenu); - installEventFilter(m_shortcutController); + m_inputModel->addMenu(fileMenu); + installEventFilter(m_inputModel); addControlledAction(fileMenu, fileMenu->addAction(tr("Load &ROM..."), this, SLOT(selectROM()), QKeySequence::Open), "loadROM"); #ifdef USE_SQLITE3@@ -978,8 +978,8 @@ addControlledAction(fileMenu, saveState, "saveState");
QMenu* quickLoadMenu = fileMenu->addMenu(tr("Quick load")); QMenu* quickSaveMenu = fileMenu->addMenu(tr("Quick save")); - m_shortcutController->addMenu(quickLoadMenu); - m_shortcutController->addMenu(quickSaveMenu); + m_inputModel->addMenu(quickLoadMenu); + m_inputModel->addMenu(quickSaveMenu); QAction* quickLoad = new QAction(tr("Load recent"), quickLoadMenu); connect(quickLoad, SIGNAL(triggered()), m_controller, SLOT(loadState()));@@ -1065,7 +1065,7 @@ addControlledAction(fileMenu, fileMenu->addAction(tr("E&xit"), this, SLOT(close()), QKeySequence::Quit), "quit");
#endif QMenu* emulationMenu = menubar->addMenu(tr("&Emulation")); - m_shortcutController->addMenu(emulationMenu); + m_inputModel->addMenu(emulationMenu); QAction* reset = new QAction(tr("&Reset"), emulationMenu); reset->setShortcut(tr("Ctrl+R")); connect(reset, SIGNAL(triggered()), m_controller, SLOT(reset()));@@ -1106,7 +1106,7 @@ addControlledAction(emulationMenu, frameAdvance, "frameAdvance");
emulationMenu->addSeparator(); - m_shortcutController->addFunctions(emulationMenu, [this]() { + m_inputModel->addFunctions(emulationMenu, [this]() { m_controller->setTurbo(true, false); }, [this]() { m_controller->setTurbo(false, false);@@ -1132,7 +1132,7 @@ ffspeed->addValue(tr("%0x").arg(i), i, ffspeedMenu);
} m_config->updateOption("fastForwardRatio"); - m_shortcutController->addFunctions(emulationMenu, [this]() { + m_inputModel->addFunctions(emulationMenu, [this]() { m_controller->startRewinding(); }, [this]() { m_controller->stopRewinding();@@ -1171,7 +1171,7 @@
emulationMenu->addSeparator(); QMenu* solarMenu = emulationMenu->addMenu(tr("Solar sensor")); - m_shortcutController->addMenu(solarMenu); + m_inputModel->addMenu(solarMenu); QAction* solarIncrease = new QAction(tr("Increase solar level"), solarMenu); connect(solarIncrease, SIGNAL(triggered()), m_controller, SLOT(increaseLuminanceLevel())); addControlledAction(solarMenu, solarIncrease, "increaseLuminanceLevel");@@ -1198,9 +1198,9 @@ addControlledAction(solarMenu, setSolar, QString("luminanceLevel.%1").arg(QString::number(i)));
} QMenu* avMenu = menubar->addMenu(tr("Audio/&Video")); - m_shortcutController->addMenu(avMenu); + m_inputModel->addMenu(avMenu); QMenu* frameMenu = avMenu->addMenu(tr("Frame size")); - m_shortcutController->addMenu(frameMenu, avMenu); + m_inputModel->addMenu(frameMenu, avMenu); for (int i = 1; i <= 6; ++i) { QAction* setSize = new QAction(tr("%1x").arg(QString::number(i)), avMenu); setSize->setCheckable(true);@@ -1314,7 +1314,7 @@ #endif
avMenu->addSeparator(); QMenu* videoLayers = avMenu->addMenu(tr("Video layers")); - m_shortcutController->addMenu(videoLayers, avMenu); + m_inputModel->addMenu(videoLayers, avMenu); for (int i = 0; i < 4; ++i) { QAction* enableBg = new QAction(tr("Background %0").arg(i), videoLayers);@@ -1331,7 +1331,7 @@ connect(enableObj, &QAction::triggered, [this](bool enable) { m_controller->setVideoLayerEnabled(4, enable); });
addControlledAction(videoLayers, enableObj, "enableOBJ"); QMenu* audioChannels = avMenu->addMenu(tr("Audio channels")); - m_shortcutController->addMenu(audioChannels, avMenu); + m_inputModel->addMenu(audioChannels, avMenu); for (int i = 0; i < 4; ++i) { QAction* enableCh = new QAction(tr("Channel %0").arg(i + 1), audioChannels);@@ -1354,7 +1354,7 @@ connect(enableChB, &QAction::triggered, [this, i](bool enable) { m_controller->setAudioChannelEnabled(5, enable); });
addControlledAction(audioChannels, enableChB, QString("enableChB")); QMenu* toolsMenu = menubar->addMenu(tr("&Tools")); - m_shortcutController->addMenu(toolsMenu); + m_inputModel->addMenu(toolsMenu); QAction* viewLogs = new QAction(tr("View &logs..."), toolsMenu); connect(viewLogs, SIGNAL(triggered()), m_logView, SLOT(show())); addControlledAction(toolsMenu, viewLogs, "viewLogs");@@ -1481,63 +1481,63 @@ exitFullScreen->setShortcut(QKeySequence("Esc"));
addHiddenAction(frameMenu, exitFullScreen, "exitFullScreen"); QMenu* autofireMenu = new QMenu(tr("Autofire"), this); - m_shortcutController->addMenu(autofireMenu); + m_inputModel->addMenu(autofireMenu); - m_shortcutController->addFunctions(autofireMenu, [this]() { + m_inputModel->addFunctions(autofireMenu, [this]() { m_controller->setAutofire(GBA_KEY_A, true); }, [this]() { m_controller->setAutofire(GBA_KEY_A, false); }, QKeySequence(), tr("Autofire A"), "autofireA"); - m_shortcutController->addFunctions(autofireMenu, [this]() { + m_inputModel->addFunctions(autofireMenu, [this]() { m_controller->setAutofire(GBA_KEY_B, true); }, [this]() { m_controller->setAutofire(GBA_KEY_B, false); }, QKeySequence(), tr("Autofire B"), "autofireB"); - m_shortcutController->addFunctions(autofireMenu, [this]() { + m_inputModel->addFunctions(autofireMenu, [this]() { m_controller->setAutofire(GBA_KEY_L, true); }, [this]() { m_controller->setAutofire(GBA_KEY_L, false); }, QKeySequence(), tr("Autofire L"), "autofireL"); - m_shortcutController->addFunctions(autofireMenu, [this]() { + m_inputModel->addFunctions(autofireMenu, [this]() { m_controller->setAutofire(GBA_KEY_R, true); }, [this]() { m_controller->setAutofire(GBA_KEY_R, false); }, QKeySequence(), tr("Autofire R"), "autofireR"); - m_shortcutController->addFunctions(autofireMenu, [this]() { + m_inputModel->addFunctions(autofireMenu, [this]() { m_controller->setAutofire(GBA_KEY_START, true); }, [this]() { m_controller->setAutofire(GBA_KEY_START, false); }, QKeySequence(), tr("Autofire Start"), "autofireStart"); - m_shortcutController->addFunctions(autofireMenu, [this]() { + m_inputModel->addFunctions(autofireMenu, [this]() { m_controller->setAutofire(GBA_KEY_SELECT, true); }, [this]() { m_controller->setAutofire(GBA_KEY_SELECT, false); }, QKeySequence(), tr("Autofire Select"), "autofireSelect"); - m_shortcutController->addFunctions(autofireMenu, [this]() { + m_inputModel->addFunctions(autofireMenu, [this]() { m_controller->setAutofire(GBA_KEY_UP, true); }, [this]() { m_controller->setAutofire(GBA_KEY_UP, false); }, QKeySequence(), tr("Autofire Up"), "autofireUp"); - m_shortcutController->addFunctions(autofireMenu, [this]() { + m_inputModel->addFunctions(autofireMenu, [this]() { m_controller->setAutofire(GBA_KEY_RIGHT, true); }, [this]() { m_controller->setAutofire(GBA_KEY_RIGHT, false); }, QKeySequence(), tr("Autofire Right"), "autofireRight"); - m_shortcutController->addFunctions(autofireMenu, [this]() { + m_inputModel->addFunctions(autofireMenu, [this]() { m_controller->setAutofire(GBA_KEY_DOWN, true); }, [this]() { m_controller->setAutofire(GBA_KEY_DOWN, false); }, QKeySequence(), tr("Autofire Down"), "autofireDown"); - m_shortcutController->addFunctions(autofireMenu, [this]() { + m_inputModel->addFunctions(autofireMenu, [this]() { m_controller->setAutofire(GBA_KEY_LEFT, true); }, [this]() { m_controller->setAutofire(GBA_KEY_LEFT, false);@@ -1598,7 +1598,7 @@ return action;
} QAction* Window::addHiddenAction(QMenu* menu, QAction* action, const QString& name) { - m_shortcutController->addAction(menu, action, name); + m_inputModel->addAction(menu, action, name); action->setShortcutContext(Qt::WidgetShortcut); addAction(action); return action;
@@ -28,10 +28,10 @@ class Display;
class GameController; class GDBController; class GIFView; +class InputModel; class LibraryView; class LogView; class ShaderSelector; -class ShortcutController; class VideoView; class WindowBackground;@@ -173,7 +173,7 @@ QList<QDateTime> m_frameList;
QTimer m_fpsTimer; QList<QString> m_mruFiles; QMenu* m_mruMenu; - ShortcutController* m_shortcutController; + InputModel* m_inputModel; ShaderSelector* m_shaderView; bool m_fullscreenOnStart; QTimer m_focusCheck;