mirror of https://github.com/mgba-emu/mgba.git
Qt: Remove tree structure from InputItem
This commit is contained in:
parent
96fcf9d267
commit
94b756ca9b
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue