mirror of https://github.com/mgba-emu/mgba.git
Merge branch 'feature/shortcut-redo'
This commit is contained in:
commit
46cf812db3
1
CHANGES
1
CHANGES
|
@ -1,6 +1,7 @@
|
||||||
0.4.0: (Future)
|
0.4.0: (Future)
|
||||||
Misc:
|
Misc:
|
||||||
- Qt: Window size command line options are now supported
|
- Qt: Window size command line options are now supported
|
||||||
|
- Qt: Increase usability of key mapper
|
||||||
|
|
||||||
0.3.0: (2015-08-16)
|
0.3.0: (2015-08-16)
|
||||||
Features:
|
Features:
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "GamepadAxisEvent.h"
|
#include "GamepadAxisEvent.h"
|
||||||
#include "GamepadButtonEvent.h"
|
#include "GamepadButtonEvent.h"
|
||||||
|
#include "ShortcutController.h"
|
||||||
|
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ KeyEditor::KeyEditor(QWidget* parent)
|
||||||
, m_button(false)
|
, m_button(false)
|
||||||
{
|
{
|
||||||
setAlignment(Qt::AlignCenter);
|
setAlignment(Qt::AlignCenter);
|
||||||
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyEditor::setValue(int key) {
|
void KeyEditor::setValue(int key) {
|
||||||
|
@ -27,7 +29,11 @@ void KeyEditor::setValue(int key) {
|
||||||
if (m_button) {
|
if (m_button) {
|
||||||
updateButtonText();
|
updateButtonText();
|
||||||
} else {
|
} else {
|
||||||
setText(QKeySequence(key).toString(QKeySequence::NativeText));
|
if (key < 0) {
|
||||||
|
setText(tr("---"));
|
||||||
|
} else {
|
||||||
|
setText(QKeySequence(key).toString(QKeySequence::NativeText));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
emit valueChanged(key);
|
emit valueChanged(key);
|
||||||
}
|
}
|
||||||
|
@ -71,27 +77,60 @@ QSize KeyEditor::sizeHint() const {
|
||||||
|
|
||||||
void KeyEditor::keyPressEvent(QKeyEvent* event) {
|
void KeyEditor::keyPressEvent(QKeyEvent* event) {
|
||||||
if (!m_button) {
|
if (!m_button) {
|
||||||
setValue(event->key());
|
if (m_key < 0) {
|
||||||
|
m_key = 0;
|
||||||
|
}
|
||||||
|
if (ShortcutController::isModifierKey(event->key())) {
|
||||||
|
switch (event->key()) {
|
||||||
|
case Qt::Key_Shift:
|
||||||
|
setValue(m_key | Qt::ShiftModifier);
|
||||||
|
break;
|
||||||
|
case Qt::Key_Control:
|
||||||
|
setValue(m_key | Qt::ControlModifier);
|
||||||
|
break;
|
||||||
|
case Qt::Key_Alt:
|
||||||
|
setValue(m_key | Qt::AltModifier);
|
||||||
|
break;
|
||||||
|
case Qt::Key_Meta:
|
||||||
|
setValue(m_key | Qt::MetaModifier);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
setValue(m_key);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setValue(event->key() | (m_key & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyEditor::event(QEvent* event) {
|
bool KeyEditor::event(QEvent* event) {
|
||||||
if (!m_button) {
|
if (!m_button) {
|
||||||
return QWidget::event(event);
|
if (event->type() == QEvent::KeyPress) {
|
||||||
}
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||||
if (event->type() == GamepadButtonEvent::Down()) {
|
if (keyEvent->key() != Qt::Key_Tab && keyEvent->key() != Qt::Key_Backtab) {
|
||||||
setValueButton(static_cast<GamepadButtonEvent*>(event)->value());
|
return QWidget::event(event);
|
||||||
event->accept();
|
}
|
||||||
return true;
|
if (!(keyEvent->modifiers() & ~Qt::ShiftModifier)) {
|
||||||
}
|
keyPressEvent(keyEvent);
|
||||||
if (event->type() == GamepadAxisEvent::Type()) {
|
keyEvent->accept();
|
||||||
GamepadAxisEvent* gae = static_cast<GamepadAxisEvent*>(event);
|
return true;
|
||||||
if (gae->isNew()) {
|
}
|
||||||
setValueAxis(gae->axis(), gae->direction());
|
}
|
||||||
|
} else {
|
||||||
|
if (event->type() == GamepadButtonEvent::Down()) {
|
||||||
|
setValueButton(static_cast<GamepadButtonEvent*>(event)->value());
|
||||||
|
event->accept();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (event->type() == GamepadAxisEvent::Type()) {
|
||||||
|
GamepadAxisEvent* gae = static_cast<GamepadAxisEvent*>(event);
|
||||||
|
if (gae->isNew()) {
|
||||||
|
setValueAxis(gae->axis(), gae->direction());
|
||||||
|
}
|
||||||
|
event->accept();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
event->accept();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return QWidget::event(event);
|
return QWidget::event(event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ QVariant ShortcutController::data(const QModelIndex& index, int role) const {
|
||||||
case 0:
|
case 0:
|
||||||
return item->visibleName();
|
return item->visibleName();
|
||||||
case 1:
|
case 1:
|
||||||
return item->shortcut().toString(QKeySequence::NativeText);
|
return QKeySequence(item->shortcut()).toString(QKeySequence::NativeText);
|
||||||
case 2:
|
case 2:
|
||||||
if (item->button() >= 0) {
|
if (item->button() >= 0) {
|
||||||
return item->button();
|
return item->button();
|
||||||
|
@ -125,7 +125,7 @@ void ShortcutController::addAction(QMenu* menu, QAction* action, const QString&
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutController::addFunctions(QMenu* menu, std::function<void()> press, std::function<void()> release,
|
void ShortcutController::addFunctions(QMenu* menu, std::function<void()> press, std::function<void()> release,
|
||||||
const QKeySequence& shortcut, const QString& visibleName, const QString& name) {
|
int shortcut, const QString& visibleName, const QString& name) {
|
||||||
ShortcutItem* smenu = m_menuMap[menu];
|
ShortcutItem* smenu = m_menuMap[menu];
|
||||||
if (!smenu) {
|
if (!smenu) {
|
||||||
return;
|
return;
|
||||||
|
@ -145,6 +145,11 @@ void ShortcutController::addFunctions(QMenu* menu, std::function<void()> press,
|
||||||
createIndex(smenu->items().count() - 1, 2, item));
|
createIndex(smenu->items().count() - 1, 2, item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShortcutController::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) {
|
void ShortcutController::addMenu(QMenu* menu, QMenu* parentMenu) {
|
||||||
ShortcutItem* smenu = m_menuMap[parentMenu];
|
ShortcutItem* smenu = m_menuMap[parentMenu];
|
||||||
if (!smenu) {
|
if (!smenu) {
|
||||||
|
@ -179,10 +184,10 @@ const ShortcutController::ShortcutItem* ShortcutController::itemAt(const QModelI
|
||||||
return static_cast<const ShortcutItem*>(index.internalPointer());
|
return static_cast<const ShortcutItem*>(index.internalPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
QKeySequence ShortcutController::shortcutAt(const QModelIndex& index) const {
|
int ShortcutController::shortcutAt(const QModelIndex& index) const {
|
||||||
const ShortcutItem* item = itemAt(index);
|
const ShortcutItem* item = itemAt(index);
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return QKeySequence();
|
return 0;
|
||||||
}
|
}
|
||||||
return item->shortcut();
|
return item->shortcut();
|
||||||
}
|
}
|
||||||
|
@ -195,7 +200,7 @@ bool ShortcutController::isMenuAt(const QModelIndex& index) const {
|
||||||
return item->menu();
|
return item->menu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutController::updateKey(const QModelIndex& index, const QKeySequence& keySequence) {
|
void ShortcutController::updateKey(const QModelIndex& index, int keySequence) {
|
||||||
if (!index.isValid()) {
|
if (!index.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -204,23 +209,28 @@ void ShortcutController::updateKey(const QModelIndex& index, const QKeySequence&
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ShortcutItem* item = itemAt(index);
|
ShortcutItem* item = itemAt(index);
|
||||||
if (item->functions().first) {
|
updateKey(item, keySequence);
|
||||||
QKeySequence oldShortcut = item->shortcut();
|
|
||||||
if (!oldShortcut.isEmpty()) {
|
|
||||||
m_heldKeys.take(oldShortcut);
|
|
||||||
}
|
|
||||||
if (!keySequence.isEmpty()) {
|
|
||||||
m_heldKeys[keySequence] = item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item->setShortcut(keySequence);
|
|
||||||
if (m_config) {
|
if (m_config) {
|
||||||
m_config->setQtOption(item->name(), keySequence.toString(), KEY_SECTION);
|
m_config->setQtOption(item->name(), QKeySequence(keySequence).toString(), KEY_SECTION);
|
||||||
}
|
}
|
||||||
emit dataChanged(createIndex(index.row(), 0, index.internalPointer()),
|
emit dataChanged(createIndex(index.row(), 0, index.internalPointer()),
|
||||||
createIndex(index.row(), 2, index.internalPointer()));
|
createIndex(index.row(), 2, index.internalPointer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShortcutController::updateKey(ShortcutItem* item, int keySequence) {
|
||||||
|
int oldShortcut = item->shortcut();
|
||||||
|
if (item->functions().first) {
|
||||||
|
if (oldShortcut > 0) {
|
||||||
|
m_heldKeys.take(oldShortcut);
|
||||||
|
}
|
||||||
|
if (keySequence > 0) {
|
||||||
|
m_heldKeys[keySequence] = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item->setShortcut(keySequence);
|
||||||
|
}
|
||||||
|
|
||||||
void ShortcutController::updateButton(const QModelIndex& index, int button) {
|
void ShortcutController::updateButton(const QModelIndex& index, int button) {
|
||||||
if (!index.isValid()) {
|
if (!index.isValid()) {
|
||||||
return;
|
return;
|
||||||
|
@ -286,7 +296,7 @@ void ShortcutController::updateAxis(const QModelIndex& index, int axis, GamepadA
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutController::clearKey(const QModelIndex& index) {
|
void ShortcutController::clearKey(const QModelIndex& index) {
|
||||||
updateKey(index, QKeySequence());
|
updateKey(index, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutController::clearButton(const QModelIndex& index) {
|
void ShortcutController::clearButton(const QModelIndex& index) {
|
||||||
|
@ -299,22 +309,27 @@ bool ShortcutController::eventFilter(QObject*, QEvent* event) {
|
||||||
if (keyEvent->isAutoRepeat()) {
|
if (keyEvent->isAutoRepeat()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto item = m_heldKeys.find(keyEventToSequence(keyEvent));
|
int key = keyEvent->key();
|
||||||
if (item == m_heldKeys.end()) {
|
if (!isModifierKey(key)) {
|
||||||
return false;
|
key |= keyEvent->modifiers();
|
||||||
}
|
|
||||||
ShortcutItem::Functions pair = item.value()->functions();
|
|
||||||
if (event->type() == QEvent::KeyPress) {
|
|
||||||
if (pair.first) {
|
|
||||||
pair.first();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (pair.second) {
|
key = toModifierKey(key | keyEvent->modifiers());
|
||||||
pair.second();
|
}
|
||||||
}
|
auto item = m_heldKeys.find(key);
|
||||||
|
if (item != m_heldKeys.end()) {
|
||||||
|
ShortcutItem::Functions pair = item.value()->functions();
|
||||||
|
if (event->type() == QEvent::KeyPress) {
|
||||||
|
if (pair.first) {
|
||||||
|
pair.first();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pair.second) {
|
||||||
|
pair.second();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event->accept();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
event->accept();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if (event->type() == GamepadButtonEvent::Down()) {
|
if (event->type() == GamepadButtonEvent::Down()) {
|
||||||
auto item = m_buttons.find(static_cast<GamepadButtonEvent*>(event)->value());
|
auto item = m_buttons.find(static_cast<GamepadButtonEvent*>(event)->value());
|
||||||
|
@ -378,15 +393,11 @@ void ShortcutController::loadShortcuts(ShortcutItem* item) {
|
||||||
}
|
}
|
||||||
QVariant shortcut = m_config->getQtOption(item->name(), KEY_SECTION);
|
QVariant shortcut = m_config->getQtOption(item->name(), KEY_SECTION);
|
||||||
if (!shortcut.isNull()) {
|
if (!shortcut.isNull()) {
|
||||||
QKeySequence keySequence(shortcut.toString());
|
if (shortcut.toString().endsWith("+")) {
|
||||||
if (item->functions().first) {
|
updateKey(item, toModifierShortcut(shortcut.toString()));
|
||||||
QKeySequence oldShortcut = item->shortcut();
|
} else {
|
||||||
if (!oldShortcut.isEmpty()) {
|
updateKey(item, QKeySequence(shortcut.toString())[0]);
|
||||||
m_heldKeys.take(oldShortcut);
|
|
||||||
}
|
|
||||||
m_heldKeys[keySequence] = item;
|
|
||||||
}
|
}
|
||||||
item->setShortcut(keySequence);
|
|
||||||
}
|
}
|
||||||
loadGamepadShortcuts(item);
|
loadGamepadShortcuts(item);
|
||||||
}
|
}
|
||||||
|
@ -446,26 +457,6 @@ void ShortcutController::loadGamepadShortcuts(ShortcutItem* item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QKeySequence ShortcutController::keyEventToSequence(const QKeyEvent* event) {
|
|
||||||
QString modifier = QString::null;
|
|
||||||
|
|
||||||
if (event->modifiers() & Qt::ShiftModifier) {
|
|
||||||
modifier += "Shift+";
|
|
||||||
}
|
|
||||||
if (event->modifiers() & Qt::ControlModifier) {
|
|
||||||
modifier += "Ctrl+";
|
|
||||||
}
|
|
||||||
if (event->modifiers() & Qt::AltModifier) {
|
|
||||||
modifier += "Alt+";
|
|
||||||
}
|
|
||||||
if (event->modifiers() & Qt::MetaModifier) {
|
|
||||||
modifier += "Meta+";
|
|
||||||
}
|
|
||||||
|
|
||||||
QString key = QKeySequence(event->key()).toString();
|
|
||||||
return QKeySequence(modifier + key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShortcutController::loadProfile(const QString& profile) {
|
void ShortcutController::loadProfile(const QString& profile) {
|
||||||
m_profileName = profile;
|
m_profileName = profile;
|
||||||
m_profile = InputProfile::findProfile(profile);
|
m_profile = InputProfile::findProfile(profile);
|
||||||
|
@ -481,9 +472,69 @@ void ShortcutController::onSubitems(ShortcutItem* item, std::function<void(Short
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ShortcutController::toModifierShortcut(const QString& shortcut) {
|
||||||
|
// Qt doesn't seem to work with raw modifier shortcuts!
|
||||||
|
QStringList modifiers = shortcut.split('+');
|
||||||
|
int value = 0;
|
||||||
|
for (const auto& mod : modifiers) {
|
||||||
|
if (mod == QLatin1String("Shift")) {
|
||||||
|
value |= Qt::ShiftModifier;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (mod == QLatin1String("Ctrl")) {
|
||||||
|
value |= Qt::ControlModifier;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (mod == QLatin1String("Alt")) {
|
||||||
|
value |= Qt::AltModifier;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (mod == QLatin1String("Meta")) {
|
||||||
|
value |= Qt::MetaModifier;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShortcutController::isModifierKey(int key) {
|
||||||
|
switch (key) {
|
||||||
|
case Qt::Key_Shift:
|
||||||
|
case Qt::Key_Control:
|
||||||
|
case Qt::Key_Alt:
|
||||||
|
case Qt::Key_Meta:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ShortcutController::toModifierKey(int key) {
|
||||||
|
int modifiers = key & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier);
|
||||||
|
key ^= modifiers;
|
||||||
|
switch (key) {
|
||||||
|
case Qt::Key_Shift:
|
||||||
|
modifiers |= Qt::ShiftModifier;
|
||||||
|
break;
|
||||||
|
case Qt::Key_Control:
|
||||||
|
modifiers |= Qt::ControlModifier;
|
||||||
|
break;
|
||||||
|
case Qt::Key_Alt:
|
||||||
|
modifiers |= Qt::AltModifier;
|
||||||
|
break;
|
||||||
|
case Qt::Key_Meta:
|
||||||
|
modifiers |= Qt::MetaModifier;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return modifiers;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ShortcutController::ShortcutItem::ShortcutItem(QAction* action, const QString& name, ShortcutItem* parent)
|
ShortcutController::ShortcutItem::ShortcutItem(QAction* action, const QString& name, ShortcutItem* parent)
|
||||||
: m_action(action)
|
: m_action(action)
|
||||||
, m_shortcut(action->shortcut())
|
, m_shortcut(action->shortcut().isEmpty() ? 0 : action->shortcut()[0])
|
||||||
, m_menu(nullptr)
|
, m_menu(nullptr)
|
||||||
, m_name(name)
|
, m_name(name)
|
||||||
, m_button(-1)
|
, m_button(-1)
|
||||||
|
@ -496,7 +547,7 @@ ShortcutController::ShortcutItem::ShortcutItem(QAction* action, const QString& n
|
||||||
.remove("...");
|
.remove("...");
|
||||||
}
|
}
|
||||||
|
|
||||||
ShortcutController::ShortcutItem::ShortcutItem(ShortcutController::ShortcutItem::Functions functions, const QKeySequence& shortcut, const QString& visibleName, const QString& name, ShortcutItem* parent)
|
ShortcutController::ShortcutItem::ShortcutItem(ShortcutController::ShortcutItem::Functions functions, int shortcut, const QString& visibleName, const QString& name, ShortcutItem* parent)
|
||||||
: m_action(nullptr)
|
: m_action(nullptr)
|
||||||
, m_shortcut(shortcut)
|
, m_shortcut(shortcut)
|
||||||
, m_functions(functions)
|
, m_functions(functions)
|
||||||
|
@ -512,6 +563,7 @@ ShortcutController::ShortcutItem::ShortcutItem(ShortcutController::ShortcutItem:
|
||||||
|
|
||||||
ShortcutController::ShortcutItem::ShortcutItem(QMenu* menu, ShortcutItem* parent)
|
ShortcutController::ShortcutItem::ShortcutItem(QMenu* menu, ShortcutItem* parent)
|
||||||
: m_action(nullptr)
|
: m_action(nullptr)
|
||||||
|
, m_shortcut(0)
|
||||||
, m_menu(menu)
|
, m_menu(menu)
|
||||||
, m_button(-1)
|
, m_button(-1)
|
||||||
, m_axis(-1)
|
, m_axis(-1)
|
||||||
|
@ -530,7 +582,7 @@ void ShortcutController::ShortcutItem::addAction(QAction* action, const QString&
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutController::ShortcutItem::addFunctions(ShortcutController::ShortcutItem::Functions functions,
|
void ShortcutController::ShortcutItem::addFunctions(ShortcutController::ShortcutItem::Functions functions,
|
||||||
const QKeySequence& shortcut, const QString& visibleName,
|
int shortcut, const QString& visibleName,
|
||||||
const QString& name) {
|
const QString& name) {
|
||||||
m_items.append(ShortcutItem(functions, shortcut, visibleName, name, this));
|
m_items.append(ShortcutItem(functions, shortcut, visibleName, name, this));
|
||||||
}
|
}
|
||||||
|
@ -539,10 +591,10 @@ void ShortcutController::ShortcutItem::addSubmenu(QMenu* menu) {
|
||||||
m_items.append(ShortcutItem(menu, this));
|
m_items.append(ShortcutItem(menu, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutController::ShortcutItem::setShortcut(const QKeySequence& shortcut) {
|
void ShortcutController::ShortcutItem::setShortcut(int shortcut) {
|
||||||
m_shortcut = shortcut;
|
m_shortcut = shortcut;
|
||||||
if (m_action) {
|
if (m_action) {
|
||||||
m_action->setShortcut(shortcut);
|
m_action->setShortcut(QKeySequence(shortcut));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "GamepadAxisEvent.h"
|
#include "GamepadAxisEvent.h"
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#include <QKeySequence>
|
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
@ -38,13 +37,13 @@ private:
|
||||||
typedef QPair<std::function<void ()>, std::function<void ()>> Functions;
|
typedef QPair<std::function<void ()>, std::function<void ()>> Functions;
|
||||||
|
|
||||||
ShortcutItem(QAction* action, const QString& name, ShortcutItem* parent = nullptr);
|
ShortcutItem(QAction* action, const QString& name, ShortcutItem* parent = nullptr);
|
||||||
ShortcutItem(Functions functions, const QKeySequence& shortcut, const QString& visibleName, const QString& name,
|
ShortcutItem(Functions functions, int shortcut, const QString& visibleName, const QString& name,
|
||||||
ShortcutItem* parent = nullptr);
|
ShortcutItem* parent = nullptr);
|
||||||
ShortcutItem(QMenu* action, ShortcutItem* parent = nullptr);
|
ShortcutItem(QMenu* action, ShortcutItem* parent = nullptr);
|
||||||
|
|
||||||
QAction* action() { return m_action; }
|
QAction* action() { return m_action; }
|
||||||
const QAction* action() const { return m_action; }
|
const QAction* action() const { return m_action; }
|
||||||
const QKeySequence& shortcut() const { return m_shortcut; }
|
const int shortcut() const { return m_shortcut; }
|
||||||
Functions functions() const { return m_functions; }
|
Functions functions() const { return m_functions; }
|
||||||
QMenu* menu() { return m_menu; }
|
QMenu* menu() { return m_menu; }
|
||||||
const QMenu* menu() const { return m_menu; }
|
const QMenu* menu() const { return m_menu; }
|
||||||
|
@ -55,11 +54,11 @@ private:
|
||||||
ShortcutItem* parent() { return m_parent; }
|
ShortcutItem* parent() { return m_parent; }
|
||||||
const ShortcutItem* parent() const { return m_parent; }
|
const ShortcutItem* parent() const { return m_parent; }
|
||||||
void addAction(QAction* action, const QString& name);
|
void addAction(QAction* action, const QString& name);
|
||||||
void addFunctions(Functions functions, const QKeySequence& shortcut, const QString& visibleName,
|
void addFunctions(Functions functions, int shortcut, const QString& visibleName,
|
||||||
const QString& name);
|
const QString& name);
|
||||||
void addSubmenu(QMenu* menu);
|
void addSubmenu(QMenu* menu);
|
||||||
int button() const { return m_button; }
|
int button() const { return m_button; }
|
||||||
void setShortcut(const QKeySequence& sequence);
|
void setShortcut(int sequence);
|
||||||
void setButton(int button) { m_button = button; }
|
void setButton(int button) { m_button = button; }
|
||||||
int axis() const { return m_axis; }
|
int axis() const { return m_axis; }
|
||||||
GamepadAxisEvent::Direction direction() const { return m_direction; }
|
GamepadAxisEvent::Direction direction() const { return m_direction; }
|
||||||
|
@ -71,7 +70,7 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QAction* m_action;
|
QAction* m_action;
|
||||||
QKeySequence m_shortcut;
|
int m_shortcut;
|
||||||
QMenu* m_menu;
|
QMenu* m_menu;
|
||||||
Functions m_functions;
|
Functions m_functions;
|
||||||
QString m_name;
|
QString m_name;
|
||||||
|
@ -99,23 +98,26 @@ public:
|
||||||
virtual int rowCount(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 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,
|
void addFunctions(QMenu* menu, std::function<void()> press, std::function<void()> release,
|
||||||
const QKeySequence& shortcut, const QString& visibleName, const QString& name);
|
const QKeySequence& shortcut, const QString& visibleName, const QString& name);
|
||||||
void addMenu(QMenu* menu, QMenu* parent = nullptr);
|
void addMenu(QMenu* menu, QMenu* parent = nullptr);
|
||||||
|
|
||||||
QAction* getAction(const QString& name);
|
QAction* getAction(const QString& name);
|
||||||
|
int shortcutAt(const QModelIndex& index) const;
|
||||||
QKeySequence shortcutAt(const QModelIndex& index) const;
|
|
||||||
bool isMenuAt(const QModelIndex& index) const;
|
bool isMenuAt(const QModelIndex& index) const;
|
||||||
|
|
||||||
void updateKey(const QModelIndex& index, const QKeySequence& keySequence);
|
void updateKey(const QModelIndex& index, int keySequence);
|
||||||
void updateButton(const QModelIndex& index, int button);
|
void updateButton(const QModelIndex& index, int button);
|
||||||
void updateAxis(const QModelIndex& index, int axis, GamepadAxisEvent::Direction direction);
|
void updateAxis(const QModelIndex& index, int axis, GamepadAxisEvent::Direction direction);
|
||||||
|
|
||||||
void clearKey(const QModelIndex& index);
|
void clearKey(const QModelIndex& index);
|
||||||
void clearButton(const QModelIndex& index);
|
void clearButton(const QModelIndex& index);
|
||||||
|
|
||||||
static QKeySequence keyEventToSequence(const QKeyEvent*);
|
static int toModifierShortcut(const QString& shortcut);
|
||||||
|
static bool isModifierKey(int key);
|
||||||
|
static int toModifierKey(int key);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void loadProfile(const QString& profile);
|
void loadProfile(const QString& profile);
|
||||||
|
@ -129,12 +131,13 @@ private:
|
||||||
void loadShortcuts(ShortcutItem*);
|
void loadShortcuts(ShortcutItem*);
|
||||||
void loadGamepadShortcuts(ShortcutItem*);
|
void loadGamepadShortcuts(ShortcutItem*);
|
||||||
void onSubitems(ShortcutItem*, std::function<void(ShortcutItem*)> func);
|
void onSubitems(ShortcutItem*, std::function<void(ShortcutItem*)> func);
|
||||||
|
void updateKey(ShortcutItem* item, int keySequence);
|
||||||
|
|
||||||
ShortcutItem m_rootMenu;
|
ShortcutItem m_rootMenu;
|
||||||
QMap<QMenu*, ShortcutItem*> m_menuMap;
|
QMap<QMenu*, ShortcutItem*> m_menuMap;
|
||||||
QMap<int, ShortcutItem*> m_buttons;
|
QMap<int, ShortcutItem*> m_buttons;
|
||||||
QMap<QPair<int, GamepadAxisEvent::Direction>, ShortcutItem*> m_axes;
|
QMap<QPair<int, GamepadAxisEvent::Direction>, ShortcutItem*> m_axes;
|
||||||
QMap<QKeySequence, ShortcutItem*> m_heldKeys;
|
QMap<int, ShortcutItem*> m_heldKeys;
|
||||||
ConfigController* m_config;
|
ConfigController* m_config;
|
||||||
QString m_profileName;
|
QString m_profileName;
|
||||||
const InputProfile* m_profile;
|
const InputProfile* m_profile;
|
||||||
|
|
|
@ -19,10 +19,14 @@ ShortcutView::ShortcutView(QWidget* parent)
|
||||||
, m_input(nullptr)
|
, m_input(nullptr)
|
||||||
{
|
{
|
||||||
m_ui.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
m_ui.keyEdit->setValueButton(-1);
|
m_ui.keyEdit->setValueKey(0);
|
||||||
m_ui.keySequenceEdit->installEventFilter(this);
|
|
||||||
|
|
||||||
connect(m_ui.keySequenceEdit, SIGNAL(keySequenceChanged(const QKeySequence&)), this, SLOT(updateKey(const QKeySequence&)));
|
connect(m_ui.gamepadButton, &QAbstractButton::pressed, [this]() {
|
||||||
|
m_ui.keyEdit->setValueButton(-1);
|
||||||
|
});
|
||||||
|
connect(m_ui.keyboardButton, &QAbstractButton::pressed, [this]() {
|
||||||
|
m_ui.keyEdit->setValueKey(0);
|
||||||
|
});
|
||||||
connect(m_ui.keyEdit, SIGNAL(valueChanged(int)), this, SLOT(updateButton(int)));
|
connect(m_ui.keyEdit, SIGNAL(valueChanged(int)), this, SLOT(updateButton(int)));
|
||||||
connect(m_ui.keyEdit, SIGNAL(axisChanged(int, int)), this, SLOT(updateAxis(int, int)));
|
connect(m_ui.keyEdit, SIGNAL(axisChanged(int, int)), this, SLOT(updateAxis(int, int)));
|
||||||
connect(m_ui.shortcutTable, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(load(const QModelIndex&)));
|
connect(m_ui.shortcutTable, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(load(const QModelIndex&)));
|
||||||
|
@ -42,21 +46,6 @@ void ShortcutView::setInputController(InputController* controller) {
|
||||||
m_input->stealFocus(this);
|
m_input->stealFocus(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShortcutView::eventFilter(QObject*, QEvent* event) {
|
|
||||||
if (event->type() == QEvent::KeyPress) {
|
|
||||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
|
||||||
if (keyEvent->key() != Qt::Key_Tab && keyEvent->key() != Qt::Key_Backtab) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(keyEvent->modifiers() & ~Qt::ShiftModifier)) {
|
|
||||||
m_ui.keySequenceEdit->setKeySequence(ShortcutController::keyEventToSequence(keyEvent));
|
|
||||||
keyEvent->accept();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShortcutView::load(const QModelIndex& index) {
|
void ShortcutView::load(const QModelIndex& index) {
|
||||||
if (!m_controller) {
|
if (!m_controller) {
|
||||||
return;
|
return;
|
||||||
|
@ -64,23 +53,20 @@ void ShortcutView::load(const QModelIndex& index) {
|
||||||
if (m_controller->isMenuAt(index)) {
|
if (m_controller->isMenuAt(index)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QKeySequence sequence = m_controller->shortcutAt(index);
|
int shortcut = m_controller->shortcutAt(index);
|
||||||
if (index.column() == 1) {
|
if (index.column() == 1) {
|
||||||
m_ui.keyboardButton->click();
|
m_ui.keyboardButton->click();
|
||||||
} else if (index.column() == 2) {
|
} else if (index.column() == 2) {
|
||||||
m_ui.gamepadButton->click();
|
m_ui.gamepadButton->click();
|
||||||
}
|
}
|
||||||
|
bool blockSignals = m_ui.keyEdit->blockSignals(true);
|
||||||
|
m_ui.keyEdit->setFocus(Qt::MouseFocusReason);
|
||||||
if (m_ui.gamepadButton->isChecked()) {
|
if (m_ui.gamepadButton->isChecked()) {
|
||||||
bool blockSignals = m_ui.keyEdit->blockSignals(true);
|
|
||||||
m_ui.keyEdit->setFocus();
|
|
||||||
m_ui.keyEdit->setValueButton(-1); // There are no default bindings
|
m_ui.keyEdit->setValueButton(-1); // There are no default bindings
|
||||||
m_ui.keyEdit->blockSignals(blockSignals);
|
|
||||||
} else {
|
} else {
|
||||||
bool blockSignals = m_ui.keySequenceEdit->blockSignals(true);
|
m_ui.keyEdit->setValueKey(shortcut);
|
||||||
m_ui.keySequenceEdit->setFocus();
|
|
||||||
m_ui.keySequenceEdit->setKeySequence(sequence);
|
|
||||||
m_ui.keySequenceEdit->blockSignals(blockSignals);
|
|
||||||
}
|
}
|
||||||
|
m_ui.keyEdit->blockSignals(blockSignals);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutView::clear() {
|
void ShortcutView::clear() {
|
||||||
|
@ -96,22 +82,19 @@ void ShortcutView::clear() {
|
||||||
m_ui.keyEdit->setValueButton(-1);
|
m_ui.keyEdit->setValueButton(-1);
|
||||||
} else {
|
} else {
|
||||||
m_controller->clearKey(index);
|
m_controller->clearKey(index);
|
||||||
m_ui.keySequenceEdit->setKeySequence(QKeySequence());
|
m_ui.keyEdit->setValueKey(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutView::updateKey(const QKeySequence& shortcut) {
|
|
||||||
if (!m_controller || m_controller->isMenuAt(m_ui.shortcutTable->selectionModel()->currentIndex())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_controller->updateKey(m_ui.shortcutTable->selectionModel()->currentIndex(), shortcut);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShortcutView::updateButton(int button) {
|
void ShortcutView::updateButton(int button) {
|
||||||
if (!m_controller || m_controller->isMenuAt(m_ui.shortcutTable->selectionModel()->currentIndex())) {
|
if (!m_controller || m_controller->isMenuAt(m_ui.shortcutTable->selectionModel()->currentIndex())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_controller->updateButton(m_ui.shortcutTable->selectionModel()->currentIndex(), button);
|
if (m_ui.gamepadButton->isChecked()) {
|
||||||
|
m_controller->updateButton(m_ui.shortcutTable->selectionModel()->currentIndex(), button);
|
||||||
|
} else {
|
||||||
|
m_controller->updateKey(m_ui.shortcutTable->selectionModel()->currentIndex(), button);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutView::updateAxis(int axis, int direction) {
|
void ShortcutView::updateAxis(int axis, int direction) {
|
||||||
|
|
|
@ -27,14 +27,12 @@ public:
|
||||||
void setInputController(InputController* input);
|
void setInputController(InputController* input);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool eventFilter(QObject* obj, QEvent* event) override;
|
|
||||||
virtual bool event(QEvent*) override;
|
virtual bool event(QEvent*) override;
|
||||||
virtual void closeEvent(QCloseEvent*) override;
|
virtual void closeEvent(QCloseEvent*) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void load(const QModelIndex&);
|
void load(const QModelIndex&);
|
||||||
void clear();
|
void clear();
|
||||||
void updateKey(const QKeySequence&);
|
|
||||||
void updateButton(int button);
|
void updateButton(int button);
|
||||||
void updateAxis(int axis, int direction);
|
void updateAxis(int axis, int direction);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>425</width>
|
<width>432</width>
|
||||||
<height>443</height>
|
<height>443</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -60,16 +60,6 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QKeySequenceEdit" name="keySequenceEdit">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGBA::KeyEditor" name="keyEdit">
|
<widget class="QGBA::KeyEditor" name="keyEdit">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -78,9 +68,6 @@
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="visible">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -95,38 +82,5 @@
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections/>
|
||||||
<connection>
|
|
||||||
<sender>keyboardButton</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>keySequenceEdit</receiver>
|
|
||||||
<slot>setVisible(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>86</x>
|
|
||||||
<y>374</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>66</x>
|
|
||||||
<y>20</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>gamepadButton</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>keyEdit</receiver>
|
|
||||||
<slot>setVisible(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>213</x>
|
|
||||||
<y>374</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>206</x>
|
|
||||||
<y>340</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
</ui>
|
||||||
|
|
Loading…
Reference in New Issue