Qt: Initial hotkey implementation
This commit is contained in:
parent
0590f0935c
commit
40e1b7af23
|
@ -12,6 +12,10 @@ add_executable(duckstation-qt
|
|||
gamelistsettingswidget.ui
|
||||
gamelistwidget.cpp
|
||||
gamelistwidget.h
|
||||
hotkeysettingswidget.cpp
|
||||
hotkeysettingswidget.h
|
||||
inputbindingwidgets.cpp
|
||||
inputbindingwidgets.h
|
||||
main.cpp
|
||||
mainwindow.cpp
|
||||
mainwindow.h
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="consolesettingswidget.cpp" />
|
||||
<ClCompile Include="gpusettingswidget.cpp" />
|
||||
<ClCompile Include="hotkeysettingswidget.cpp" />
|
||||
<ClCompile Include="inputbindingwidgets.cpp" />
|
||||
<ClCompile Include="qtdisplaywindow.cpp" />
|
||||
<ClCompile Include="gamelistsettingswidget.cpp" />
|
||||
<ClCompile Include="gamelistwidget.cpp" />
|
||||
|
@ -53,6 +55,8 @@
|
|||
<QtMoc Include="portsettingswidget.h" />
|
||||
<QtMoc Include="qtdisplaywindow.h" />
|
||||
<QtMoc Include="gpusettingswidget.h" />
|
||||
<QtMoc Include="hotkeysettingswidget.h" />
|
||||
<QtMoc Include="inputbindingwidgets.h" />
|
||||
<ClInclude Include="settingwidgetbinder.h" />
|
||||
<QtMoc Include="consolesettingswidget.h" />
|
||||
<QtMoc Include="gamelistsettingswidget.h" />
|
||||
|
@ -105,6 +109,8 @@
|
|||
<ClCompile Include="$(IntDir)moc_gamelistsettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_gamelistwidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_gpusettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_hotkeysettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_inputbindingwidgets.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_mainwindow.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_opengldisplaywindow.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_portsettingswidget.cpp" />
|
||||
|
|
|
@ -25,11 +25,15 @@
|
|||
<ClCompile Include="$(IntDir)moc_qtdisplaywindow.cpp" />
|
||||
<ClCompile Include="gpusettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_gpusettingswidget.cpp" />
|
||||
<ClCompile Include="inputbindingwidgets.cpp" />
|
||||
<ClCompile Include="hotkeysettingswidget.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="qtsettingsinterface.h" />
|
||||
<ClInclude Include="qtutils.h" />
|
||||
<ClInclude Include="settingwidgetbinder.h" />
|
||||
<ClInclude Include="inputbindingwidgets.h" />
|
||||
<ClInclude Include="hotkeysettingswidget.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="resources">
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
#include "hotkeysettingswidget.h"
|
||||
#include "core/controller.h"
|
||||
#include "core/settings.h"
|
||||
#include "inputbindingwidgets.h"
|
||||
#include "qthostinterface.h"
|
||||
#include "qtutils.h"
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtWidgets/QGridLayout>
|
||||
#include <QtWidgets/QLabel>
|
||||
|
||||
HotkeySettingsWidget::HotkeySettingsWidget(QtHostInterface* host_interface, QWidget* parent /* = nullptr */)
|
||||
: QWidget(parent), m_host_interface(host_interface)
|
||||
{
|
||||
createUi();
|
||||
}
|
||||
|
||||
HotkeySettingsWidget::~HotkeySettingsWidget() = default;
|
||||
|
||||
void HotkeySettingsWidget::createUi()
|
||||
{
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
|
||||
m_tab_widget = new QTabWidget(this);
|
||||
|
||||
createButtons();
|
||||
|
||||
layout->addWidget(m_tab_widget, 0, 0, 1, 1);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void HotkeySettingsWidget::createButtons()
|
||||
{
|
||||
std::vector<QtHostInterface::HotkeyInfo> hotkeys = m_host_interface->getHotkeyList();
|
||||
|
||||
for (const QtHostInterface::HotkeyInfo& hi : hotkeys)
|
||||
{
|
||||
auto iter = m_categories.find(hi.category);
|
||||
if (iter == m_categories.end())
|
||||
{
|
||||
QWidget* container = new QWidget(m_tab_widget);
|
||||
QVBoxLayout* vlayout = new QVBoxLayout(container);
|
||||
QGridLayout* layout = new QGridLayout();
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
vlayout->addLayout(layout);
|
||||
vlayout->addStretch(1);
|
||||
iter = m_categories.insert(hi.category, Category{container, layout});
|
||||
m_tab_widget->addTab(container, hi.category);
|
||||
}
|
||||
|
||||
QWidget* container = iter->container;
|
||||
QGridLayout* layout = iter->layout;
|
||||
const int layout_count = layout->count() / 2;
|
||||
const int target_column = (layout_count / ROWS_PER_COLUMN) * 2;
|
||||
const int target_row = layout_count % ROWS_PER_COLUMN;
|
||||
|
||||
const QString setting_name = QStringLiteral("Hotkeys/%1").arg(hi.name);
|
||||
layout->addWidget(new QLabel(hi.display_name, container), target_row, target_column);
|
||||
layout->addWidget(new InputButtonBindingWidget(m_host_interface, setting_name, container), target_row,
|
||||
target_column + 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
#include "core/types.h"
|
||||
#include <QtWidgets/QTabWidget>
|
||||
#include <QtCore/QMap>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
class QtHostInterface;
|
||||
class QGridLayout;
|
||||
|
||||
class HotkeySettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HotkeySettingsWidget(QtHostInterface* host_interface, QWidget* parent = nullptr);
|
||||
~HotkeySettingsWidget();
|
||||
|
||||
private:
|
||||
enum : u32
|
||||
{
|
||||
ROWS_PER_COLUMN = 10
|
||||
};
|
||||
|
||||
void createUi();
|
||||
void createButtons();
|
||||
|
||||
QtHostInterface* m_host_interface;
|
||||
|
||||
QTabWidget* m_tab_widget;
|
||||
|
||||
struct Category
|
||||
{
|
||||
QWidget* container;
|
||||
QGridLayout* layout;
|
||||
};
|
||||
QMap<QString, Category> m_categories;
|
||||
};
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
#include "inputbindingwidgets.h"
|
||||
#include "core/settings.h"
|
||||
#include "qthostinterface.h"
|
||||
#include "qtutils.h"
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QKeyEvent>
|
||||
|
||||
InputButtonBindingWidget::InputButtonBindingWidget(QtHostInterface* host_interface, QString setting_name,
|
||||
QWidget* parent)
|
||||
: QPushButton(parent), m_host_interface(host_interface), m_setting_name(std::move(setting_name))
|
||||
{
|
||||
m_current_binding_value = m_host_interface->getQSettings().value(m_setting_name).toString();
|
||||
setText(m_current_binding_value);
|
||||
|
||||
connect(this, &QPushButton::pressed, this, &InputButtonBindingWidget::onPressed);
|
||||
}
|
||||
|
||||
InputButtonBindingWidget::~InputButtonBindingWidget() = default;
|
||||
|
||||
void InputButtonBindingWidget::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
// ignore the key press if we're listening for input
|
||||
if (isListeningForInput())
|
||||
return;
|
||||
|
||||
QPushButton::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void InputButtonBindingWidget::keyReleaseEvent(QKeyEvent* event)
|
||||
{
|
||||
if (!isListeningForInput())
|
||||
{
|
||||
QPushButton::keyReleaseEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
QString key_name = QtUtils::GetKeyIdentifier(event->key());
|
||||
if (!key_name.isEmpty())
|
||||
{
|
||||
// TODO: Update input map
|
||||
m_current_binding_value = QStringLiteral("Keyboard/%1").arg(key_name);
|
||||
m_host_interface->getQSettings().setValue(m_setting_name, m_current_binding_value);
|
||||
}
|
||||
|
||||
stopListeningForInput();
|
||||
}
|
||||
|
||||
void InputButtonBindingWidget::onPressed()
|
||||
{
|
||||
if (isListeningForInput())
|
||||
stopListeningForInput();
|
||||
|
||||
startListeningForInput();
|
||||
}
|
||||
|
||||
void InputButtonBindingWidget::onInputListenTimerTimeout()
|
||||
{
|
||||
m_input_listen_remaining_seconds--;
|
||||
if (m_input_listen_remaining_seconds == 0)
|
||||
{
|
||||
stopListeningForInput();
|
||||
return;
|
||||
}
|
||||
|
||||
setText(tr("Push Button... [%1]").arg(m_input_listen_remaining_seconds));
|
||||
}
|
||||
|
||||
void InputButtonBindingWidget::startListeningForInput()
|
||||
{
|
||||
m_input_listen_timer = new QTimer(this);
|
||||
m_input_listen_timer->setSingleShot(false);
|
||||
m_input_listen_timer->start(1000);
|
||||
|
||||
m_input_listen_timer->connect(m_input_listen_timer, &QTimer::timeout, this,
|
||||
&InputButtonBindingWidget::onInputListenTimerTimeout);
|
||||
m_input_listen_remaining_seconds = 5;
|
||||
setText(tr("Push Button... [%1]").arg(m_input_listen_remaining_seconds));
|
||||
}
|
||||
|
||||
void InputButtonBindingWidget::stopListeningForInput()
|
||||
{
|
||||
setText(m_current_binding_value);
|
||||
delete m_input_listen_timer;
|
||||
m_input_listen_timer = nullptr;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
#include "core/types.h"
|
||||
#include <QtWidgets/QPushButton>
|
||||
|
||||
class QTimer;
|
||||
|
||||
class QtHostInterface;
|
||||
|
||||
class InputButtonBindingWidget : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InputButtonBindingWidget(QtHostInterface* host_interface, QString setting_name, QWidget* parent);
|
||||
~InputButtonBindingWidget();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
void keyReleaseEvent(QKeyEvent* event) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPressed();
|
||||
void onInputListenTimerTimeout();
|
||||
|
||||
private:
|
||||
bool isListeningForInput() const { return m_input_listen_timer != nullptr; }
|
||||
void startListeningForInput();
|
||||
void stopListeningForInput();
|
||||
|
||||
QtHostInterface* m_host_interface;
|
||||
QString m_setting_name;
|
||||
QString m_current_binding_value;
|
||||
QTimer* m_input_listen_timer = nullptr;
|
||||
u32 m_input_listen_remaining_seconds = 0;
|
||||
};
|
|
@ -72,8 +72,9 @@
|
|||
</widget>
|
||||
<addaction name="actionFullscreen"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionConsoleSettings"/>
|
||||
<addaction name="actionGameListSettings"/>
|
||||
<addaction name="actionHotkeySettings"/>
|
||||
<addaction name="actionConsoleSettings"/>
|
||||
<addaction name="actionPortSettings"/>
|
||||
<addaction name="actionGPUSettings"/>
|
||||
<addaction name="actionAudioSettings"/>
|
||||
|
@ -219,13 +220,13 @@
|
|||
<string>&Port Settings...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCPUSettings">
|
||||
<action name="actionHotkeySettings">
|
||||
<property name="icon">
|
||||
<iconset resource="icons.qrc">
|
||||
<normaloff>:/icons/applications-other.png</normaloff>:/icons/applications-other.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&CPU Settings...</string>
|
||||
<string>&Hotkey Settings...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGPUSettings">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "portsettingswidget.h"
|
||||
#include "core/controller.h"
|
||||
#include "core/settings.h"
|
||||
#include "inputbindingwidgets.h"
|
||||
#include "qthostinterface.h"
|
||||
#include "qtutils.h"
|
||||
#include <QtCore/QTimer>
|
||||
|
@ -94,7 +95,7 @@ void PortSettingsWidget::createPortBindingSettingsUi(int index, PortSettingsUI*
|
|||
const QString button_name_q = QString::fromStdString(button_name);
|
||||
const QString setting_name = QStringLiteral("Controller%1/Button%2").arg(index + 1).arg(button_name_q);
|
||||
QLabel* label = new QLabel(button_name_q, container);
|
||||
InputButtonBindingWidget* button = new InputButtonBindingWidget(m_host_interface, setting_name, ctype, container);
|
||||
InputButtonBindingWidget* button = new InputButtonBindingWidget(m_host_interface, setting_name, container);
|
||||
layout->addWidget(label, start_row + current_row, current_column);
|
||||
layout->addWidget(button, start_row + current_row, current_column + 1);
|
||||
|
||||
|
@ -129,83 +130,3 @@ void PortSettingsWidget::onControllerTypeChanged(int index)
|
|||
QString::fromStdString(Settings::GetControllerTypeName(static_cast<ControllerType>(type_index))));
|
||||
createPortBindingSettingsUi(index, &m_port_ui[index]);
|
||||
}
|
||||
|
||||
InputButtonBindingWidget::InputButtonBindingWidget(QtHostInterface* host_interface, QString setting_name,
|
||||
ControllerType controller_type, QWidget* parent)
|
||||
: QPushButton(parent), m_host_interface(host_interface), m_setting_name(std::move(setting_name)),
|
||||
m_controller_type(controller_type)
|
||||
{
|
||||
m_current_binding_value = m_host_interface->getQSettings().value(m_setting_name).toString();
|
||||
setText(m_current_binding_value);
|
||||
|
||||
connect(this, &QPushButton::pressed, this, &InputButtonBindingWidget::onPressed);
|
||||
}
|
||||
|
||||
InputButtonBindingWidget::~InputButtonBindingWidget() = default;
|
||||
|
||||
void InputButtonBindingWidget::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
// ignore the key press if we're listening for input
|
||||
if (isListeningForInput())
|
||||
return;
|
||||
|
||||
QPushButton::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void InputButtonBindingWidget::keyReleaseEvent(QKeyEvent* event)
|
||||
{
|
||||
if (!isListeningForInput())
|
||||
{
|
||||
QPushButton::keyReleaseEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
QString key_name = QtUtils::GetKeyIdentifier(event->key());
|
||||
if (!key_name.isEmpty())
|
||||
{
|
||||
// TODO: Update input map
|
||||
m_current_binding_value = QStringLiteral("Keyboard/%1").arg(key_name);
|
||||
m_host_interface->getQSettings().setValue(m_setting_name, m_current_binding_value);
|
||||
}
|
||||
|
||||
stopListeningForInput();
|
||||
}
|
||||
|
||||
void InputButtonBindingWidget::onPressed()
|
||||
{
|
||||
if (isListeningForInput())
|
||||
stopListeningForInput();
|
||||
|
||||
startListeningForInput();
|
||||
}
|
||||
|
||||
void InputButtonBindingWidget::onInputListenTimerTimeout()
|
||||
{
|
||||
m_input_listen_remaining_seconds--;
|
||||
if (m_input_listen_remaining_seconds == 0)
|
||||
{
|
||||
stopListeningForInput();
|
||||
return;
|
||||
}
|
||||
|
||||
setText(tr("Push Button... [%1]").arg(m_input_listen_remaining_seconds));
|
||||
}
|
||||
|
||||
void InputButtonBindingWidget::startListeningForInput()
|
||||
{
|
||||
m_input_listen_timer = new QTimer(this);
|
||||
m_input_listen_timer->setSingleShot(false);
|
||||
m_input_listen_timer->start(1000);
|
||||
|
||||
m_input_listen_timer->connect(m_input_listen_timer, &QTimer::timeout, this,
|
||||
&InputButtonBindingWidget::onInputListenTimerTimeout);
|
||||
m_input_listen_remaining_seconds = 5;
|
||||
setText(tr("Push Button... [%1]").arg(m_input_listen_remaining_seconds));
|
||||
}
|
||||
|
||||
void InputButtonBindingWidget::stopListeningForInput()
|
||||
{
|
||||
setText(m_current_binding_value);
|
||||
delete m_input_listen_timer;
|
||||
m_input_listen_timer = nullptr;
|
||||
}
|
||||
|
|
|
@ -45,33 +45,3 @@ private:
|
|||
|
||||
std::array<PortSettingsUI, 2> m_port_ui = {};
|
||||
};
|
||||
|
||||
class InputButtonBindingWidget : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InputButtonBindingWidget(QtHostInterface* host_interface, QString setting_name, ControllerType controller_type,
|
||||
QWidget* parent);
|
||||
~InputButtonBindingWidget();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
void keyReleaseEvent(QKeyEvent* event) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPressed();
|
||||
void onInputListenTimerTimeout();
|
||||
|
||||
private:
|
||||
bool isListeningForInput() const { return m_input_listen_timer != nullptr; }
|
||||
void startListeningForInput();
|
||||
void stopListeningForInput();
|
||||
|
||||
QtHostInterface* m_host_interface;
|
||||
QString m_setting_name;
|
||||
QString m_current_binding_value;
|
||||
ControllerType m_controller_type;
|
||||
QTimer* m_input_listen_timer = nullptr;
|
||||
u32 m_input_listen_remaining_seconds = 0;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "qthostinterface.h"
|
||||
#include "YBaseLib/Log.h"
|
||||
#include "YBaseLib/String.h"
|
||||
#include "common/null_audio_stream.h"
|
||||
#include "core/controller.h"
|
||||
#include "core/game_list.h"
|
||||
|
@ -198,6 +199,12 @@ void QtHostInterface::doUpdateInputMap()
|
|||
{
|
||||
m_keyboard_input_handlers.clear();
|
||||
|
||||
updateControllerInputMap();
|
||||
updateHotkeyInputMap();
|
||||
}
|
||||
|
||||
void QtHostInterface::updateControllerInputMap()
|
||||
{
|
||||
for (u32 controller_index = 0; controller_index < 2; controller_index++)
|
||||
{
|
||||
const ControllerType ctype = m_settings.controller_types[controller_index];
|
||||
|
@ -212,38 +219,102 @@ void QtHostInterface::doUpdateInputMap()
|
|||
if (!var.isValid())
|
||||
continue;
|
||||
|
||||
auto handler = [this, controller_index, button_code](bool pressed) {
|
||||
addButtonToInputMap(var.toString(), [this, controller_index, button_code](bool pressed) {
|
||||
if (!m_system)
|
||||
return;
|
||||
|
||||
Controller* controller = m_system->GetController(controller_index);
|
||||
if (controller)
|
||||
controller->SetButtonState(button_code, pressed);
|
||||
};
|
||||
|
||||
const QString value = var.toString();
|
||||
const QString device = value.section('/', 0, 0);
|
||||
const QString button = value.section('/', 1, 1);
|
||||
if (device == QStringLiteral("Keyboard"))
|
||||
{
|
||||
std::optional<int> key_id = QtUtils::GetKeyIdForIdentifier(button);
|
||||
if (!key_id.has_value())
|
||||
{
|
||||
qWarning() << "Unknown keyboard key " << button;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_keyboard_input_handlers.emplace(key_id.value(), std::move(handler));
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << "Unknown input device: " << device;
|
||||
continue;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<QtHostInterface::HotkeyInfo> QtHostInterface::getHotkeyList() const
|
||||
{
|
||||
std::vector<HotkeyInfo> hotkeys = {
|
||||
{QStringLiteral("FastForward"), QStringLiteral("Toggle Fast Forward"), QStringLiteral("General")},
|
||||
{QStringLiteral("Fullscreen"), QStringLiteral("Toggle Fullscreen"), QStringLiteral("General")},
|
||||
{QStringLiteral("Pause"), QStringLiteral("Toggle Pause"), QStringLiteral("General")}};
|
||||
|
||||
for (u32 i = 1; i <= NUM_SAVE_STATE_HOTKEYS; i++)
|
||||
{
|
||||
hotkeys.push_back(
|
||||
{QStringLiteral("LoadState%1").arg(i), QStringLiteral("Load State %1").arg(i), QStringLiteral("Save States")});
|
||||
}
|
||||
for (u32 i = 1; i <= NUM_SAVE_STATE_HOTKEYS; i++)
|
||||
{
|
||||
hotkeys.push_back(
|
||||
{QStringLiteral("SaveState%1").arg(i), QStringLiteral("Save State %1").arg(i), QStringLiteral("Save States")});
|
||||
}
|
||||
|
||||
return hotkeys;
|
||||
}
|
||||
|
||||
void QtHostInterface::updateHotkeyInputMap()
|
||||
{
|
||||
auto hk = [this](const QString& hotkey_name, InputButtonHandler handler) {
|
||||
QVariant var = m_qsettings.value(QStringLiteral("Hotkeys/%1").arg(hotkey_name));
|
||||
if (!var.isValid())
|
||||
return;
|
||||
|
||||
addButtonToInputMap(var.toString(), std::move(handler));
|
||||
};
|
||||
|
||||
hk(QStringLiteral("FastForward"), [this](bool pressed) {
|
||||
m_speed_limiter_temp_disabled = pressed;
|
||||
HostInterface::UpdateSpeedLimiterState();
|
||||
});
|
||||
|
||||
hk(QStringLiteral("Fullscreen"), [this](bool pressed) {
|
||||
if (!pressed)
|
||||
toggleFullscreen();
|
||||
});
|
||||
|
||||
hk(QStringLiteral("Pause"), [this](bool pressed) {
|
||||
if (!pressed)
|
||||
pauseSystem(!m_paused);
|
||||
});
|
||||
|
||||
for (u32 i = 1; i <= NUM_SAVE_STATE_HOTKEYS; i++)
|
||||
{
|
||||
hk(QStringLiteral("LoadState%1").arg(i), [this, i](bool pressed) {
|
||||
if (!pressed)
|
||||
HostInterface::LoadState(TinyString::FromFormat("savestate_%u.bin", i));
|
||||
});
|
||||
|
||||
hk(QStringLiteral("SaveState%1").arg(i), [this, i](bool pressed) {
|
||||
if (!pressed)
|
||||
HostInterface::SaveState(TinyString::FromFormat("savestate_%u.bin", i));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void QtHostInterface::addButtonToInputMap(const QString& binding, InputButtonHandler handler)
|
||||
{
|
||||
const QString device = binding.section('/', 0, 0);
|
||||
const QString button = binding.section('/', 1, 1);
|
||||
if (device == QStringLiteral("Keyboard"))
|
||||
{
|
||||
std::optional<int> key_id = QtUtils::GetKeyIdForIdentifier(button);
|
||||
if (!key_id.has_value())
|
||||
{
|
||||
qWarning() << "Unknown keyboard key " << button;
|
||||
return;
|
||||
}
|
||||
|
||||
m_keyboard_input_handlers.emplace(key_id.value(), std::move(handler));
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << "Unknown input device: " << device;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void QtHostInterface::updateFullscreen() {}
|
||||
|
||||
void QtHostInterface::powerOffSystem()
|
||||
{
|
||||
if (!isOnWorkerThread())
|
||||
|
@ -295,6 +366,18 @@ void QtHostInterface::pauseSystem(bool paused)
|
|||
|
||||
void QtHostInterface::changeDisc(QString new_disc_filename) {}
|
||||
|
||||
void QtHostInterface::toggleFullscreen()
|
||||
{
|
||||
if (!isOnWorkerThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "toggleFullscreen", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
m_settings.display_fullscreen = !m_settings.display_fullscreen;
|
||||
updateFullscreen();
|
||||
}
|
||||
|
||||
void QtHostInterface::doBootSystem(QString initial_filename, QString initial_save_state_filename)
|
||||
{
|
||||
if (!m_display_window->initializeDeviceContext())
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
class QWidget;
|
||||
|
||||
|
@ -49,6 +51,14 @@ public:
|
|||
void updateInputMap();
|
||||
void handleKeyEvent(int key, bool pressed);
|
||||
|
||||
struct HotkeyInfo
|
||||
{
|
||||
QString name;
|
||||
QString display_name;
|
||||
QString category;
|
||||
};
|
||||
std::vector<HotkeyInfo> getHotkeyList() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void emulationStarting();
|
||||
void emulationStarted();
|
||||
|
@ -61,6 +71,7 @@ public Q_SLOTS:
|
|||
void resetSystem();
|
||||
void pauseSystem(bool paused);
|
||||
void changeDisc(QString new_disc_filename);
|
||||
void toggleFullscreen();
|
||||
|
||||
private Q_SLOTS:
|
||||
void doStopThread();
|
||||
|
@ -70,6 +81,13 @@ private Q_SLOTS:
|
|||
void onDisplayWindowResized(int width, int height);
|
||||
|
||||
private:
|
||||
using InputButtonHandler = std::function<void(bool)>;
|
||||
|
||||
enum : u32
|
||||
{
|
||||
NUM_SAVE_STATE_HOTKEYS = 8
|
||||
};
|
||||
|
||||
class Thread : public QThread
|
||||
{
|
||||
public:
|
||||
|
@ -85,6 +103,10 @@ private:
|
|||
|
||||
void checkSettings();
|
||||
void createGameList();
|
||||
void updateControllerInputMap();
|
||||
void updateHotkeyInputMap();
|
||||
void addButtonToInputMap(const QString& binding, InputButtonHandler handler);
|
||||
void updateFullscreen();
|
||||
void createThread();
|
||||
void stopThread();
|
||||
void threadEntryPoint();
|
||||
|
@ -100,5 +122,5 @@ private:
|
|||
std::atomic_bool m_shutdown_flag{false};
|
||||
|
||||
// input key maps, todo hotkeys
|
||||
std::map<int, std::function<void(bool)>> m_keyboard_input_handlers;
|
||||
std::map<int, InputButtonHandler> m_keyboard_input_handlers;
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "consolesettingswidget.h"
|
||||
#include "gamelistsettingswidget.h"
|
||||
#include "gpusettingswidget.h"
|
||||
#include "hotkeysettingswidget.h"
|
||||
#include "portsettingswidget.h"
|
||||
#include "qthostinterface.h"
|
||||
#include <QtWidgets/QTextEdit>
|
||||
|
@ -11,17 +12,19 @@ SettingsDialog::SettingsDialog(QtHostInterface* host_interface, QWidget* parent
|
|||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
m_console_settings = new ConsoleSettingsWidget(host_interface, m_ui.settingsContainer);
|
||||
m_game_list_settings = new GameListSettingsWidget(host_interface, m_ui.settingsContainer);
|
||||
m_hotkey_settings = new HotkeySettingsWidget(host_interface, m_ui.settingsContainer);
|
||||
m_console_settings = new ConsoleSettingsWidget(host_interface, m_ui.settingsContainer);
|
||||
m_port_settings = new PortSettingsWidget(host_interface, m_ui.settingsContainer);
|
||||
m_gpu_settings = new GPUSettingsWidget(host_interface, m_ui.settingsContainer);
|
||||
m_audio_settings = new QWidget(m_ui.settingsContainer);
|
||||
|
||||
m_ui.settingsContainer->insertWidget(0, m_console_settings);
|
||||
m_ui.settingsContainer->insertWidget(1, m_game_list_settings);
|
||||
m_ui.settingsContainer->insertWidget(2, m_port_settings);
|
||||
m_ui.settingsContainer->insertWidget(3, m_gpu_settings);
|
||||
m_ui.settingsContainer->insertWidget(4, m_audio_settings);
|
||||
m_ui.settingsContainer->insertWidget(0, m_game_list_settings);
|
||||
m_ui.settingsContainer->insertWidget(1, m_hotkey_settings);
|
||||
m_ui.settingsContainer->insertWidget(2, m_console_settings);
|
||||
m_ui.settingsContainer->insertWidget(3, m_port_settings);
|
||||
m_ui.settingsContainer->insertWidget(4, m_gpu_settings);
|
||||
m_ui.settingsContainer->insertWidget(5, m_audio_settings);
|
||||
|
||||
m_ui.settingsCategory->setCurrentRow(0);
|
||||
m_ui.settingsContainer->setCurrentIndex(0);
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include <QtWidgets/QDialog>
|
||||
#include "ui_settingsdialog.h"
|
||||
#include <QtWidgets/QDialog>
|
||||
|
||||
class QtHostInterface;
|
||||
|
||||
class GameListSettingsWidget;
|
||||
class HotkeySettingsWidget;
|
||||
class ConsoleSettingsWidget;
|
||||
class PortSettingsWidget;
|
||||
class GPUSettingsWidget;
|
||||
|
||||
class SettingsDialog : public QDialog
|
||||
{
|
||||
|
@ -14,15 +18,16 @@ class SettingsDialog : public QDialog
|
|||
public:
|
||||
enum class Category
|
||||
{
|
||||
ConsoleSettings,
|
||||
GameListSettings,
|
||||
HotkeySettings,
|
||||
ConsoleSettings,
|
||||
PortSettings,
|
||||
GPUSettings,
|
||||
AudioSettings,
|
||||
Count
|
||||
};
|
||||
|
||||
explicit SettingsDialog(QtHostInterface* host_interface, QWidget* parent = nullptr);
|
||||
SettingsDialog(QtHostInterface* host_interface, QWidget* parent = nullptr);
|
||||
~SettingsDialog();
|
||||
|
||||
public Q_SLOTS:
|
||||
|
@ -36,10 +41,10 @@ private:
|
|||
|
||||
QtHostInterface* m_host_interface;
|
||||
|
||||
GameListSettingsWidget* m_game_list_settings = nullptr;
|
||||
HotkeySettingsWidget* m_hotkey_settings = nullptr;
|
||||
ConsoleSettingsWidget* m_console_settings = nullptr;
|
||||
QWidget* m_game_list_settings = nullptr;
|
||||
QWidget* m_port_settings = nullptr;
|
||||
QWidget* m_cpu_settings = nullptr;
|
||||
QWidget* m_gpu_settings = nullptr;
|
||||
PortSettingsWidget* m_port_settings = nullptr;
|
||||
GPUSettingsWidget* m_gpu_settings = nullptr;
|
||||
QWidget* m_audio_settings = nullptr;
|
||||
};
|
||||
|
|
|
@ -40,15 +40,6 @@
|
|||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Console Settings</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="icons.qrc">
|
||||
<normaloff>:/icons/utilities-system-monitor.png</normaloff>:/icons/utilities-system-monitor.png</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Game List Settings</string>
|
||||
|
@ -58,6 +49,24 @@
|
|||
<normaloff>:/icons/folder-open.png</normaloff>:/icons/folder-open.png</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Hotkey Settings</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="icons.qrc">
|
||||
<normaloff>:/icons/applications-other.png</normaloff>:/icons/applications-other.png</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Console Settings</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="icons.qrc">
|
||||
<normaloff>:/icons/utilities-system-monitor.png</normaloff>:/icons/utilities-system-monitor.png</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Port Settings</string>
|
||||
|
|
Loading…
Reference in New Issue