src/platform/qt/ShortcutModel.cpp (view raw)
1/* Copyright (c) 2013-2019 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "ShortcutModel.h"
7
8#include "ShortcutController.h"
9
10using namespace QGBA;
11
12ShortcutModel::ShortcutModel(QObject* parent)
13 : QAbstractItemModel(parent)
14{
15}
16
17void ShortcutModel::setController(ShortcutController* controller) {
18 beginResetModel();
19 m_controller = controller;
20 m_cache.clear();
21 connect(controller, &ShortcutController::shortcutAdded, this, &ShortcutModel::addRowNamed);
22 connect(controller, &ShortcutController::menuCleared, this, &ShortcutModel::clearMenu);
23 endResetModel();
24}
25
26QVariant ShortcutModel::data(const QModelIndex& index, int role) const {
27 if (role != Qt::DisplayRole || !index.isValid()) {
28 return QVariant();
29 }
30 int row = index.row();
31 const Item* item = static_cast<Item*>(index.internalPointer());
32 const Shortcut* shortcut = item->shortcut;
33 switch (index.column()) {
34 case 0:
35 return m_controller->visibleName(item->name);
36 case 1:
37 return shortcut ? QKeySequence(shortcut->shortcut()).toString(QKeySequence::NativeText) : QVariant();
38 case 2:
39 if (!shortcut) {
40 return QVariant();
41 }
42 if (shortcut->button() >= 0) {
43 return shortcut->button();
44 }
45 if (shortcut->axis() >= 0) {
46 char d = '\0';
47 if (shortcut->direction() == GamepadAxisEvent::POSITIVE) {
48 d = '+';
49 }
50 if (shortcut->direction() == GamepadAxisEvent::NEGATIVE) {
51 d = '-';
52 }
53 return QString("%1%2").arg(d).arg(shortcut->axis());
54 }
55 break;
56 }
57 return QVariant();
58}
59
60QVariant ShortcutModel::headerData(int section, Qt::Orientation orientation, int role) const {
61 if (role != Qt::DisplayRole) {
62 return QAbstractItemModel::headerData(section, orientation, role);
63 }
64 if (orientation == Qt::Horizontal) {
65 switch (section) {
66 case 0:
67 return tr("Action");
68 case 1:
69 return tr("Keyboard");
70 case 2:
71 return tr("Gamepad");
72 }
73 }
74 return section;
75}
76
77QModelIndex ShortcutModel::index(int row, int column, const QModelIndex& parent) const {
78 QString pmenu;
79 if (parent.isValid()) {
80 pmenu = static_cast<Item*>(parent.internalPointer())->name;
81 }
82 QString name = m_controller->name(row, pmenu);
83 Item* item = &m_cache[name];
84 item->name = name;
85 item->shortcut = m_controller->shortcut(name);
86 return createIndex(row, column, item);
87}
88
89QModelIndex ShortcutModel::parent(const QModelIndex& index) const {
90 if (!index.isValid() || !index.internalPointer()) {
91 return QModelIndex();
92 }
93 Item* item = static_cast<Item*>(index.internalPointer());
94 QString parent = m_controller->parent(item->name);
95 if (parent.isNull()) {
96 return QModelIndex();
97 }
98 Item* pitem = &m_cache[parent];
99 pitem->name = parent;
100 pitem->shortcut = m_controller->shortcut(parent);
101 return createIndex(m_controller->indexIn(parent), 0, pitem);
102}
103
104int ShortcutModel::columnCount(const QModelIndex& index) const {
105 return 3;
106}
107
108int ShortcutModel::rowCount(const QModelIndex& index) const {
109 if (!index.isValid()) {
110 return m_controller->count();
111 }
112 Item* item = static_cast<Item*>(index.internalPointer());
113 return m_controller->count(item->name);
114}
115
116QString ShortcutModel::name(const QModelIndex& index) const {
117 if (!index.isValid()) {
118 return {};
119 }
120 Item* item = static_cast<Item*>(index.internalPointer());
121 return item->name;
122}
123
124void ShortcutModel::addRowNamed(const QString& name) {
125 QString parent = m_controller->parent(name);
126 Item* item = &m_cache[parent];
127 item->name = parent;
128 item->shortcut = m_controller->shortcut(parent);
129 int index = m_controller->indexIn(name);
130 beginInsertRows(createIndex(m_controller->indexIn(parent), 0, item), index, index + 1);
131 endInsertRows();
132}
133
134void ShortcutModel::clearMenu(const QString& name) {
135 // TODO
136 beginResetModel();
137 endResetModel();
138}