From b135b32159651b54d61790886a0cc8185d698c44 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Thu, 2 Jan 2020 16:13:03 +1000 Subject: [PATCH] Qt: Add config and implementation for basic controller input --- src/duckstation-qt/CMakeLists.txt | 2 + src/duckstation-qt/duckstation-qt.vcxproj | 3 + .../duckstation-qt.vcxproj.filters | 3 + src/duckstation-qt/mainwindow.cpp | 2 + src/duckstation-qt/opengldisplaywindow.cpp | 17 +- src/duckstation-qt/opengldisplaywindow.h | 10 +- src/duckstation-qt/portsettingswidget.cpp | 211 ++++++++ src/duckstation-qt/portsettingswidget.h | 77 +++ src/duckstation-qt/qthostinterface.cpp | 105 +++- src/duckstation-qt/qthostinterface.h | 27 +- src/duckstation-qt/qtutils.cpp | 458 ++++++++++++++++++ src/duckstation-qt/qtutils.h | 8 + src/duckstation-qt/settingsdialog.cpp | 9 +- src/duckstation-qt/settingsdialog.h | 2 + src/duckstation-qt/settingsdialog.ui | 13 +- 15 files changed, 929 insertions(+), 18 deletions(-) create mode 100644 src/duckstation-qt/portsettingswidget.cpp create mode 100644 src/duckstation-qt/portsettingswidget.h diff --git a/src/duckstation-qt/CMakeLists.txt b/src/duckstation-qt/CMakeLists.txt index eec9bf139..3f9f16d9f 100644 --- a/src/duckstation-qt/CMakeLists.txt +++ b/src/duckstation-qt/CMakeLists.txt @@ -18,6 +18,8 @@ add_executable(duckstation-qt mainwindow.ui opengldisplaywindow.cpp opengldisplaywindow.h + portsettingswidget.cpp + portsettingswidget.h qthostinterface.cpp qthostinterface.h qtsettingsinterface.cpp diff --git a/src/duckstation-qt/duckstation-qt.vcxproj b/src/duckstation-qt/duckstation-qt.vcxproj index c2479fb40..38e54dc7d 100644 --- a/src/duckstation-qt/duckstation-qt.vcxproj +++ b/src/duckstation-qt/duckstation-qt.vcxproj @@ -41,12 +41,14 @@ + + @@ -100,6 +102,7 @@ + diff --git a/src/duckstation-qt/duckstation-qt.vcxproj.filters b/src/duckstation-qt/duckstation-qt.vcxproj.filters index 38de9472d..eea141aec 100644 --- a/src/duckstation-qt/duckstation-qt.vcxproj.filters +++ b/src/duckstation-qt/duckstation-qt.vcxproj.filters @@ -19,6 +19,8 @@ + + @@ -41,6 +43,7 @@ + diff --git a/src/duckstation-qt/mainwindow.cpp b/src/duckstation-qt/mainwindow.cpp index 4e6956d3d..bca619558 100644 --- a/src/duckstation-qt/mainwindow.cpp +++ b/src/duckstation-qt/mainwindow.cpp @@ -159,6 +159,8 @@ void MainWindow::connectSignals() connect(m_ui.actionSettings, &QAction::triggered, [this]() { doSettings(SettingsDialog::Category::Count); }); connect(m_ui.actionGameListSettings, &QAction::triggered, [this]() { doSettings(SettingsDialog::Category::GameListSettings); }); + connect(m_ui.actionPortSettings, &QAction::triggered, + [this]() { doSettings(SettingsDialog::Category::PortSettings); }); connect(m_ui.actionCPUSettings, &QAction::triggered, [this]() { doSettings(SettingsDialog::Category::CPUSettings); }); connect(m_ui.actionGPUSettings, &QAction::triggered, [this]() { doSettings(SettingsDialog::Category::GPUSettings); }); connect(m_ui.actionAudioSettings, &QAction::triggered, diff --git a/src/duckstation-qt/opengldisplaywindow.cpp b/src/duckstation-qt/opengldisplaywindow.cpp index ba1c72402..c1e0984d9 100644 --- a/src/duckstation-qt/opengldisplaywindow.cpp +++ b/src/duckstation-qt/opengldisplaywindow.cpp @@ -1,6 +1,8 @@ #include "opengldisplaywindow.h" #include "YBaseLib/Assert.h" #include "YBaseLib/Log.h" +#include "qthostinterface.h" +#include #include #include Log_SetChannel(OpenGLDisplayWindow); @@ -56,7 +58,8 @@ private: u32 m_height; }; -OpenGLDisplayWindow::OpenGLDisplayWindow(QWindow* parent) : QWindow(parent) +OpenGLDisplayWindow::OpenGLDisplayWindow(QtHostInterface* host_interface, QWindow* parent) + : QWindow(parent), m_host_interface(host_interface) { setSurfaceType(QWindow::OpenGLSurface); } @@ -151,6 +154,16 @@ std::tuple OpenGLDisplayWindow::GetWindowSize() const void OpenGLDisplayWindow::WindowResized() {} +void OpenGLDisplayWindow::keyPressEvent(QKeyEvent* event) +{ + m_host_interface->handleKeyEvent(event->key(), true); +} + +void OpenGLDisplayWindow::keyReleaseEvent(QKeyEvent* event) +{ + m_host_interface->handleKeyEvent(event->key(), false); +} + const char* OpenGLDisplayWindow::GetGLSLVersionString() const { return m_is_gles ? "#version 300 es" : "#version 130\n"; @@ -278,7 +291,7 @@ bool OpenGLDisplayWindow::initializeGLContext() return false; } -#if 1 +#if 0 if (GLAD_GL_KHR_debug) { glad_glDebugMessageCallbackKHR(GLDebugCallback, nullptr); diff --git a/src/duckstation-qt/opengldisplaywindow.h b/src/duckstation-qt/opengldisplaywindow.h index 0749fb2a3..516ac7543 100644 --- a/src/duckstation-qt/opengldisplaywindow.h +++ b/src/duckstation-qt/opengldisplaywindow.h @@ -9,12 +9,14 @@ #include #include +class QtHostInterface; + class OpenGLDisplayWindow final : public QWindow, public HostDisplay { Q_OBJECT public: - explicit OpenGLDisplayWindow(QWindow* parent); + OpenGLDisplayWindow(QtHostInterface* host_interface, QWindow* parent); ~OpenGLDisplayWindow(); bool createGLContext(QThread* worker_thread); @@ -43,6 +45,10 @@ public: std::tuple GetWindowSize() const override; void WindowResized() override; +protected: + void keyPressEvent(QKeyEvent* event); + void keyReleaseEvent(QKeyEvent* event); + private: const char* GetGLSLVersionString() const; std::string GetGLSLVersionHeader() const; @@ -53,6 +59,8 @@ private: void Render(); void RenderDisplay(); + QtHostInterface* m_host_interface; + QOpenGLContext* m_gl_context = nullptr; GL::Program m_display_program; diff --git a/src/duckstation-qt/portsettingswidget.cpp b/src/duckstation-qt/portsettingswidget.cpp new file mode 100644 index 000000000..c83736252 --- /dev/null +++ b/src/duckstation-qt/portsettingswidget.cpp @@ -0,0 +1,211 @@ +#include "portsettingswidget.h" +#include "core/controller.h" +#include "core/settings.h" +#include "qthostinterface.h" +#include "qtutils.h" +#include +#include + +PortSettingsWidget::PortSettingsWidget(QtHostInterface* host_interface, QWidget* parent /* = nullptr */) + : QWidget(parent), m_host_interface(host_interface) +{ + createUi(); +} + +PortSettingsWidget::~PortSettingsWidget() = default; + +void PortSettingsWidget::createUi() +{ + QGridLayout* layout = new QGridLayout(this); + + m_tab_widget = new QTabWidget(this); + for (int i = 0; i < static_cast(m_port_ui.size()); i++) + createPortSettingsUi(i, &m_port_ui[i]); + + layout->addWidget(m_tab_widget, 0, 0, 1, 1); + + setLayout(layout); +} + +void PortSettingsWidget::createPortSettingsUi(int index, PortSettingsUI* ui) +{ + const Settings& settings = m_host_interface->GetCoreSettings(); + + ui->widget = new QWidget(m_tab_widget); + ui->layout = new QVBoxLayout(ui->widget); + + QHBoxLayout* memory_card_layout = new QHBoxLayout(); + ui->memory_card_path = new QLineEdit(QString::fromStdString(settings.memory_card_paths[index]), ui->widget); + memory_card_layout->addWidget(ui->memory_card_path); + ui->memory_card_path_browse = new QPushButton(tr("Browse..."), ui->widget); + memory_card_layout->addWidget(ui->memory_card_path_browse); + ui->layout->addWidget(new QLabel(tr("Memory Card Path:"), ui->widget)); + ui->layout->addLayout(memory_card_layout); + + ui->controller_type = new QComboBox(ui->widget); + for (int i = 0; i < static_cast(ControllerType::Count); i++) + { + ui->controller_type->addItem( + QString::fromLocal8Bit(Settings::GetControllerTypeDisplayName(static_cast(i)))); + } + ui->controller_type->setCurrentIndex(static_cast(settings.controller_types[index])); + connect(ui->controller_type, static_cast(&QComboBox::currentIndexChanged), + [this, index]() { onControllerTypeChanged(index); }); + ui->layout->addWidget(new QLabel(tr("Controller Type:"), ui->widget)); + ui->layout->addWidget(ui->controller_type); + + createPortBindingSettingsUi(index, ui); + + ui->layout->addStretch(1); + + ui->widget->setLayout(ui->layout); + + m_tab_widget->addTab(ui->widget, tr("Port %1").arg(index + 1)); +} + +void PortSettingsWidget::createPortBindingSettingsUi(int index, PortSettingsUI* ui) +{ + QWidget* container = new QWidget(ui->widget); + QGridLayout* layout = new QGridLayout(container); + layout->setContentsMargins(0, 0, 0, 0); + const ControllerType ctype = m_host_interface->GetCoreSettings().controller_types[index]; + const auto buttons = Controller::GetButtonNames(ctype); + + if (!buttons.empty()) + { + QFrame* line = new QFrame(container); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + layout->addWidget(line, 0, 0, 1, 4); + layout->addWidget(new QLabel(tr("Button Bindings:"), container), 1, 0, 1, 4); + + const int start_row = 2; + const int num_rows = (static_cast(buttons.size()) + 1) / 2; + int current_row = 0; + int current_column = 0; + for (const auto& [button_name, button_code] : buttons) + { + if (current_row == num_rows) + { + current_row = 0; + current_column += 2; + } + + 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); + layout->addWidget(label, start_row + current_row, current_column); + layout->addWidget(button, start_row + current_row, current_column + 1); + + current_row++; + } + } + + if (ui->button_binding_container) + { + QLayoutItem* old_item = ui->layout->replaceWidget(ui->button_binding_container, container); + Q_ASSERT(old_item != nullptr); + + delete old_item; + delete ui->button_binding_container; + } + else + { + ui->layout->addWidget(container); + } + ui->button_binding_container = container; +} + +void PortSettingsWidget::onControllerTypeChanged(int index) +{ + const int type_index = m_port_ui[index].controller_type->currentIndex(); + if (type_index < 0 || type_index >= static_cast(ControllerType::Count)) + return; + + m_host_interface->GetCoreSettings().controller_types[index] = static_cast(type_index); + m_host_interface->getQSettings().setValue( + QStringLiteral("Controller%1/Type").arg(index + 1), + QString::fromStdString(Settings::GetControllerTypeName(static_cast(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; +} diff --git a/src/duckstation-qt/portsettingswidget.h b/src/duckstation-qt/portsettingswidget.h new file mode 100644 index 000000000..151a422f2 --- /dev/null +++ b/src/duckstation-qt/portsettingswidget.h @@ -0,0 +1,77 @@ +#pragma once +#include "core/types.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QTimer; + +class QtHostInterface; +class InputButtonBindingWidget; + +class PortSettingsWidget : public QWidget +{ + Q_OBJECT + +public: + PortSettingsWidget(QtHostInterface* host_interface, QWidget* parent = nullptr); + ~PortSettingsWidget(); + +private: + QtHostInterface* m_host_interface; + + QTabWidget* m_tab_widget; + + struct PortSettingsUI + { + QWidget* widget; + QVBoxLayout* layout; + QComboBox* controller_type; + QLineEdit* memory_card_path; + QPushButton* memory_card_path_browse; + QWidget* button_binding_container; + }; + + void createUi(); + void createPortSettingsUi(int index, PortSettingsUI* ui); + void createPortBindingSettingsUi(int index, PortSettingsUI* ui); + void onControllerTypeChanged(int index); + + std::array 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; +}; diff --git a/src/duckstation-qt/qthostinterface.cpp b/src/duckstation-qt/qthostinterface.cpp index b7d36548a..98074e296 100644 --- a/src/duckstation-qt/qthostinterface.cpp +++ b/src/duckstation-qt/qthostinterface.cpp @@ -1,11 +1,14 @@ #include "qthostinterface.h" #include "YBaseLib/Log.h" #include "common/null_audio_stream.h" +#include "core/controller.h" #include "core/game_list.h" #include "core/gpu.h" #include "core/system.h" #include "qtsettingsinterface.h" +#include "qtutils.h" #include +#include #include #include Log_SetChannel(QtHostInterface); @@ -15,6 +18,7 @@ QtHostInterface::QtHostInterface(QObject* parent) { checkSettings(); createGameList(); + doUpdateInputMap(); createThread(); } @@ -37,6 +41,24 @@ void QtHostInterface::ReportMessage(const char* message) void QtHostInterface::setDefaultSettings() { m_settings.SetDefaults(); + + // default input settings for Qt + m_settings.controller_types[0] = ControllerType::DigitalController; + m_qsettings.setValue(QStringLiteral("Controller1/ButtonUp"), QStringLiteral("Keyboard/W")); + m_qsettings.setValue(QStringLiteral("Controller1/ButtonDown"), QStringLiteral("Keyboard/S")); + m_qsettings.setValue(QStringLiteral("Controller1/ButtonLeft"), QStringLiteral("Keyboard/A")); + m_qsettings.setValue(QStringLiteral("Controller1/ButtonRight"), QStringLiteral("Keyboard/D")); + m_qsettings.setValue(QStringLiteral("Controller1/ButtonSelect"), QStringLiteral("Keyboard/Backspace")); + m_qsettings.setValue(QStringLiteral("Controller1/ButtonStart"), QStringLiteral("Keyboard/Return")); + m_qsettings.setValue(QStringLiteral("Controller1/ButtonTriangle"), QStringLiteral("Keyboard/8")); + m_qsettings.setValue(QStringLiteral("Controller1/ButtonCross"), QStringLiteral("Keyboard/2")); + m_qsettings.setValue(QStringLiteral("Controller1/ButtonSquare"), QStringLiteral("Keyboard/4")); + m_qsettings.setValue(QStringLiteral("Controller1/ButtonCircle"), QStringLiteral("Keyboard/6")); + m_qsettings.setValue(QStringLiteral("Controller1/ButtonL1"), QStringLiteral("Keyboard/Q")); + m_qsettings.setValue(QStringLiteral("Controller1/ButtonL2"), QStringLiteral("Keyboard/1")); + m_qsettings.setValue(QStringLiteral("Controller1/ButtonR1"), QStringLiteral("Keyboard/E")); + m_qsettings.setValue(QStringLiteral("Controller1/ButtonR2"), QStringLiteral("Keyboard/3")); + updateQSettings(); } @@ -107,7 +129,7 @@ void QtHostInterface::refreshGameList(bool invalidate_cache /*= false*/) QWidget* QtHostInterface::createDisplayWidget(QWidget* parent) { - m_opengl_display_window = new OpenGLDisplayWindow(nullptr); + m_opengl_display_window = new OpenGLDisplayWindow(this, nullptr); m_display.release(); m_display = std::unique_ptr(static_cast(m_opengl_display_window)); return QWidget::createWindowContainer(m_opengl_display_window, parent); @@ -134,6 +156,87 @@ void QtHostInterface::bootSystem(QString initial_filename, QString initial_save_ Q_ARG(QString, initial_save_state_filename)); } +void QtHostInterface::handleKeyEvent(int key, bool pressed) +{ + if (!isOnWorkerThread()) + { + QMetaObject::invokeMethod(this, "doHandleKeyEvent", Qt::QueuedConnection, Q_ARG(int, key), Q_ARG(bool, pressed)); + return; + } + + doHandleKeyEvent(key, pressed); +} + +void QtHostInterface::doHandleKeyEvent(int key, bool pressed) +{ + const auto iter = m_keyboard_input_handlers.find(key); + if (iter == m_keyboard_input_handlers.end()) + return; + + iter->second(pressed); +} + +void QtHostInterface::updateInputMap() +{ + if (!isOnWorkerThread()) + { + QMetaObject::invokeMethod(this, "doUpdateInputMap", Qt::QueuedConnection); + return; + } + + doUpdateInputMap(); +} + +void QtHostInterface::doUpdateInputMap() +{ + m_keyboard_input_handlers.clear(); + + for (u32 controller_index = 0; controller_index < 2; controller_index++) + { + const ControllerType ctype = m_settings.controller_types[controller_index]; + if (ctype == ControllerType::None) + continue; + + const auto button_names = Controller::GetButtonNames(ctype); + for (const auto& [button_name, button_code] : button_names) + { + QVariant var = m_qsettings.value( + QStringLiteral("Controller%1/Button%2").arg(controller_index + 1).arg(QString::fromStdString(button_name))); + if (!var.isValid()) + continue; + + auto handler = [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 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; + } + } + } +} + void QtHostInterface::powerOffSystem() { if (!isOnWorkerThread()) diff --git a/src/duckstation-qt/qthostinterface.h b/src/duckstation-qt/qthostinterface.h index d6034bba1..024b96c3a 100644 --- a/src/duckstation-qt/qthostinterface.h +++ b/src/duckstation-qt/qthostinterface.h @@ -1,11 +1,13 @@ #pragma once -#include -#include -#include -#include -#include #include "core/host_interface.h" #include "opengldisplaywindow.h" +#include +#include +#include +#include +#include +#include +#include class QWidget; @@ -30,7 +32,7 @@ public: const Settings& GetCoreSettings() const { return m_settings; } Settings& GetCoreSettings() { return m_settings; } - //void UpdateCoreSettingsGPU(); + // void UpdateCoreSettingsGPU(); const GameList* getGameList() const { return m_game_list.get(); } GameList* getGameList() { return m_game_list.get(); } @@ -44,6 +46,9 @@ public: void bootSystem(QString initial_filename, QString initial_save_state_filename); + void updateInputMap(); + void handleKeyEvent(int key, bool pressed); + Q_SIGNALS: void emulationStarting(); void emulationStarted(); @@ -58,8 +63,10 @@ public Q_SLOTS: void changeDisc(QString new_disc_filename); private Q_SLOTS: - void doBootSystem(QString initial_filename, QString initial_save_state_filename); void doStopThread(); + void doBootSystem(QString initial_filename, QString initial_save_state_filename); + void doUpdateInputMap(); + void doHandleKeyEvent(int key, bool pressed); private: class Thread : public QThread @@ -89,6 +96,8 @@ private: QThread* m_original_thread = nullptr; Thread* m_worker_thread = nullptr; - std::atomic_bool m_shutdown_flag{ false }; -}; + std::atomic_bool m_shutdown_flag{false}; + // input key maps, todo hotkeys + std::map> m_keyboard_input_handlers; +}; diff --git a/src/duckstation-qt/qtutils.cpp b/src/duckstation-qt/qtutils.cpp index a1295d784..7f7ec12a5 100644 --- a/src/duckstation-qt/qtutils.cpp +++ b/src/duckstation-qt/qtutils.cpp @@ -1,6 +1,7 @@ #include "qtutils.h" #include #include +#include namespace QtUtils { @@ -20,4 +21,461 @@ void ResizeColumnsForTableView(QTableView* view, const std::initializer_list s_qt_key_names = { + {Qt::Key_Escape, QStringLiteral("Escape")}, + {Qt::Key_Tab, QStringLiteral("Tab")}, + {Qt::Key_Backtab, QStringLiteral("Backtab")}, + {Qt::Key_Backspace, QStringLiteral("Backspace")}, + {Qt::Key_Return, QStringLiteral("Return")}, + {Qt::Key_Enter, QStringLiteral("Enter")}, + {Qt::Key_Insert, QStringLiteral("Insert")}, + {Qt::Key_Delete, QStringLiteral("Delete")}, + {Qt::Key_Pause, QStringLiteral("Pause")}, + {Qt::Key_Print, QStringLiteral("Print")}, + {Qt::Key_SysReq, QStringLiteral("SysReq")}, + {Qt::Key_Clear, QStringLiteral("Clear")}, + {Qt::Key_Home, QStringLiteral("Home")}, + {Qt::Key_End, QStringLiteral("End")}, + {Qt::Key_Left, QStringLiteral("Left")}, + {Qt::Key_Up, QStringLiteral("Up")}, + {Qt::Key_Right, QStringLiteral("Right")}, + {Qt::Key_Down, QStringLiteral("Down")}, + {Qt::Key_PageUp, QStringLiteral("PageUp")}, + {Qt::Key_PageDown, QStringLiteral("PageDown")}, + {Qt::Key_Shift, QStringLiteral("Shift")}, + {Qt::Key_Control, QStringLiteral("Control")}, + {Qt::Key_Meta, QStringLiteral("Meta")}, + {Qt::Key_Alt, QStringLiteral("Alt")}, + {Qt::Key_CapsLock, QStringLiteral("CapsLock")}, + {Qt::Key_NumLock, QStringLiteral("NumLock")}, + {Qt::Key_ScrollLock, QStringLiteral("ScrollLock")}, + {Qt::Key_F1, QStringLiteral("F1")}, + {Qt::Key_F2, QStringLiteral("F2")}, + {Qt::Key_F3, QStringLiteral("F3")}, + {Qt::Key_F4, QStringLiteral("F4")}, + {Qt::Key_F5, QStringLiteral("F5")}, + {Qt::Key_F6, QStringLiteral("F6")}, + {Qt::Key_F7, QStringLiteral("F7")}, + {Qt::Key_F8, QStringLiteral("F8")}, + {Qt::Key_F9, QStringLiteral("F9")}, + {Qt::Key_F10, QStringLiteral("F10")}, + {Qt::Key_F11, QStringLiteral("F11")}, + {Qt::Key_F12, QStringLiteral("F12")}, + {Qt::Key_F13, QStringLiteral("F13")}, + {Qt::Key_F14, QStringLiteral("F14")}, + {Qt::Key_F15, QStringLiteral("F15")}, + {Qt::Key_F16, QStringLiteral("F16")}, + {Qt::Key_F17, QStringLiteral("F17")}, + {Qt::Key_F18, QStringLiteral("F18")}, + {Qt::Key_F19, QStringLiteral("F19")}, + {Qt::Key_F20, QStringLiteral("F20")}, + {Qt::Key_F21, QStringLiteral("F21")}, + {Qt::Key_F22, QStringLiteral("F22")}, + {Qt::Key_F23, QStringLiteral("F23")}, + {Qt::Key_F24, QStringLiteral("F24")}, + {Qt::Key_F25, QStringLiteral("F25")}, + {Qt::Key_F26, QStringLiteral("F26")}, + {Qt::Key_F27, QStringLiteral("F27")}, + {Qt::Key_F28, QStringLiteral("F28")}, + {Qt::Key_F29, QStringLiteral("F29")}, + {Qt::Key_F30, QStringLiteral("F30")}, + {Qt::Key_F31, QStringLiteral("F31")}, + {Qt::Key_F32, QStringLiteral("F32")}, + {Qt::Key_F33, QStringLiteral("F33")}, + {Qt::Key_F34, QStringLiteral("F34")}, + {Qt::Key_F35, QStringLiteral("F35")}, + {Qt::Key_Super_L, QStringLiteral("Super_L")}, + {Qt::Key_Super_R, QStringLiteral("Super_R")}, + {Qt::Key_Menu, QStringLiteral("Menu")}, + {Qt::Key_Hyper_L, QStringLiteral("Hyper_L")}, + {Qt::Key_Hyper_R, QStringLiteral("Hyper_R")}, + {Qt::Key_Help, QStringLiteral("Help")}, + {Qt::Key_Direction_L, QStringLiteral("Direction_L")}, + {Qt::Key_Direction_R, QStringLiteral("Direction_R")}, + {Qt::Key_Space, QStringLiteral("Space")}, + {Qt::Key_Any, QStringLiteral("Any")}, + {Qt::Key_Exclam, QStringLiteral("Exclam")}, + {Qt::Key_QuoteDbl, QStringLiteral("QuoteDbl")}, + {Qt::Key_NumberSign, QStringLiteral("NumberSign")}, + {Qt::Key_Dollar, QStringLiteral("Dollar")}, + {Qt::Key_Percent, QStringLiteral("Percent")}, + {Qt::Key_Ampersand, QStringLiteral("Ampersand")}, + {Qt::Key_Apostrophe, QStringLiteral("Apostrophe")}, + {Qt::Key_ParenLeft, QStringLiteral("ParenLeft")}, + {Qt::Key_ParenRight, QStringLiteral("ParenRight")}, + {Qt::Key_Asterisk, QStringLiteral("Asterisk")}, + {Qt::Key_Plus, QStringLiteral("Plus")}, + {Qt::Key_Comma, QStringLiteral("Comma")}, + {Qt::Key_Minus, QStringLiteral("Minus")}, + {Qt::Key_Period, QStringLiteral("Period")}, + {Qt::Key_Slash, QStringLiteral("Slash")}, + {Qt::Key_0, QStringLiteral("0")}, + {Qt::Key_1, QStringLiteral("1")}, + {Qt::Key_2, QStringLiteral("2")}, + {Qt::Key_3, QStringLiteral("3")}, + {Qt::Key_4, QStringLiteral("4")}, + {Qt::Key_5, QStringLiteral("5")}, + {Qt::Key_6, QStringLiteral("6")}, + {Qt::Key_7, QStringLiteral("7")}, + {Qt::Key_8, QStringLiteral("8")}, + {Qt::Key_9, QStringLiteral("9")}, + {Qt::Key_Colon, QStringLiteral("Colon")}, + {Qt::Key_Semicolon, QStringLiteral("Semicolon")}, + {Qt::Key_Less, QStringLiteral("Less")}, + {Qt::Key_Equal, QStringLiteral("Equal")}, + {Qt::Key_Greater, QStringLiteral("Greater")}, + {Qt::Key_Question, QStringLiteral("Question")}, + {Qt::Key_At, QStringLiteral("At")}, + {Qt::Key_A, QStringLiteral("A")}, + {Qt::Key_B, QStringLiteral("B")}, + {Qt::Key_C, QStringLiteral("C")}, + {Qt::Key_D, QStringLiteral("D")}, + {Qt::Key_E, QStringLiteral("E")}, + {Qt::Key_F, QStringLiteral("F")}, + {Qt::Key_G, QStringLiteral("G")}, + {Qt::Key_H, QStringLiteral("H")}, + {Qt::Key_I, QStringLiteral("I")}, + {Qt::Key_J, QStringLiteral("J")}, + {Qt::Key_K, QStringLiteral("K")}, + {Qt::Key_L, QStringLiteral("L")}, + {Qt::Key_M, QStringLiteral("M")}, + {Qt::Key_N, QStringLiteral("N")}, + {Qt::Key_O, QStringLiteral("O")}, + {Qt::Key_P, QStringLiteral("P")}, + {Qt::Key_Q, QStringLiteral("Q")}, + {Qt::Key_R, QStringLiteral("R")}, + {Qt::Key_S, QStringLiteral("S")}, + {Qt::Key_T, QStringLiteral("T")}, + {Qt::Key_U, QStringLiteral("U")}, + {Qt::Key_V, QStringLiteral("V")}, + {Qt::Key_W, QStringLiteral("W")}, + {Qt::Key_X, QStringLiteral("X")}, + {Qt::Key_Y, QStringLiteral("Y")}, + {Qt::Key_Z, QStringLiteral("Z")}, + {Qt::Key_BracketLeft, QStringLiteral("BracketLeft")}, + {Qt::Key_Backslash, QStringLiteral("Backslash")}, + {Qt::Key_BracketRight, QStringLiteral("BracketRight")}, + {Qt::Key_AsciiCircum, QStringLiteral("AsciiCircum")}, + {Qt::Key_Underscore, QStringLiteral("Underscore")}, + {Qt::Key_QuoteLeft, QStringLiteral("QuoteLeft")}, + {Qt::Key_BraceLeft, QStringLiteral("BraceLeft")}, + {Qt::Key_Bar, QStringLiteral("Bar")}, + {Qt::Key_BraceRight, QStringLiteral("BraceRight")}, + {Qt::Key_AsciiTilde, QStringLiteral("AsciiTilde")}, + {Qt::Key_nobreakspace, QStringLiteral("nobreakspace")}, + {Qt::Key_exclamdown, QStringLiteral("exclamdown")}, + {Qt::Key_cent, QStringLiteral("cent")}, + {Qt::Key_sterling, QStringLiteral("sterling")}, + {Qt::Key_currency, QStringLiteral("currency")}, + {Qt::Key_yen, QStringLiteral("yen")}, + {Qt::Key_brokenbar, QStringLiteral("brokenbar")}, + {Qt::Key_section, QStringLiteral("section")}, + {Qt::Key_diaeresis, QStringLiteral("diaeresis")}, + {Qt::Key_copyright, QStringLiteral("copyright")}, + {Qt::Key_ordfeminine, QStringLiteral("ordfeminine")}, + {Qt::Key_guillemotleft, QStringLiteral("guillemotleft")}, + {Qt::Key_notsign, QStringLiteral("notsign")}, + {Qt::Key_hyphen, QStringLiteral("hyphen")}, + {Qt::Key_registered, QStringLiteral("registered")}, + {Qt::Key_macron, QStringLiteral("macron")}, + {Qt::Key_degree, QStringLiteral("degree")}, + {Qt::Key_plusminus, QStringLiteral("plusminus")}, + {Qt::Key_twosuperior, QStringLiteral("twosuperior")}, + {Qt::Key_threesuperior, QStringLiteral("threesuperior")}, + {Qt::Key_acute, QStringLiteral("acute")}, + {Qt::Key_mu, QStringLiteral("mu")}, + {Qt::Key_paragraph, QStringLiteral("paragraph")}, + {Qt::Key_periodcentered, QStringLiteral("periodcentered")}, + {Qt::Key_cedilla, QStringLiteral("cedilla")}, + {Qt::Key_onesuperior, QStringLiteral("onesuperior")}, + {Qt::Key_masculine, QStringLiteral("masculine")}, + {Qt::Key_guillemotright, QStringLiteral("guillemotright")}, + {Qt::Key_onequarter, QStringLiteral("onequarter")}, + {Qt::Key_onehalf, QStringLiteral("onehalf")}, + {Qt::Key_threequarters, QStringLiteral("threequarters")}, + {Qt::Key_questiondown, QStringLiteral("questiondown")}, + {Qt::Key_Agrave, QStringLiteral("Agrave")}, + {Qt::Key_Aacute, QStringLiteral("Aacute")}, + {Qt::Key_Acircumflex, QStringLiteral("Acircumflex")}, + {Qt::Key_Atilde, QStringLiteral("Atilde")}, + {Qt::Key_Adiaeresis, QStringLiteral("Adiaeresis")}, + {Qt::Key_Aring, QStringLiteral("Aring")}, + {Qt::Key_AE, QStringLiteral("AE")}, + {Qt::Key_Ccedilla, QStringLiteral("Ccedilla")}, + {Qt::Key_Egrave, QStringLiteral("Egrave")}, + {Qt::Key_Eacute, QStringLiteral("Eacute")}, + {Qt::Key_Ecircumflex, QStringLiteral("Ecircumflex")}, + {Qt::Key_Ediaeresis, QStringLiteral("Ediaeresis")}, + {Qt::Key_Igrave, QStringLiteral("Igrave")}, + {Qt::Key_Iacute, QStringLiteral("Iacute")}, + {Qt::Key_Icircumflex, QStringLiteral("Icircumflex")}, + {Qt::Key_Idiaeresis, QStringLiteral("Idiaeresis")}, + {Qt::Key_ETH, QStringLiteral("ETH")}, + {Qt::Key_Ntilde, QStringLiteral("Ntilde")}, + {Qt::Key_Ograve, QStringLiteral("Ograve")}, + {Qt::Key_Oacute, QStringLiteral("Oacute")}, + {Qt::Key_Ocircumflex, QStringLiteral("Ocircumflex")}, + {Qt::Key_Otilde, QStringLiteral("Otilde")}, + {Qt::Key_Odiaeresis, QStringLiteral("Odiaeresis")}, + {Qt::Key_multiply, QStringLiteral("multiply")}, + {Qt::Key_Ooblique, QStringLiteral("Ooblique")}, + {Qt::Key_Ugrave, QStringLiteral("Ugrave")}, + {Qt::Key_Uacute, QStringLiteral("Uacute")}, + {Qt::Key_Ucircumflex, QStringLiteral("Ucircumflex")}, + {Qt::Key_Udiaeresis, QStringLiteral("Udiaeresis")}, + {Qt::Key_Yacute, QStringLiteral("Yacute")}, + {Qt::Key_THORN, QStringLiteral("THORN")}, + {Qt::Key_ssharp, QStringLiteral("ssharp")}, + {Qt::Key_division, QStringLiteral("division")}, + {Qt::Key_ydiaeresis, QStringLiteral("ydiaeresis")}, + {Qt::Key_AltGr, QStringLiteral("AltGr")}, + {Qt::Key_Multi_key, QStringLiteral("Multi_key")}, + {Qt::Key_Codeinput, QStringLiteral("Codeinput")}, + {Qt::Key_SingleCandidate, QStringLiteral("SingleCandidate")}, + {Qt::Key_MultipleCandidate, QStringLiteral("MultipleCandidate")}, + {Qt::Key_PreviousCandidate, QStringLiteral("PreviousCandidate")}, + {Qt::Key_Mode_switch, QStringLiteral("Mode_switch")}, + {Qt::Key_Kanji, QStringLiteral("Kanji")}, + {Qt::Key_Muhenkan, QStringLiteral("Muhenkan")}, + {Qt::Key_Henkan, QStringLiteral("Henkan")}, + {Qt::Key_Romaji, QStringLiteral("Romaji")}, + {Qt::Key_Hiragana, QStringLiteral("Hiragana")}, + {Qt::Key_Katakana, QStringLiteral("Katakana")}, + {Qt::Key_Hiragana_Katakana, QStringLiteral("Hiragana_Katakana")}, + {Qt::Key_Zenkaku, QStringLiteral("Zenkaku")}, + {Qt::Key_Hankaku, QStringLiteral("Hankaku")}, + {Qt::Key_Zenkaku_Hankaku, QStringLiteral("Zenkaku_Hankaku")}, + {Qt::Key_Touroku, QStringLiteral("Touroku")}, + {Qt::Key_Massyo, QStringLiteral("Massyo")}, + {Qt::Key_Kana_Lock, QStringLiteral("Kana_Lock")}, + {Qt::Key_Kana_Shift, QStringLiteral("Kana_Shift")}, + {Qt::Key_Eisu_Shift, QStringLiteral("Eisu_Shift")}, + {Qt::Key_Eisu_toggle, QStringLiteral("Eisu_toggle")}, + {Qt::Key_Hangul, QStringLiteral("Hangul")}, + {Qt::Key_Hangul_Start, QStringLiteral("Hangul_Start")}, + {Qt::Key_Hangul_End, QStringLiteral("Hangul_End")}, + {Qt::Key_Hangul_Hanja, QStringLiteral("Hangul_Hanja")}, + {Qt::Key_Hangul_Jamo, QStringLiteral("Hangul_Jamo")}, + {Qt::Key_Hangul_Romaja, QStringLiteral("Hangul_Romaja")}, + {Qt::Key_Hangul_Jeonja, QStringLiteral("Hangul_Jeonja")}, + {Qt::Key_Hangul_Banja, QStringLiteral("Hangul_Banja")}, + {Qt::Key_Hangul_PreHanja, QStringLiteral("Hangul_PreHanja")}, + {Qt::Key_Hangul_PostHanja, QStringLiteral("Hangul_PostHanja")}, + {Qt::Key_Hangul_Special, QStringLiteral("Hangul_Special")}, + {Qt::Key_Dead_Grave, QStringLiteral("Dead_Grave")}, + {Qt::Key_Dead_Acute, QStringLiteral("Dead_Acute")}, + {Qt::Key_Dead_Circumflex, QStringLiteral("Dead_Circumflex")}, + {Qt::Key_Dead_Tilde, QStringLiteral("Dead_Tilde")}, + {Qt::Key_Dead_Macron, QStringLiteral("Dead_Macron")}, + {Qt::Key_Dead_Breve, QStringLiteral("Dead_Breve")}, + {Qt::Key_Dead_Abovedot, QStringLiteral("Dead_Abovedot")}, + {Qt::Key_Dead_Diaeresis, QStringLiteral("Dead_Diaeresis")}, + {Qt::Key_Dead_Abovering, QStringLiteral("Dead_Abovering")}, + {Qt::Key_Dead_Doubleacute, QStringLiteral("Dead_Doubleacute")}, + {Qt::Key_Dead_Caron, QStringLiteral("Dead_Caron")}, + {Qt::Key_Dead_Cedilla, QStringLiteral("Dead_Cedilla")}, + {Qt::Key_Dead_Ogonek, QStringLiteral("Dead_Ogonek")}, + {Qt::Key_Dead_Iota, QStringLiteral("Dead_Iota")}, + {Qt::Key_Dead_Voiced_Sound, QStringLiteral("Dead_Voiced_Sound")}, + {Qt::Key_Dead_Semivoiced_Sound, QStringLiteral("Dead_Semivoiced_Sound")}, + {Qt::Key_Dead_Belowdot, QStringLiteral("Dead_Belowdot")}, + {Qt::Key_Dead_Hook, QStringLiteral("Dead_Hook")}, + {Qt::Key_Dead_Horn, QStringLiteral("Dead_Horn")}, + {Qt::Key_Back, QStringLiteral("Back")}, + {Qt::Key_Forward, QStringLiteral("Forward")}, + {Qt::Key_Stop, QStringLiteral("Stop")}, + {Qt::Key_Refresh, QStringLiteral("Refresh")}, + {Qt::Key_VolumeDown, QStringLiteral("VolumeDown")}, + {Qt::Key_VolumeMute, QStringLiteral("VolumeMute")}, + {Qt::Key_VolumeUp, QStringLiteral("VolumeUp")}, + {Qt::Key_BassBoost, QStringLiteral("BassBoost")}, + {Qt::Key_BassUp, QStringLiteral("BassUp")}, + {Qt::Key_BassDown, QStringLiteral("BassDown")}, + {Qt::Key_TrebleUp, QStringLiteral("TrebleUp")}, + {Qt::Key_TrebleDown, QStringLiteral("TrebleDown")}, + {Qt::Key_MediaPlay, QStringLiteral("MediaPlay")}, + {Qt::Key_MediaStop, QStringLiteral("MediaStop")}, + {Qt::Key_MediaPrevious, QStringLiteral("MediaPrevious")}, + {Qt::Key_MediaNext, QStringLiteral("MediaNext")}, + {Qt::Key_MediaRecord, QStringLiteral("MediaRecord")}, + {Qt::Key_MediaPause, QStringLiteral("MediaPause")}, + {Qt::Key_MediaTogglePlayPause, QStringLiteral("MediaTogglePlayPause")}, + {Qt::Key_HomePage, QStringLiteral("HomePage")}, + {Qt::Key_Favorites, QStringLiteral("Favorites")}, + {Qt::Key_Search, QStringLiteral("Search")}, + {Qt::Key_Standby, QStringLiteral("Standby")}, + {Qt::Key_OpenUrl, QStringLiteral("OpenUrl")}, + {Qt::Key_LaunchMail, QStringLiteral("LaunchMail")}, + {Qt::Key_LaunchMedia, QStringLiteral("LaunchMedia")}, + {Qt::Key_Launch0, QStringLiteral("Launch0")}, + {Qt::Key_Launch1, QStringLiteral("Launch1")}, + {Qt::Key_Launch2, QStringLiteral("Launch2")}, + {Qt::Key_Launch3, QStringLiteral("Launch3")}, + {Qt::Key_Launch4, QStringLiteral("Launch4")}, + {Qt::Key_Launch5, QStringLiteral("Launch5")}, + {Qt::Key_Launch6, QStringLiteral("Launch6")}, + {Qt::Key_Launch7, QStringLiteral("Launch7")}, + {Qt::Key_Launch8, QStringLiteral("Launch8")}, + {Qt::Key_Launch9, QStringLiteral("Launch9")}, + {Qt::Key_LaunchA, QStringLiteral("LaunchA")}, + {Qt::Key_LaunchB, QStringLiteral("LaunchB")}, + {Qt::Key_LaunchC, QStringLiteral("LaunchC")}, + {Qt::Key_LaunchD, QStringLiteral("LaunchD")}, + {Qt::Key_LaunchE, QStringLiteral("LaunchE")}, + {Qt::Key_LaunchF, QStringLiteral("LaunchF")}, + {Qt::Key_MonBrightnessUp, QStringLiteral("MonBrightnessUp")}, + {Qt::Key_MonBrightnessDown, QStringLiteral("MonBrightnessDown")}, + {Qt::Key_KeyboardLightOnOff, QStringLiteral("KeyboardLightOnOff")}, + {Qt::Key_KeyboardBrightnessUp, QStringLiteral("KeyboardBrightnessUp")}, + {Qt::Key_KeyboardBrightnessDown, QStringLiteral("KeyboardBrightnessDown")}, + {Qt::Key_PowerOff, QStringLiteral("PowerOff")}, + {Qt::Key_WakeUp, QStringLiteral("WakeUp")}, + {Qt::Key_Eject, QStringLiteral("Eject")}, + {Qt::Key_ScreenSaver, QStringLiteral("ScreenSaver")}, + {Qt::Key_WWW, QStringLiteral("WWW")}, + {Qt::Key_Memo, QStringLiteral("Memo")}, + {Qt::Key_LightBulb, QStringLiteral("LightBulb")}, + {Qt::Key_Shop, QStringLiteral("Shop")}, + {Qt::Key_History, QStringLiteral("History")}, + {Qt::Key_AddFavorite, QStringLiteral("AddFavorite")}, + {Qt::Key_HotLinks, QStringLiteral("HotLinks")}, + {Qt::Key_BrightnessAdjust, QStringLiteral("BrightnessAdjust")}, + {Qt::Key_Finance, QStringLiteral("Finance")}, + {Qt::Key_Community, QStringLiteral("Community")}, + {Qt::Key_AudioRewind, QStringLiteral("AudioRewind")}, + {Qt::Key_BackForward, QStringLiteral("BackForward")}, + {Qt::Key_ApplicationLeft, QStringLiteral("ApplicationLeft")}, + {Qt::Key_ApplicationRight, QStringLiteral("ApplicationRight")}, + {Qt::Key_Book, QStringLiteral("Book")}, + {Qt::Key_CD, QStringLiteral("CD")}, + {Qt::Key_Calculator, QStringLiteral("Calculator")}, + {Qt::Key_ToDoList, QStringLiteral("ToDoList")}, + {Qt::Key_ClearGrab, QStringLiteral("ClearGrab")}, + {Qt::Key_Close, QStringLiteral("Close")}, + {Qt::Key_Copy, QStringLiteral("Copy")}, + {Qt::Key_Cut, QStringLiteral("Cut")}, + {Qt::Key_Display, QStringLiteral("Display")}, + {Qt::Key_DOS, QStringLiteral("DOS")}, + {Qt::Key_Documents, QStringLiteral("Documents")}, + {Qt::Key_Excel, QStringLiteral("Excel")}, + {Qt::Key_Explorer, QStringLiteral("Explorer")}, + {Qt::Key_Game, QStringLiteral("Game")}, + {Qt::Key_Go, QStringLiteral("Go")}, + {Qt::Key_iTouch, QStringLiteral("iTouch")}, + {Qt::Key_LogOff, QStringLiteral("LogOff")}, + {Qt::Key_Market, QStringLiteral("Market")}, + {Qt::Key_Meeting, QStringLiteral("Meeting")}, + {Qt::Key_MenuKB, QStringLiteral("MenuKB")}, + {Qt::Key_MenuPB, QStringLiteral("MenuPB")}, + {Qt::Key_MySites, QStringLiteral("MySites")}, + {Qt::Key_News, QStringLiteral("News")}, + {Qt::Key_OfficeHome, QStringLiteral("OfficeHome")}, + {Qt::Key_Option, QStringLiteral("Option")}, + {Qt::Key_Paste, QStringLiteral("Paste")}, + {Qt::Key_Phone, QStringLiteral("Phone")}, + {Qt::Key_Calendar, QStringLiteral("Calendar")}, + {Qt::Key_Reply, QStringLiteral("Reply")}, + {Qt::Key_Reload, QStringLiteral("Reload")}, + {Qt::Key_RotateWindows, QStringLiteral("RotateWindows")}, + {Qt::Key_RotationPB, QStringLiteral("RotationPB")}, + {Qt::Key_RotationKB, QStringLiteral("RotationKB")}, + {Qt::Key_Save, QStringLiteral("Save")}, + {Qt::Key_Send, QStringLiteral("Send")}, + {Qt::Key_Spell, QStringLiteral("Spell")}, + {Qt::Key_SplitScreen, QStringLiteral("SplitScreen")}, + {Qt::Key_Support, QStringLiteral("Support")}, + {Qt::Key_TaskPane, QStringLiteral("TaskPane")}, + {Qt::Key_Terminal, QStringLiteral("Terminal")}, + {Qt::Key_Tools, QStringLiteral("Tools")}, + {Qt::Key_Travel, QStringLiteral("Travel")}, + {Qt::Key_Video, QStringLiteral("Video")}, + {Qt::Key_Word, QStringLiteral("Word")}, + {Qt::Key_Xfer, QStringLiteral("Xfer")}, + {Qt::Key_ZoomIn, QStringLiteral("ZoomIn")}, + {Qt::Key_ZoomOut, QStringLiteral("ZoomOut")}, + {Qt::Key_Away, QStringLiteral("Away")}, + {Qt::Key_Messenger, QStringLiteral("Messenger")}, + {Qt::Key_WebCam, QStringLiteral("WebCam")}, + {Qt::Key_MailForward, QStringLiteral("MailForward")}, + {Qt::Key_Pictures, QStringLiteral("Pictures")}, + {Qt::Key_Music, QStringLiteral("Music")}, + {Qt::Key_Battery, QStringLiteral("Battery")}, + {Qt::Key_Bluetooth, QStringLiteral("Bluetooth")}, + {Qt::Key_WLAN, QStringLiteral("WLAN")}, + {Qt::Key_UWB, QStringLiteral("UWB")}, + {Qt::Key_AudioForward, QStringLiteral("AudioForward")}, + {Qt::Key_AudioRepeat, QStringLiteral("AudioRepeat")}, + {Qt::Key_AudioRandomPlay, QStringLiteral("AudioRandomPlay")}, + {Qt::Key_Subtitle, QStringLiteral("Subtitle")}, + {Qt::Key_AudioCycleTrack, QStringLiteral("AudioCycleTrack")}, + {Qt::Key_Time, QStringLiteral("Time")}, + {Qt::Key_Hibernate, QStringLiteral("Hibernate")}, + {Qt::Key_View, QStringLiteral("View")}, + {Qt::Key_TopMenu, QStringLiteral("TopMenu")}, + {Qt::Key_PowerDown, QStringLiteral("PowerDown")}, + {Qt::Key_Suspend, QStringLiteral("Suspend")}, + {Qt::Key_ContrastAdjust, QStringLiteral("ContrastAdjust")}, + {Qt::Key_LaunchG, QStringLiteral("LaunchG")}, + {Qt::Key_LaunchH, QStringLiteral("LaunchH")}, + {Qt::Key_TouchpadToggle, QStringLiteral("TouchpadToggle")}, + {Qt::Key_TouchpadOn, QStringLiteral("TouchpadOn")}, + {Qt::Key_TouchpadOff, QStringLiteral("TouchpadOff")}, + {Qt::Key_MicMute, QStringLiteral("MicMute")}, + {Qt::Key_Red, QStringLiteral("Red")}, + {Qt::Key_Green, QStringLiteral("Green")}, + {Qt::Key_Yellow, QStringLiteral("Yellow")}, + {Qt::Key_Blue, QStringLiteral("Blue")}, + {Qt::Key_ChannelUp, QStringLiteral("ChannelUp")}, + {Qt::Key_ChannelDown, QStringLiteral("ChannelDown")}, + {Qt::Key_Guide, QStringLiteral("Guide")}, + {Qt::Key_Info, QStringLiteral("Info")}, + {Qt::Key_Settings, QStringLiteral("Settings")}, + {Qt::Key_MicVolumeUp, QStringLiteral("MicVolumeUp")}, + {Qt::Key_MicVolumeDown, QStringLiteral("MicVolumeDown")}, + {Qt::Key_New, QStringLiteral("New")}, + {Qt::Key_Open, QStringLiteral("Open")}, + {Qt::Key_Find, QStringLiteral("Find")}, + {Qt::Key_Undo, QStringLiteral("Undo")}, + {Qt::Key_Redo, QStringLiteral("Redo")}, + {Qt::Key_MediaLast, QStringLiteral("MediaLast")}, + {Qt::Key_Select, QStringLiteral("Select")}, + {Qt::Key_Yes, QStringLiteral("Yes")}, + {Qt::Key_No, QStringLiteral("No")}, + {Qt::Key_Cancel, QStringLiteral("Cancel")}, + {Qt::Key_Printer, QStringLiteral("Printer")}, + {Qt::Key_Execute, QStringLiteral("Execute")}, + {Qt::Key_Sleep, QStringLiteral("Sleep")}, + {Qt::Key_Play, QStringLiteral("Play")}, + {Qt::Key_Zoom, QStringLiteral("Zoom")}, + {Qt::Key_Exit, QStringLiteral("Exit")}, + {Qt::Key_Context1, QStringLiteral("Context1")}, + {Qt::Key_Context2, QStringLiteral("Context2")}, + {Qt::Key_Context3, QStringLiteral("Context3")}, + {Qt::Key_Context4, QStringLiteral("Context4")}, + {Qt::Key_Call, QStringLiteral("Call")}, + {Qt::Key_Hangup, QStringLiteral("Hangup")}, + {Qt::Key_Flip, QStringLiteral("Flip")}, + {Qt::Key_ToggleCallHangup, QStringLiteral("ToggleCallHangup")}, + {Qt::Key_VoiceDial, QStringLiteral("VoiceDial")}, + {Qt::Key_LastNumberRedial, QStringLiteral("LastNumberRedial")}, + {Qt::Key_Camera, QStringLiteral("Camera")}, + {Qt::Key_CameraFocus, QStringLiteral("CameraFocus")}}; + +QString GetKeyIdentifier(int key) +{ + const auto it = s_qt_key_names.find(key); + return it == s_qt_key_names.end() ? QString() : it->second; +} + +std::optional GetKeyIdForIdentifier(const QString& key_identifier) +{ + for (const auto& it : s_qt_key_names) + { + if (it.second == key_identifier) + return it.first; + } + + return std::nullopt; +} + } // namespace QtUtils \ No newline at end of file diff --git a/src/duckstation-qt/qtutils.h b/src/duckstation-qt/qtutils.h index ea2b6f85a..7097810a2 100644 --- a/src/duckstation-qt/qtutils.h +++ b/src/duckstation-qt/qtutils.h @@ -1,5 +1,7 @@ #pragma once +#include #include +#include class QTableView; @@ -9,4 +11,10 @@ namespace QtUtils { /// remaining space. void ResizeColumnsForTableView(QTableView* view, const std::initializer_list& widths); +/// Returns a string identifier for a Qt key ID. +QString GetKeyIdentifier(int key); + +/// Returns the integer Qt key ID for an identifier. +std::optional GetKeyIdForIdentifier(const QString& key_identifier); + } // namespace QtUtils \ No newline at end of file diff --git a/src/duckstation-qt/settingsdialog.cpp b/src/duckstation-qt/settingsdialog.cpp index 3d4ef2a9a..4d574e6a3 100644 --- a/src/duckstation-qt/settingsdialog.cpp +++ b/src/duckstation-qt/settingsdialog.cpp @@ -1,6 +1,7 @@ #include "settingsdialog.h" #include "consolesettingswidget.h" #include "gamelistsettingswidget.h" +#include "portsettingswidget.h" #include "qthostinterface.h" #include @@ -11,15 +12,17 @@ SettingsDialog::SettingsDialog(QtHostInterface* host_interface, QWidget* parent m_console_settings = new ConsoleSettingsWidget(host_interface, m_ui.settingsContainer); m_game_list_settings = new GameListSettingsWidget(host_interface, m_ui.settingsContainer); + m_port_settings = new PortSettingsWidget(host_interface, m_ui.settingsContainer); m_cpu_settings = new QWidget(m_ui.settingsContainer); m_gpu_settings = new QWidget(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_cpu_settings); - m_ui.settingsContainer->insertWidget(3, m_gpu_settings); - m_ui.settingsContainer->insertWidget(4, m_audio_settings); + m_ui.settingsContainer->insertWidget(2, m_port_settings); + m_ui.settingsContainer->insertWidget(3, m_cpu_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); diff --git a/src/duckstation-qt/settingsdialog.h b/src/duckstation-qt/settingsdialog.h index f006768cb..80b7ffcb9 100644 --- a/src/duckstation-qt/settingsdialog.h +++ b/src/duckstation-qt/settingsdialog.h @@ -16,6 +16,7 @@ public: { ConsoleSettings, GameListSettings, + PortSettings, CPUSettings, GPUSettings, AudioSettings, @@ -38,6 +39,7 @@ private: 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; QWidget* m_audio_settings = nullptr; diff --git a/src/duckstation-qt/settingsdialog.ui b/src/duckstation-qt/settingsdialog.ui index 0351c7552..fe1c8af51 100644 --- a/src/duckstation-qt/settingsdialog.ui +++ b/src/duckstation-qt/settingsdialog.ui @@ -9,8 +9,8 @@ 0 0 - 637 - 405 + 640 + 480 @@ -58,6 +58,15 @@ :/icons/folder-open.png:/icons/folder-open.png + + + Port Settings + + + + :/icons/input-gaming.png:/icons/input-gaming.png + + CPU Settings