Qt: Rudimentary settings window
Jeffrey Pfau jeffrey@endrift.com
Sun, 21 Dec 2014 16:29:56 -0800
10 files changed,
515 insertions(+),
1 deletions(-)
jump to
M
CHANGES
→
CHANGES
@@ -4,6 +4,7 @@ - Support for gamepad axes, e.g. analog sticks or triggers
- Add scale presets for up to 6x - Debugger: Add CLI "frame", frame advance command - Better audio resampling via FFmpeg + - Settings window Bugfixes: - Qt: Fix issue with set frame sizes being the wrong height - Qt: Fix emulator crashing when full screen if a game is not running
M
src/platform/qt/CMakeLists.txt
→
src/platform/qt/CMakeLists.txt
@@ -44,6 +44,7 @@ KeyEditor.cpp
LoadSaveState.cpp LogView.cpp SavestateButton.cpp + SettingsView.cpp Window.cpp VFileDevice.cpp VideoView.cpp)@@ -52,6 +53,7 @@ qt5_wrap_ui(UI_FILES
GIFView.ui LoadSaveState.ui LogView.ui + SettingsView.ui VideoView.ui) set(QT_LIBRARIES)
M
src/platform/qt/ConfigController.cpp
→
src/platform/qt/ConfigController.cpp
@@ -130,6 +130,10 @@ }
m_optionSet[optionName]->setValue(GBAConfigGetValue(&m_config, key)); } +QString ConfigController::getOption(const char* key) { + return QString(GBAConfigGetValue(&m_config, key)); +} + void ConfigController::setOption(const char* key, bool value) { GBAConfigSetIntValue(&m_config, key, value); QString optionName(key);
M
src/platform/qt/ConfigController.h
→
src/platform/qt/ConfigController.h
@@ -67,6 +67,8 @@
ConfigOption* addOption(const char* key); void updateOption(const char* key); + QString getOption(const char* key); + public slots: void setOption(const char* key, bool value); void setOption(const char* key, int value);
M
src/platform/qt/GameController.cpp
→
src/platform/qt/GameController.cpp
@@ -177,6 +177,9 @@ }
} void GameController::loadBIOS(const QString& path) { + if (m_bios == path) { + return; + } m_bios = path; if (m_gameOpen) { closeGame();
A
src/platform/qt/SettingsView.cpp
@@ -0,0 +1,90 @@
+/* Copyright (c) 2013-2014 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "SettingsView.h" + +#include "ConfigController.h" + +#include <QFileDialog> + +using namespace QGBA; + +SettingsView::SettingsView(ConfigController* controller, QWidget* parent) + : QWidget(parent) + , m_controller(controller) +{ + m_ui.setupUi(this); + + loadSetting("bios", m_ui.bios); + loadSetting("audioBuffers", m_ui.audioBufferSize); + loadSetting("videoSync", m_ui.videoSync); + loadSetting("audioSync", m_ui.audioSync); + loadSetting("frameskip", m_ui.frameskip); + loadSetting("lockAspectRatio", m_ui.lockAspectRatio); + loadSetting("rewindBufferInterval", m_ui.rewindInterval); + loadSetting("rewindBufferCapacity", m_ui.rewindCapacity); + + connect(m_ui.biosBrowse, SIGNAL(clicked()), this, SLOT(selectBios())); + connect(m_ui.buttonBox, SIGNAL(accepted()), this, SLOT(updateConfig())); +} + +void SettingsView::selectBios() { + QString filename = QFileDialog::getOpenFileName(this, tr("Select BIOS")); + if (!filename.isEmpty()) { + m_ui.bios->setText(filename); + } +} + +void SettingsView::updateConfig() { + saveSetting("bios", m_ui.bios); + saveSetting("audioBuffers", m_ui.audioBufferSize); + saveSetting("videoSync", m_ui.videoSync); + saveSetting("audioSync", m_ui.audioSync); + saveSetting("frameskip", m_ui.frameskip); + saveSetting("lockAspectRatio", m_ui.lockAspectRatio); + saveSetting("rewindBufferInterval", m_ui.rewindInterval); + saveSetting("rewindBufferCapacity", m_ui.rewindCapacity); + m_controller->write(); + + emit biosLoaded(m_ui.bios->text()); +} + +void SettingsView::saveSetting(const char* key, const QAbstractButton* field) { + m_controller->setOption(key, field->isChecked()); + m_controller->updateOption(key); +} + +void SettingsView::saveSetting(const char* key, const QComboBox* field) { + saveSetting(key, field->lineEdit()); +} + +void SettingsView::saveSetting(const char* key, const QLineEdit* field) { + m_controller->setOption(key, field->text()); + m_controller->updateOption(key); +} + +void SettingsView::saveSetting(const char* key, const QSpinBox* field) { + m_controller->setOption(key, field->cleanText()); + m_controller->updateOption(key); +} + +void SettingsView::loadSetting(const char* key, QAbstractButton* field) { + QString option = m_controller->getOption(key); + field->setChecked(option != "0"); +} + +void SettingsView::loadSetting(const char* key, QComboBox* field) { + loadSetting(key, field->lineEdit()); +} + +void SettingsView::loadSetting(const char* key, QLineEdit* field) { + QString option = m_controller->getOption(key); + field->setText(option); +} + +void SettingsView::loadSetting(const char* key, QSpinBox* field) { + QString option = m_controller->getOption(key); + field->setValue(option.toInt()); +}
A
src/platform/qt/SettingsView.h
@@ -0,0 +1,48 @@
+/* Copyright (c) 2013-2014 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef QGBA_SETTINGS_VIEW +#define QGBA_SETTINGS_VIEW + +#include <QWidget> + +#include "ui_SettingsView.h" + +namespace QGBA { + +class ConfigController; + +class SettingsView : public QWidget { +Q_OBJECT + +public: + SettingsView(ConfigController* controller, QWidget* parent = nullptr); + +signals: + void biosLoaded(const QString&); + +private slots: + void selectBios(); + void updateConfig(); + +private: + Ui::SettingsView m_ui; + + ConfigController* m_controller; + + void saveSetting(const char* key, const QAbstractButton*); + void saveSetting(const char* key, const QComboBox*); + void saveSetting(const char* key, const QLineEdit*); + void saveSetting(const char* key, const QSpinBox*); + + void loadSetting(const char* key, QAbstractButton*); + void loadSetting(const char* key, QComboBox*); + void loadSetting(const char* key, QLineEdit*); + void loadSetting(const char* key, QSpinBox*); +}; + +} + +#endif
A
src/platform/qt/SettingsView.ui
@@ -0,0 +1,347 @@
+<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SettingsView</class> + <widget class="QWidget" name="SettingsView"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>339</width> + <height>503</height> + </rect> + </property> + <property name="windowTitle"> + <string>Settings</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QFormLayout" name="formLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::ExpandingFieldsGrow</enum> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>BIOS file:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLineEdit" name="bios"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="biosBrowse"> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="1" column="1"> + <widget class="QCheckBox" name="skipBios"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Skip BIOS intro</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QCheckBox" name="useBios"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Use BIOS file</string> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="Line" name="line_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_14"> + <property name="text"> + <string>Audio driver:</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QComboBox" name="audioDriver"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <item> + <property name="text"> + <string>SDL</string> + </property> + </item> + <item> + <property name="text"> + <string>Qt Multimedia</string> + </property> + </item> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="audioBufferSizeLabel"> + <property name="text"> + <string>Audio buffer:</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_9"> + <item> + <widget class="QComboBox" name="audioBufferSize"> + <property name="editable"> + <bool>true</bool> + </property> + <property name="currentText"> + <string>2048</string> + </property> + <property name="currentIndex"> + <number>2</number> + </property> + <item> + <property name="text"> + <string>512</string> + </property> + </item> + <item> + <property name="text"> + <string>1024</string> + </property> + </item> + <item> + <property name="text"> + <string>2048</string> + </property> + </item> + <item> + <property name="text"> + <string>4096</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>samples</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Sync:</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_10"> + <item> + <widget class="QCheckBox" name="videoSync"> + <property name="text"> + <string>Video</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="audioSync"> + <property name="text"> + <string>Audio</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>Frameskip:</string> + </property> + </widget> + </item> + <item row="7" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_16"> + <item> + <widget class="QLabel" name="label_12"> + <property name="text"> + <string>Skip every</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="frameskip"/> + </item> + <item> + <widget class="QLabel" name="label_13"> + <property name="text"> + <string>frames</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="8" column="0" colspan="2"> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="9" column="1"> + <widget class="QCheckBox" name="lockAspectRatio"> + <property name="text"> + <string>Lock aspect ratio</string> + </property> + </widget> + </item> + <item row="10" column="1"> + <widget class="QCheckBox" name="resampleVideo"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Resample video</string> + </property> + </widget> + </item> + <item row="11" column="0" colspan="2"> + <widget class="Line" name="line_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="12" column="1"> + <widget class="QCheckBox" name="rewind"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Enable rewind</string> + </property> + </widget> + </item> + <item row="13" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Rewind interval:</string> + </property> + </widget> + </item> + <item row="13" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_12"> + <item> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Every</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="rewindInterval"/> + </item> + <item> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>frames</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="14" column="0"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>Rewind length:</string> + </property> + </widget> + </item> + <item row="14" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_13"> + <item> + <widget class="QSpinBox" name="rewindCapacity"/> + </item> + <item> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>intervals</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>SettingsView</receiver> + <slot>close()</slot> + <hints> + <hint type="sourcelabel"> + <x>169</x> + <y>453</y> + </hint> + <hint type="destinationlabel"> + <x>169</x> + <y>236</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>SettingsView</receiver> + <slot>close()</slot> + <hints> + <hint type="sourcelabel"> + <x>169</x> + <y>453</y> + </hint> + <hint type="destinationlabel"> + <x>169</x> + <y>236</y> + </hint> + </hints> + </connection> + </connections> +</ui>
M
src/platform/qt/Window.cpp
→
src/platform/qt/Window.cpp
@@ -20,6 +20,7 @@ #include "GDBWindow.h"
#include "GIFView.h" #include "LoadSaveState.h" #include "LogView.h" +#include "SettingsView.h" #include "VideoView.h" extern "C" {@@ -171,6 +172,8 @@
void Window::selectBIOS() { QString filename = QFileDialog::getOpenFileName(this, tr("Select BIOS")); if (!filename.isEmpty()) { + m_config->setOption("bios", filename); + m_config->updateOption("bios"); m_controller->loadBIOS(filename); } }@@ -189,6 +192,14 @@ keyEditor->setAttribute(Qt::WA_DeleteOnClose);
keyEditor->show(); } +void Window::openSettingsWindow() { + SettingsView* settingsWindow = new SettingsView(m_config); + connect(this, SIGNAL(shutdown()), settingsWindow, SLOT(close())); + connect(settingsWindow, SIGNAL(biosLoaded(const QString&)), m_controller, SLOT(loadBIOS(const QString&))); + settingsWindow->setAttribute(Qt::WA_DeleteOnClose); + settingsWindow->show(); +} + #ifdef BUILD_SDL void Window::openGamepadWindow() { GBAKeyEditor* keyEditor = new GBAKeyEditor(&m_inputController, SDL_BINDING_BUTTON);@@ -426,6 +437,11 @@ }
#ifndef Q_OS_MAC fileMenu->addSeparator(); +#endif + fileMenu->addAction(tr("Settings"), this, SLOT(openSettingsWindow())); + +#ifndef Q_OS_MAC + fileMenu->addSeparator(); fileMenu->addAction(tr("E&xit"), this, SLOT(close()), QKeySequence::Quit); #endif@@ -526,7 +542,7 @@ m_config->updateOption("frameskip");
avMenu->addSeparator(); - QMenu* buffersMenu = avMenu->addMenu(tr("Buffer &size")); + QMenu* buffersMenu = avMenu->addMenu(tr("Audio buffer &size")); ConfigOption* buffers = m_config->addOption("audioBuffers"); buffers->connect([this](const QVariant& value) { emit audioBufferSamplesChanged(value.toInt()); }); buffers->addValue(tr("512"), 512, buffersMenu);
M
src/platform/qt/Window.h
→
src/platform/qt/Window.h
@@ -61,6 +61,7 @@ void loadConfig();
void saveConfig(); void openKeymapWindow(); + void openSettingsWindow(); #ifdef BUILD_SDL void openGamepadWindow();