mirror of https://github.com/mgba-emu/mgba.git
Qt: Persist shortcut configurations to a settings file
This commit is contained in:
parent
92f877e6a7
commit
721145a319
1
CHANGES
1
CHANGES
|
@ -12,6 +12,7 @@ Features:
|
||||||
- Better audio resampling via blip-buf
|
- Better audio resampling via blip-buf
|
||||||
- Game Pak overrides dialog for setting savetype and sensor values
|
- Game Pak overrides dialog for setting savetype and sensor values
|
||||||
- Support for games using the tilt sensor
|
- Support for games using the tilt sensor
|
||||||
|
- Remappable shortcuts for keyboard and gamepad
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
- Qt: Fix issue with set frame sizes being the wrong height
|
- Qt: Fix issue with set frame sizes being the wrong height
|
||||||
- Qt: Fix emulator crashing when full screen if a game is not running
|
- Qt: Fix emulator crashing when full screen if a game is not running
|
||||||
|
|
|
@ -143,6 +143,17 @@ QString ConfigController::getOption(const char* key) const {
|
||||||
return QString(GBAConfigGetValue(&m_config, key));
|
return QString(GBAConfigGetValue(&m_config, key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant ConfigController::getQtOption(const QString& key, const QString& group) const {
|
||||||
|
if (!group.isNull()) {
|
||||||
|
m_settings->beginGroup(group);
|
||||||
|
}
|
||||||
|
QVariant value = m_settings->value(key);
|
||||||
|
if (!group.isNull()) {
|
||||||
|
m_settings->endGroup();
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
void ConfigController::setOption(const char* key, bool value) {
|
void ConfigController::setOption(const char* key, bool value) {
|
||||||
GBAConfigSetIntValue(&m_config, key, value);
|
GBAConfigSetIntValue(&m_config, key, value);
|
||||||
QString optionName(key);
|
QString optionName(key);
|
||||||
|
@ -184,6 +195,16 @@ void ConfigController::setOption(const char* key, const QVariant& value) {
|
||||||
setOption(key, stringValue.toLocal8Bit().constData());
|
setOption(key, stringValue.toLocal8Bit().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigController::setQtOption(const QString& key, const QVariant& value, const QString& group) {
|
||||||
|
if (!group.isNull()) {
|
||||||
|
m_settings->beginGroup(group);
|
||||||
|
}
|
||||||
|
m_settings->setValue(key, value);
|
||||||
|
if (!group.isNull()) {
|
||||||
|
m_settings->endGroup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QList<QString> ConfigController::getMRU() const {
|
QList<QString> ConfigController::getMRU() const {
|
||||||
QList<QString> mru;
|
QList<QString> mru;
|
||||||
m_settings->beginGroup("mru");
|
m_settings->beginGroup("mru");
|
||||||
|
|
|
@ -70,6 +70,8 @@ public:
|
||||||
|
|
||||||
QString getOption(const char* key) const;
|
QString getOption(const char* key) const;
|
||||||
|
|
||||||
|
QVariant getQtOption(const QString& key, const QString& group = QString()) const;
|
||||||
|
|
||||||
QList<QString> getMRU() const;
|
QList<QString> getMRU() const;
|
||||||
void setMRU(const QList<QString>& mru);
|
void setMRU(const QList<QString>& mru);
|
||||||
|
|
||||||
|
@ -79,6 +81,7 @@ public slots:
|
||||||
void setOption(const char* key, unsigned value);
|
void setOption(const char* key, unsigned value);
|
||||||
void setOption(const char* key, const char* value);
|
void setOption(const char* key, const char* value);
|
||||||
void setOption(const char* key, const QVariant& value);
|
void setOption(const char* key, const QVariant& value);
|
||||||
|
void setQtOption(const QString& key, const QVariant& value, const QString& group = QString());
|
||||||
|
|
||||||
void write();
|
void write();
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
#include "ShortcutController.h"
|
#include "ShortcutController.h"
|
||||||
|
|
||||||
|
#include "ConfigController.h"
|
||||||
#include "GamepadButtonEvent.h"
|
#include "GamepadButtonEvent.h"
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
@ -16,9 +17,14 @@ using namespace QGBA;
|
||||||
ShortcutController::ShortcutController(QObject* parent)
|
ShortcutController::ShortcutController(QObject* parent)
|
||||||
: QAbstractItemModel(parent)
|
: QAbstractItemModel(parent)
|
||||||
, m_rootMenu(nullptr)
|
, m_rootMenu(nullptr)
|
||||||
|
, m_config(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShortcutController::setConfigController(ConfigController* controller) {
|
||||||
|
m_config = controller;
|
||||||
|
}
|
||||||
|
|
||||||
QVariant ShortcutController::data(const QModelIndex& index, int role) const {
|
QVariant ShortcutController::data(const QModelIndex& index, int role) const {
|
||||||
if (role != Qt::DisplayRole || !index.isValid()) {
|
if (role != Qt::DisplayRole || !index.isValid()) {
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
@ -99,6 +105,9 @@ void ShortcutController::addAction(QMenu* menu, QAction* action, const QString&
|
||||||
smenu->addAction(action, name);
|
smenu->addAction(action, name);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
ShortcutItem* item = &smenu->items().last();
|
ShortcutItem* item = &smenu->items().last();
|
||||||
|
if (m_config) {
|
||||||
|
loadShortcuts(item);
|
||||||
|
}
|
||||||
emit dataChanged(createIndex(smenu->items().count() - 1, 0, item), createIndex(smenu->items().count() - 1, 2, item));
|
emit dataChanged(createIndex(smenu->items().count() - 1, 0, item), createIndex(smenu->items().count() - 1, 2, item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +123,9 @@ void ShortcutController::addFunctions(QMenu* menu, std::function<void ()> press,
|
||||||
smenu->addFunctions(qMakePair(press, release), shortcut, visibleName, name);
|
smenu->addFunctions(qMakePair(press, release), shortcut, visibleName, name);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
ShortcutItem* item = &smenu->items().last();
|
ShortcutItem* item = &smenu->items().last();
|
||||||
|
if (m_config) {
|
||||||
|
loadShortcuts(item);
|
||||||
|
}
|
||||||
m_heldKeys[shortcut] = item;
|
m_heldKeys[shortcut] = item;
|
||||||
emit dataChanged(createIndex(smenu->items().count() - 1, 0, item), createIndex(smenu->items().count() - 1, 2, item));
|
emit dataChanged(createIndex(smenu->items().count() - 1, 0, item), createIndex(smenu->items().count() - 1, 2, item));
|
||||||
}
|
}
|
||||||
|
@ -176,6 +188,9 @@ void ShortcutController::updateKey(const QModelIndex& index, const QKeySequence&
|
||||||
m_heldKeys[keySequence] = item;
|
m_heldKeys[keySequence] = item;
|
||||||
}
|
}
|
||||||
item->setShortcut(keySequence);
|
item->setShortcut(keySequence);
|
||||||
|
if (m_config) {
|
||||||
|
m_config->setQtOption(item->name(), keySequence.toString(), KEY_SECTION);
|
||||||
|
}
|
||||||
emit dataChanged(createIndex(index.row(), 0, index.internalPointer()), createIndex(index.row(), 2, index.internalPointer()));
|
emit dataChanged(createIndex(index.row(), 0, index.internalPointer()), createIndex(index.row(), 2, index.internalPointer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,6 +209,9 @@ void ShortcutController::updateButton(const QModelIndex& index, int button) {
|
||||||
m_buttons.take(oldButton);
|
m_buttons.take(oldButton);
|
||||||
}
|
}
|
||||||
m_buttons[button] = item;
|
m_buttons[button] = item;
|
||||||
|
if (m_config) {
|
||||||
|
m_config->setQtOption(item->name(), button, BUTTON_SECTION);
|
||||||
|
}
|
||||||
emit dataChanged(createIndex(index.row(), 0, index.internalPointer()), createIndex(index.row(), 2, index.internalPointer()));
|
emit dataChanged(createIndex(index.row(), 0, index.internalPointer()), createIndex(index.row(), 2, index.internalPointer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,6 +269,30 @@ bool ShortcutController::eventFilter(QObject*, QEvent* event) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShortcutController::loadShortcuts(ShortcutItem* item) {
|
||||||
|
QVariant shortcut = m_config->getQtOption(item->name(), KEY_SECTION);
|
||||||
|
if (!shortcut.isNull()) {
|
||||||
|
QKeySequence keySequence(shortcut.toString());
|
||||||
|
if (item->functions().first) {
|
||||||
|
QKeySequence oldShortcut = item->shortcut();
|
||||||
|
if (!oldShortcut.isEmpty()) {
|
||||||
|
m_heldKeys.take(oldShortcut);
|
||||||
|
}
|
||||||
|
m_heldKeys[keySequence] = item;
|
||||||
|
}
|
||||||
|
item->setShortcut(keySequence);
|
||||||
|
}
|
||||||
|
QVariant button = m_config->getQtOption(item->name(), BUTTON_SECTION);
|
||||||
|
if (!button.isNull()) {
|
||||||
|
int oldButton = item->button();
|
||||||
|
item->setButton(button.toInt());
|
||||||
|
if (oldButton >= 0) {
|
||||||
|
m_buttons.take(oldButton);
|
||||||
|
}
|
||||||
|
m_buttons[button.toInt()] = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QKeySequence ShortcutController::keyEventToSequence(const QKeyEvent* event) {
|
QKeySequence ShortcutController::keyEventToSequence(const QKeyEvent* event) {
|
||||||
QString modifier = QString::null;
|
QString modifier = QString::null;
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,15 @@ class QString;
|
||||||
|
|
||||||
namespace QGBA {
|
namespace QGBA {
|
||||||
|
|
||||||
|
class ConfigController;
|
||||||
|
|
||||||
class ShortcutController : public QAbstractItemModel {
|
class ShortcutController : public QAbstractItemModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
constexpr static const char* const KEY_SECTION = "shortcutKey";
|
||||||
|
constexpr static const char* const BUTTON_SECTION = "shortcutButton";
|
||||||
|
|
||||||
class ShortcutItem {
|
class ShortcutItem {
|
||||||
public:
|
public:
|
||||||
typedef QPair<std::function<void ()>, std::function<void ()>> Functions;
|
typedef QPair<std::function<void ()>, std::function<void ()>> Functions;
|
||||||
|
@ -66,6 +71,8 @@ private:
|
||||||
public:
|
public:
|
||||||
ShortcutController(QObject* parent = nullptr);
|
ShortcutController(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
void setConfigController(ConfigController* controller);
|
||||||
|
|
||||||
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
@ -91,10 +98,14 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QKeySequence keyEventToSequence(const QKeyEvent*);
|
static QKeySequence keyEventToSequence(const QKeyEvent*);
|
||||||
|
|
||||||
|
void loadShortcuts(ShortcutItem*);
|
||||||
|
|
||||||
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<QKeySequence, ShortcutItem*> m_heldKeys;
|
QMap<QKeySequence, ShortcutItem*> m_heldKeys;
|
||||||
|
ConfigController* m_config;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,7 @@ Window::Window(ConfigController* config, QWidget* parent)
|
||||||
m_logView->setLevels(GBA_LOG_WARN | GBA_LOG_ERROR | GBA_LOG_FATAL);
|
m_logView->setLevels(GBA_LOG_WARN | GBA_LOG_ERROR | GBA_LOG_FATAL);
|
||||||
m_fpsTimer.setInterval(FPS_TIMER_INTERVAL);
|
m_fpsTimer.setInterval(FPS_TIMER_INTERVAL);
|
||||||
|
|
||||||
|
m_shortcutController->setConfigController(m_config);
|
||||||
setupMenu(menuBar());
|
setupMenu(menuBar());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue