Qt: Remove tree structure from InputItem

This commit is contained in:
Vicki Pfau 2017-06-27 20:18:37 -07:00
parent 96fcf9d267
commit 94b756ca9b
11 changed files with 204 additions and 241 deletions

View File

@ -87,7 +87,7 @@ InputController::~InputController() {
#endif
}
void InputController::rebuildIndex(const InputItem* index) {
void InputController::rebuildIndex(const InputIndex* index) {
m_inputIndex.rebuild(index);
rebindKey(GBA_KEY_A);

View File

@ -46,7 +46,7 @@ public:
~InputController();
InputIndex* inputIndex() { return &m_inputIndex; }
void rebuildIndex(const InputItem* = nullptr);
void rebuildIndex(const InputIndex* = nullptr);
void setConfiguration(ConfigController* config);
void saveConfiguration();

View File

@ -18,36 +18,31 @@ void InputIndex::clone(InputIndex* root, bool actions) {
if (!actions) {
clone(const_cast<const InputIndex*>(root));
} else {
m_root.clear();
onSubitems(root->root(), [this](InputItem* item, InputItem* parent, QVariant accum) -> QVariant {
InputItem* newParent = qvariant_cast<InputItem*>(accum);
InputItem* newItem = newParent->addItem(*item);
qDeleteAll(m_items);
m_items.clear();
for (auto& item : root->m_items) {
InputItem* newItem = new InputItem(*item);
m_items.append(newItem);
itemAdded(newItem);
return QVariant::fromValue(newItem);
}, QVariant::fromValue(&m_root));
}
}
rebuild();
}
void InputIndex::clone(const InputIndex* root) {
m_root.clear();
onSubitems(root->root(), [this](const InputItem* item, const InputItem* parent, QVariant accum) -> QVariant {
InputItem* newParent = qvariant_cast<InputItem*>(accum);
InputItem* newItem = newParent->addItem(*item);
qDeleteAll(m_items);
m_items.clear();
for (auto& item : root->m_items) {
InputItem* newItem = new InputItem(*item);
m_items.append(newItem);
itemAdded(newItem);
return QVariant::fromValue(newItem);
}, QVariant::fromValue(&m_root));
}
rebuild();
}
void InputIndex::rebuild(const InputIndex* root) {
rebuild(root->root());
}
void InputIndex::rebuild(const InputItem* root) {
const InputItem* sourceRoot;
if (!root) {
sourceRoot = &m_root;
} else {
sourceRoot = root;
root = this;
}
m_names.clear();
@ -56,10 +51,9 @@ void InputIndex::rebuild(const InputItem* root) {
m_buttons.clear();
m_axes.clear();
onSubitems(sourceRoot, [this](const InputItem* item, const InputItem* parent, QVariant accum) -> QVariant {
InputItem* newParent = qvariant_cast<InputItem*>(accum);
for (auto& item : root->m_items) {
InputItem* newItem = nullptr;
for (auto iter : newParent->items()) {
for (auto &iter : m_items) {
if (*iter == *item) {
newItem = iter;
break;
@ -70,8 +64,7 @@ void InputIndex::rebuild(const InputItem* root) {
newItem->setAxis(item->axis(), item->direction());
itemAdded(newItem);
return QVariant::fromValue(newItem);
}, QVariant::fromValue(&m_root));
}
}
InputItem* InputIndex::itemAt(const QString& name) {
@ -244,32 +237,11 @@ int InputIndex::toModifierKey(int key) {
return modifiers;
}
void InputIndex::onSubitems(InputItem* item, std::function<void(InputItem*)> func) {
for (InputItem* subitem : item->items()) {
func(subitem);
onSubitems(subitem, func);
}
}
void InputIndex::onSubitems(InputItem* item, std::function<QVariant(InputItem*, InputItem*, QVariant)> func, QVariant accum) {
for (InputItem* subitem : item->items()) {
QVariant newAccum = func(subitem, item, accum);
onSubitems(subitem, func, newAccum);
}
}
void InputIndex::onSubitems(const InputItem* item, std::function<QVariant(const InputItem*, const InputItem*, QVariant)> func, QVariant accum) {
for (const InputItem* subitem : item->items()) {
QVariant newAccum = func(subitem, item, accum);
onSubitems(subitem, func, newAccum);
}
}
void InputIndex::loadProfile(const QString& profile) {
m_profileName = profile;
m_profile = InputProfile::findProfile(profile);
onSubitems(&m_root, [this](InputItem* item) {
for (auto& item : m_items) {
loadGamepadShortcuts(item);
});
}
}

View File

@ -32,11 +32,13 @@ public:
void clone(InputIndex* root, bool actions = false);
void clone(const InputIndex* root);
void rebuild(const InputIndex* root);
void rebuild(const InputItem* root = nullptr);
void rebuild(const InputIndex* root = nullptr);
const QList<InputItem*>& items() const { return m_items; }
template<typename... Args> InputItem* addItem(Args... params) {
InputItem* newItem = m_root.addItem(params...);
InputItem* newItem = new InputItem(params...);
m_items.append(newItem);
itemAdded(newItem);
return newItem;
}
@ -55,21 +57,15 @@ public:
static bool isModifierKey(int key);
static int toModifierKey(int key);
InputItem* root() { return &m_root; }
const InputItem* root() const { return &m_root; }
void loadProfile(const QString& profile);
private:
bool loadShortcuts(InputItem*);
void loadGamepadShortcuts(InputItem*);
void onSubitems(InputItem*, std::function<void(InputItem*)> func);
void onSubitems(InputItem*, std::function<QVariant(InputItem*, InputItem* parent, QVariant accum)> func, QVariant accum = QVariant());
void onSubitems(const InputItem*, std::function<QVariant(const InputItem*, const InputItem* parent, QVariant accum)> func, QVariant accum = QVariant());
void itemAdded(InputItem*);
InputItem m_root;
QList<InputItem*> m_items;
QMap<QString, InputItem*> m_names;
QMap<const QMenu*, InputItem*> m_menus;

View File

@ -10,86 +10,71 @@
using namespace QGBA;
InputItem::InputItem()
: QObject(nullptr)
, m_parent(nullptr)
{
}
InputItem::InputItem(QAction* action, const QString& name, InputItem* parent)
InputItem::InputItem(QAction* action, const QString& name, QMenu* parent)
: QObject(parent)
, m_action(action)
, m_shortcut(action->shortcut().isEmpty() ? 0 : action->shortcut()[0])
, m_name(name)
, m_parent(parent)
, m_menu(parent)
{
m_visibleName = action->text()
.remove(QRegExp("&(?!&)"))
.remove("...");
}
InputItem::InputItem(QMenu* menu, const QString& name, InputItem* parent)
: QObject(parent)
, m_menu(menu)
, m_name(name)
, m_parent(parent)
{
m_visibleName = menu->title()
.remove(QRegExp("&(?!&)"))
.remove("...");
}
InputItem::InputItem(InputItem::Functions functions, const QString& visibleName, const QString& name, InputItem* parent)
InputItem::InputItem(InputItem::Functions functions, const QString& visibleName, const QString& name, QMenu* parent)
: QObject(parent)
, m_functions(functions)
, m_name(name)
, m_visibleName(visibleName)
, m_parent(parent)
, m_menu(parent)
{
}
InputItem::InputItem(int key, const QString& visibleName, const QString& name, InputItem* parent)
InputItem::InputItem(int key, const QString& visibleName, const QString& name, QMenu* parent)
: QObject(parent)
, m_key(key)
, m_name(name)
, m_visibleName(visibleName)
, m_parent(parent)
, m_menu(parent)
{
}
InputItem::InputItem(const QString& visibleName, const QString& name, InputItem* parent)
InputItem::InputItem(const QString& visibleName, const QString& name, QMenu* parent)
: QObject(parent)
, m_name(name)
, m_visibleName(visibleName)
, m_parent(parent)
, m_menu(parent)
{
}
InputItem::InputItem(const InputItem& other, InputItem* parent)
: QObject(parent)
, m_menu(other.m_menu)
InputItem::InputItem(const InputItem& other)
: QObject(other.m_menu)
, m_name(other.m_name)
, m_visibleName(other.m_visibleName)
, m_shortcut(other.m_shortcut)
, m_button(other.m_button)
, m_axis(other.m_axis)
, m_direction(other.m_direction)
, m_parent(parent)
, m_menu(other.m_menu)
{
}
InputItem::InputItem(InputItem& other, InputItem* parent)
: QObject(parent)
InputItem::InputItem(InputItem& other)
: QObject(other.m_menu)
, m_action(other.m_action)
, m_functions(other.m_functions)
, m_key(other.m_key)
, m_menu(other.m_menu)
, m_name(other.m_name)
, m_visibleName(other.m_visibleName)
, m_shortcut(other.m_shortcut)
, m_button(other.m_button)
, m_axis(other.m_axis)
, m_direction(other.m_direction)
, m_parent(parent)
, m_menu(other.m_menu)
{
}
@ -120,11 +105,6 @@ void InputItem::setAxis(int axis, GamepadAxisEvent::Direction direction) {
emit axisBound(this, axis, direction);
}
void InputItem::clear() {
qDeleteAll(m_items);
m_items.clear();
}
void InputItem::trigger(bool active) {
if (active) {
if (m_functions.first) {

View File

@ -18,42 +18,30 @@ namespace QGBA {
class InputItem : public QObject {
Q_OBJECT
private:
public:
typedef QPair<std::function<void ()>, std::function<void ()>> Functions;
InputItem(QAction* action, const QString& name, InputItem* parent = nullptr);
InputItem(QMenu* menu, const QString& name, InputItem* parent = nullptr);
InputItem(QAction* action, const QString& name, QMenu* parent = nullptr);
InputItem(Functions functions, const QString& visibleName, const QString& name,
InputItem* parent = nullptr);
InputItem(int key, const QString& name, const QString& visibleName, InputItem* parent = nullptr);
InputItem(const QString& visibleName, const QString& name, InputItem* parent = nullptr);
QMenu* parent = nullptr);
InputItem(int key, const QString& name, const QString& visibleName, QMenu* parent = nullptr);
InputItem(const QString& visibleName, const QString& name, QMenu* parent = nullptr);
public:
InputItem();
InputItem(InputItem&, InputItem* parent = nullptr);
InputItem(const InputItem&, InputItem* parent = nullptr);
InputItem(InputItem&);
InputItem(const InputItem&);
QAction* action() { return m_action; }
const QAction* action() const { return m_action; }
QMenu* menu() { return m_menu; }
const QMenu* menu() const { return m_menu; }
Functions functions() const { return m_functions; }
int key() const { return m_key; }
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; }
template<typename... Args> InputItem* addItem(Args... params) {
InputItem* item = new InputItem(params..., this);
m_items.append(item);
emit childAdded(this, item);
return item;
}
int shortcut() const { return m_shortcut; }
void setShortcut(int sequence);
void clearShortcut();
@ -66,8 +54,6 @@ public:
GamepadAxisEvent::Direction direction() const { return m_direction; }
void setAxis(int axis, GamepadAxisEvent::Direction direction);
void clear();
bool operator==(const InputItem& other) const {
return m_name == other.m_name;
}
@ -94,8 +80,6 @@ private:
int m_button = -1;
int m_axis = -1;
GamepadAxisEvent::Direction m_direction = GamepadAxisEvent::NEUTRAL;
QList<InputItem*> m_items;
InputItem* m_parent;
};
}

View File

@ -14,10 +14,22 @@
using namespace QGBA;
QString InputModel::InputModelItem::visibleName() const {
if (item) {
return item->visibleName();
}
if (menu) {
return menu->title()
.remove(QRegExp("&(?!&)"))
.remove("...");
}
return QString();
}
InputModel::InputModel(const InputIndex& index, QObject* parent)
: QAbstractItemModel(parent)
{
m_root.clone(&index);
clone(index);
}
InputModel::InputModel(QObject* parent)
@ -27,7 +39,28 @@ InputModel::InputModel(QObject* parent)
void InputModel::clone(const InputIndex& index) {
emit beginResetModel();
m_root.clone(&index);
m_index.clone(&index);
m_menus.clear();
m_topLevelMenus.clear();
QList<const QMenu*> menus;
for (auto& item : m_index.items()) {
const QMenu* menu = item->menu();
if (!menus.contains(menu)) {
menus.append(menu);
m_menus.insert(menu);
}
}
for (auto& menu : menus) {
if (m_menus.contains(menu->parent())) {
m_tree[menu->parent()].append(menu);
} else {
m_topLevelMenus.append(menu);
}
}
for (auto& item : m_index.items()) {
const QMenu* menu = item->menu();
m_tree[menu].append(item);
}
emit endResetModel();
}
@ -36,25 +69,31 @@ QVariant InputModel::data(const QModelIndex& index, int role) const {
return QVariant();
}
int row = index.row();
const InputItem* item = static_cast<const InputItem*>(index.internalPointer());
const InputModelItem* item = static_cast<const InputModelItem*>(index.internalPointer());
switch (index.column()) {
case 0:
return item->visibleName();
case 1:
return QKeySequence(item->shortcut()).toString(QKeySequence::NativeText);
case 2:
if (item->button() >= 0) {
return item->button();
if (item->item) {
return QKeySequence(item->item->shortcut()).toString(QKeySequence::NativeText);
}
if (item->axis() >= 0) {
break;
case 2:
if (!item->item) {
break;
}
if (item->item->button() >= 0) {
return item->item->button();
}
if (item->item->axis() >= 0) {
char d = '\0';
if (item->direction() == GamepadAxisEvent::POSITIVE) {
if (item->item->direction() == GamepadAxisEvent::POSITIVE) {
d = '+';
}
if (item->direction() == GamepadAxisEvent::NEGATIVE) {
if (item->item->direction() == GamepadAxisEvent::NEGATIVE) {
d = '-';
}
return QString("%1%2").arg(d).arg(item->axis());
return QString("%1%2").arg(d).arg(item->item->axis());
}
break;
}
@ -79,26 +118,39 @@ QVariant InputModel::headerData(int section, Qt::Orientation orientation, int ro
}
QModelIndex InputModel::index(int row, int column, const QModelIndex& parent) const {
const InputItem* pmenu = m_root.root();
if (parent.isValid()) {
pmenu = static_cast<InputItem*>(parent.internalPointer());
InputModelItem* p = static_cast<InputModelItem*>(parent.internalPointer());
return createIndex(row, column, const_cast<InputModelItem*>(&m_tree[p->obj][row]));
}
return createIndex(row, column, const_cast<InputItem*>(pmenu->items()[row]));
return createIndex(row, column, const_cast<InputModelItem*>(&m_topLevelMenus[row]));
}
QModelIndex InputModel::parent(const QModelIndex& index) const {
if (!index.isValid() || !index.internalPointer()) {
return QModelIndex();
}
InputItem* item = static_cast<InputItem*>(index.internalPointer());
return this->index(item->parent());
const QObject* obj = static_cast<const InputModelItem*>(index.internalPointer())->obj;
if (m_menus.contains(obj->parent())) {
return this->index(obj->parent());
} else {
return QModelIndex();
}
}
QModelIndex InputModel::index(InputItem* item, int row) const {
QModelIndex InputModel::index(const QObject* item, int column) const {
if (!item || !item->parent()) {
return QModelIndex();
}
return createIndex(item->parent()->items().indexOf(item), row, item);
const QObject* parent = item->parent();
if (m_tree.contains(parent)) {
int index = m_tree[parent].indexOf(item);
return createIndex(index, column, const_cast<InputModelItem*>(&m_tree[parent][index]));
}
if (m_topLevelMenus.contains(item)) {
int index = m_topLevelMenus.indexOf(item);
return createIndex(index, column, const_cast<InputModelItem*>(&m_topLevelMenus[index]));
}
return QModelIndex();
}
int InputModel::columnCount(const QModelIndex& index) const {
@ -106,37 +158,27 @@ int InputModel::columnCount(const QModelIndex& index) const {
}
int InputModel::rowCount(const QModelIndex& index) const {
if (!index.isValid()) {
return m_root.root()->items().count();
if (!index.isValid() || !index.internalPointer()) {
return m_topLevelMenus.count();
}
const InputItem* item = static_cast<const InputItem*>(index.internalPointer());
return item->items().count();
const QObject* obj = static_cast<const InputModelItem*>(index.internalPointer())->obj;
if (!m_tree.contains(obj)) {
return 0;
}
return m_tree[obj].count();
}
InputItem* InputModel::itemAt(const QModelIndex& index) {
if (!index.isValid()) {
if (!index.isValid() || !index.internalPointer()) {
return nullptr;
}
if (index.internalPointer()) {
return static_cast<InputItem*>(index.internalPointer());
}
if (!index.parent().isValid()) {
return nullptr;
}
InputItem* pmenu = static_cast<InputItem*>(index.parent().internalPointer());
return pmenu->items()[index.row()];
return static_cast<InputModelItem*>(index.internalPointer())->item;
}
const InputItem* InputModel::itemAt(const QModelIndex& index) const {
if (!index.isValid()) {
if (!index.isValid() || !index.internalPointer()) {
return nullptr;
}
if (index.internalPointer()) {
return static_cast<InputItem*>(index.internalPointer());
}
if (!index.parent().isValid()) {
return nullptr;
}
InputItem* pmenu = static_cast<InputItem*>(index.parent().internalPointer());
return pmenu->items()[index.row()];
return static_cast<const InputModelItem*>(index.internalPointer())->item;
}

View File

@ -11,6 +11,8 @@
#include "InputIndex.h"
#include <QAbstractItemModel>
#include <QMenu>
#include <QSet>
#include <functional>
@ -48,12 +50,28 @@ public:
InputItem* itemAt(const QModelIndex& index);
const InputItem* itemAt(const QModelIndex& index) const;
InputItem* root() { return m_root.root(); }
InputIndex* inputIndex() { return &m_index; }
private:
QModelIndex index(InputItem* item, int column = 0) const;
struct InputModelItem {
InputModelItem(InputItem* i) : item(i), obj(i) {}
InputModelItem(const QMenu* i) : menu(i), obj(i) {}
InputModelItem(const QObject* i) : obj(i) {}
InputIndex m_root;
InputItem* item = nullptr;
const QMenu* menu = nullptr;
const QObject* obj;
QString visibleName() const;
bool operator==(const InputModelItem& other) { return obj == other.obj; }
};
QModelIndex index(const QObject* item, int column = 0) const;
InputIndex m_index;
QList<InputModelItem> m_topLevelMenus;
QSet<const QObject*> m_menus;
QMap<const QObject*, QList<InputModelItem>> m_tree;
QString m_profileName;
};

View File

@ -28,7 +28,7 @@ public:
void setModel(InputIndex* model);
void setInputController(InputController* input);
const InputItem* root() { return m_model.root(); }
const InputIndex* root() { return m_model.inputIndex(); }
protected:
virtual bool event(QEvent*) override;

View File

@ -920,7 +920,6 @@ void Window::setupMenu(QMenuBar* menubar) {
installEventFilter(&m_inputController);
QMenu* fileMenu = menubar->addMenu(tr("&File"));
m_inputController.inputIndex()->addItem(fileMenu, "file");
addControlledAction(fileMenu, fileMenu->addAction(tr("Load &ROM..."), this, SLOT(selectROM()), QKeySequence::Open),
"loadROM");
#ifdef USE_SQLITE3
@ -975,8 +974,6 @@ void Window::setupMenu(QMenuBar* menubar) {
QMenu* quickLoadMenu = fileMenu->addMenu(tr("Quick load"));
QMenu* quickSaveMenu = fileMenu->addMenu(tr("Quick save"));
m_inputController.inputIndex()->addItem(quickLoadMenu, "quickLoadMenu");
m_inputController.inputIndex()->addItem(quickSaveMenu, "quickSaveMenu");
QAction* quickLoad = new QAction(tr("Load recent"), quickLoadMenu);
connect(quickLoad, &QAction::triggered, m_controller, &GameController::loadState);
@ -1062,7 +1059,6 @@ void Window::setupMenu(QMenuBar* menubar) {
#endif
QMenu* emulationMenu = menubar->addMenu(tr("&Emulation"));
InputItem* emulationMenuItem = m_inputController.inputIndex()->addItem(emulationMenu, "emulation");
QAction* reset = new QAction(tr("&Reset"), emulationMenu);
reset->setShortcut(tr("Ctrl+R"));
connect(reset, &QAction::triggered, m_controller, &GameController::reset);
@ -1103,11 +1099,11 @@ void Window::setupMenu(QMenuBar* menubar) {
emulationMenu->addSeparator();
emulationMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->setTurbo(true, false);
}, [this]() {
m_controller->setTurbo(false, false);
}), tr("Fast forward (held)"), "holdFastForward")->setShortcut(QKeySequence(Qt::Key_Tab)[0]);
}), tr("Fast forward (held)"), "holdFastForward", emulationMenu)->setShortcut(QKeySequence(Qt::Key_Tab)[0]);
QAction* turbo = new QAction(tr("&Fast forward"), emulationMenu);
turbo->setCheckable(true);
@ -1129,11 +1125,11 @@ void Window::setupMenu(QMenuBar* menubar) {
}
m_config->updateOption("fastForwardRatio");
emulationMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->startRewinding();
}, [this]() {
m_controller->stopRewinding();
}), tr("Rewind (held)"), "holdRewind")->setShortcut(QKeySequence("`")[0]);
}), tr("Rewind (held)"), "holdRewind", emulationMenu)->setShortcut(QKeySequence("`")[0]);
QAction* rewind = new QAction(tr("Re&wind"), emulationMenu);
rewind->setShortcut(tr("~"));
@ -1168,7 +1164,6 @@ void Window::setupMenu(QMenuBar* menubar) {
emulationMenu->addSeparator();
QMenu* solarMenu = emulationMenu->addMenu(tr("Solar sensor"));
m_inputController.inputIndex()->addItem(solarMenu, "luminance");
QAction* solarIncrease = new QAction(tr("Increase solar level"), solarMenu);
connect(solarIncrease, &QAction::triggered, m_controller, &GameController::increaseLuminanceLevel);
addControlledAction(solarMenu, solarIncrease, "increaseLuminanceLevel");
@ -1195,9 +1190,7 @@ void Window::setupMenu(QMenuBar* menubar) {
}
QMenu* avMenu = menubar->addMenu(tr("Audio/&Video"));
InputItem* avMenuItem = m_inputController.inputIndex()->addItem(avMenu, "av");
QMenu* frameMenu = avMenu->addMenu(tr("Frame size"));
InputItem* frameMenuItem = avMenuItem->addItem(frameMenu, "frameSize");
for (int i = 1; i <= 6; ++i) {
QAction* setSize = new QAction(tr("%1x").arg(QString::number(i)), avMenu);
setSize->setCheckable(true);
@ -1219,7 +1212,7 @@ void Window::setupMenu(QMenuBar* menubar) {
setSize->blockSignals(enableSignals);
});
m_frameSizes[i] = setSize;
addControlledAction(frameMenuItem, setSize, QString("frame%1x").arg(QString::number(i)));
addControlledAction(frameMenu, setSize, QString("frame%1x").arg(QString::number(i)));
}
QKeySequence fullscreenKeys;
#ifdef Q_OS_WIN
@ -1227,7 +1220,7 @@ void Window::setupMenu(QMenuBar* menubar) {
#else
fullscreenKeys = QKeySequence("Ctrl+F");
#endif
addControlledAction(frameMenuItem, frameMenu->addAction(tr("Toggle fullscreen"), this, SLOT(toggleFullScreen()), fullscreenKeys), "fullscreen");
addControlledAction(frameMenu, frameMenu->addAction(tr("Toggle fullscreen"), this, SLOT(toggleFullScreen()), fullscreenKeys), "fullscreen");
ConfigOption* lockAspectRatio = m_config->addOption("lockAspectRatio");
lockAspectRatio->addBoolean(tr("Lock aspect ratio"), avMenu);
@ -1332,13 +1325,9 @@ void Window::setupMenu(QMenuBar* menubar) {
avMenu->addSeparator();
m_videoLayers = avMenu->addMenu(tr("Video layers"));
avMenuItem->addItem(m_videoLayers, "videoLayers");
m_audioChannels = avMenu->addMenu(tr("Audio channels"));
avMenuItem->addItem(m_audioChannels, "audioChannels");
QMenu* toolsMenu = menubar->addMenu(tr("&Tools"));
m_inputController.inputIndex()->addItem(toolsMenu, "tools");
QAction* viewLogs = new QAction(tr("View &logs..."), toolsMenu);
connect(viewLogs, &QAction::triggered, m_logView, &QWidget::show);
addControlledAction(toolsMenu, viewLogs, "viewLogs");
@ -1475,133 +1464,131 @@ void Window::setupMenu(QMenuBar* menubar) {
QAction* exitFullScreen = new QAction(tr("Exit fullscreen"), frameMenu);
connect(exitFullScreen, &QAction::triggered, this, &Window::exitFullScreen);
exitFullScreen->setShortcut(QKeySequence("Esc"));
addHiddenAction(frameMenuItem, exitFullScreen, "exitFullScreen");
addHiddenAction(frameMenu, exitFullScreen, "exitFullScreen");
QMenu* autofireMenu = new QMenu(tr("Autofire"), this);
InputItem* autofireMenuItem = m_inputController.inputIndex()->addItem(autofireMenu, "autofire");
autofireMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->setAutofire(GBA_KEY_A, true);
}, [this]() {
m_controller->setAutofire(GBA_KEY_A, false);
}), tr("Autofire A"), "autofireA");
}), tr("Autofire A"), "autofireA", autofireMenu);
autofireMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->setAutofire(GBA_KEY_B, true);
}, [this]() {
m_controller->setAutofire(GBA_KEY_B, false);
}), tr("Autofire B"), "autofireB");
}), tr("Autofire B"), "autofireB", autofireMenu);
autofireMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->setAutofire(GBA_KEY_L, true);
}, [this]() {
m_controller->setAutofire(GBA_KEY_L, false);
}), tr("Autofire L"), "autofireL");
}), tr("Autofire L"), "autofireL", autofireMenu);
autofireMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->setAutofire(GBA_KEY_R, true);
}, [this]() {
m_controller->setAutofire(GBA_KEY_R, false);
}), tr("Autofire R"), "autofireR");
}), tr("Autofire R"), "autofireR", autofireMenu);
autofireMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->setAutofire(GBA_KEY_START, true);
}, [this]() {
m_controller->setAutofire(GBA_KEY_START, false);
}), tr("Autofire Start"), "autofireStart");
}), tr("Autofire Start"), "autofireStart", autofireMenu);
autofireMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->setAutofire(GBA_KEY_SELECT, true);
}, [this]() {
m_controller->setAutofire(GBA_KEY_SELECT, false);
}), tr("Autofire Select"), "autofireSelect");
}), tr("Autofire Select"), "autofireSelect", autofireMenu);
autofireMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->setAutofire(GBA_KEY_UP, true);
}, [this]() {
m_controller->setAutofire(GBA_KEY_UP, false);
}), tr("Autofire Up"), "autofireUp");
}), tr("Autofire Up"), "autofireUp", autofireMenu);
autofireMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->setAutofire(GBA_KEY_RIGHT, true);
}, [this]() {
m_controller->setAutofire(GBA_KEY_RIGHT, false);
}), tr("Autofire Right"), "autofireRight");
}), tr("Autofire Right"), "autofireRight", autofireMenu);
autofireMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->setAutofire(GBA_KEY_DOWN, true);
}, [this]() {
m_controller->setAutofire(GBA_KEY_DOWN, false);
}), tr("Autofire Down"), "autofireDown");
}), tr("Autofire Down"), "autofireDown", autofireMenu);
autofireMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->setAutofire(GBA_KEY_LEFT, true);
}, [this]() {
m_controller->setAutofire(GBA_KEY_LEFT, false);
}), tr("Autofire Left"), "autofireLeft");
}), tr("Autofire Left"), "autofireLeft", autofireMenu);
QMenu* bindingsMenu = new QMenu(tr("Bindings"), this);
InputItem* bindingsMenuItem = m_inputController.inputIndex()->addItem(bindingsMenu, "bindings");
bindingsMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->keyPressed(GBA_KEY_A);
}, [this]() {
m_controller->keyReleased(GBA_KEY_A);
}), tr("A"), "keyA");
}), tr("A"), "keyA", bindingsMenu);
bindingsMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->keyPressed(GBA_KEY_B);
}, [this]() {
m_controller->keyReleased(GBA_KEY_B);
}), tr("B"), "keyB");
}), tr("B"), "keyB", bindingsMenu);
bindingsMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->keyPressed(GBA_KEY_START);
}, [this]() {
m_controller->keyReleased(GBA_KEY_START);
}), tr("Start"), "keyStart");
}), tr("Start"), "keyStart", bindingsMenu);
bindingsMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->keyPressed(GBA_KEY_SELECT);
}, [this]() {
m_controller->keyReleased(GBA_KEY_SELECT);
}), tr("Select"), "keySelect");
}), tr("Select"), "keySelect", bindingsMenu);
bindingsMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->keyPressed(GBA_KEY_L);
}, [this]() {
m_controller->keyReleased(GBA_KEY_L);
}), tr("L"), "keyL");
}), tr("L"), "keyL", bindingsMenu);
bindingsMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->keyPressed(GBA_KEY_R);
}, [this]() {
m_controller->keyReleased(GBA_KEY_R);
}), tr("R"), "keyR");
}), tr("R"), "keyR", bindingsMenu);
bindingsMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->keyPressed(GBA_KEY_UP);
}, [this]() {
m_controller->keyReleased(GBA_KEY_UP);
}), tr("Up"), "keyUp");
}), tr("Up"), "keyUp", bindingsMenu);
bindingsMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->keyPressed(GBA_KEY_DOWN);
}, [this]() {
m_controller->keyReleased(GBA_KEY_DOWN);
}), tr("Down"), "keyDown");
}), tr("Down"), "keyDown", bindingsMenu);
bindingsMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->keyPressed(GBA_KEY_LEFT);
}, [this]() {
m_controller->keyReleased(GBA_KEY_LEFT);
}), tr("Left"), "keyLeft");
}), tr("Left"), "keyLeft", bindingsMenu);
bindingsMenuItem->addItem(qMakePair([this]() {
m_inputController.inputIndex()->addItem(qMakePair([this]() {
m_controller->keyPressed(GBA_KEY_RIGHT);
}, [this]() {
m_controller->keyReleased(GBA_KEY_RIGHT);
}), tr("Right"), "keyRight");
}), tr("Right"), "keyRight", bindingsMenu);
for (QAction* action : m_gameActions) {
action->setDisabled(true);
@ -1659,22 +1646,8 @@ QAction* Window::addControlledAction(QMenu* menu, QAction* action, const QString
return action;
}
QAction* Window::addControlledAction(InputItem* parent, QAction* action, const QString& name) {
addHiddenAction(parent, action, name);
parent->menu()->addAction(action);
return action;
}
QAction* Window::addHiddenAction(QMenu* menu, QAction* action, const QString& name) {
InputItem* parent = m_inputController.inputIndex()->itemForMenu(menu);
parent->addItem(action, name);
action->setShortcutContext(Qt::WidgetShortcut);
addAction(action);
return action;
}
QAction* Window::addHiddenAction(InputItem* parent, QAction* action, const QString& name) {
parent->addItem(action, name);
m_inputController.inputIndex()->addItem(action, name, menu);
action->setShortcutContext(Qt::WidgetShortcut);
addAction(action);
return action;

View File

@ -143,9 +143,7 @@ private:
template <typename T> std::function<void()> openTView();
QAction* addControlledAction(QMenu* menu, QAction* action, const QString& name);
QAction* addControlledAction(InputItem* parent, QAction* action, const QString& name);
QAction* addHiddenAction(QMenu* menu, QAction* action, const QString& name);
QAction* addHiddenAction(InputItem* parent, QAction* action, const QString& name);
void updateTitle(float fps = -1);