Qt: Rudimentary settings window

This commit is contained in:
Jeffrey Pfau 2014-12-21 16:29:56 -08:00
parent 22826f2e7a
commit 7c8f1d9726
10 changed files with 515 additions and 1 deletions

View File

@ -4,6 +4,7 @@ Features:
- Add scale presets for up to 6x - Add scale presets for up to 6x
- Debugger: Add CLI "frame", frame advance command - Debugger: Add CLI "frame", frame advance command
- Better audio resampling via FFmpeg - Better audio resampling via FFmpeg
- Settings window
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

View File

@ -44,6 +44,7 @@ set(SOURCE_FILES
LoadSaveState.cpp LoadSaveState.cpp
LogView.cpp LogView.cpp
SavestateButton.cpp SavestateButton.cpp
SettingsView.cpp
Window.cpp Window.cpp
VFileDevice.cpp VFileDevice.cpp
VideoView.cpp) VideoView.cpp)
@ -52,6 +53,7 @@ qt5_wrap_ui(UI_FILES
GIFView.ui GIFView.ui
LoadSaveState.ui LoadSaveState.ui
LogView.ui LogView.ui
SettingsView.ui
VideoView.ui) VideoView.ui)
set(QT_LIBRARIES) set(QT_LIBRARIES)

View File

@ -130,6 +130,10 @@ void ConfigController::updateOption(const char* key) {
m_optionSet[optionName]->setValue(GBAConfigGetValue(&m_config, key)); 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) { void ConfigController::setOption(const char* key, bool value) {
GBAConfigSetIntValue(&m_config, key, value); GBAConfigSetIntValue(&m_config, key, value);
QString optionName(key); QString optionName(key);

View File

@ -67,6 +67,8 @@ public:
ConfigOption* addOption(const char* key); ConfigOption* addOption(const char* key);
void updateOption(const char* key); void updateOption(const char* key);
QString getOption(const char* key);
public slots: public slots:
void setOption(const char* key, bool value); void setOption(const char* key, bool value);
void setOption(const char* key, int value); void setOption(const char* key, int value);

View File

@ -177,6 +177,9 @@ void GameController::openGame() {
} }
void GameController::loadBIOS(const QString& path) { void GameController::loadBIOS(const QString& path) {
if (m_bios == path) {
return;
}
m_bios = path; m_bios = path;
if (m_gameOpen) { if (m_gameOpen) {
closeGame(); closeGame();

View File

@ -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());
}

View File

@ -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

View File

@ -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>

View File

@ -20,6 +20,7 @@
#include "GIFView.h" #include "GIFView.h"
#include "LoadSaveState.h" #include "LoadSaveState.h"
#include "LogView.h" #include "LogView.h"
#include "SettingsView.h"
#include "VideoView.h" #include "VideoView.h"
extern "C" { extern "C" {
@ -171,6 +172,8 @@ void Window::selectROM() {
void Window::selectBIOS() { void Window::selectBIOS() {
QString filename = QFileDialog::getOpenFileName(this, tr("Select BIOS")); QString filename = QFileDialog::getOpenFileName(this, tr("Select BIOS"));
if (!filename.isEmpty()) { if (!filename.isEmpty()) {
m_config->setOption("bios", filename);
m_config->updateOption("bios");
m_controller->loadBIOS(filename); m_controller->loadBIOS(filename);
} }
} }
@ -189,6 +192,14 @@ void Window::openKeymapWindow() {
keyEditor->show(); 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 #ifdef BUILD_SDL
void Window::openGamepadWindow() { void Window::openGamepadWindow() {
GBAKeyEditor* keyEditor = new GBAKeyEditor(&m_inputController, SDL_BINDING_BUTTON); GBAKeyEditor* keyEditor = new GBAKeyEditor(&m_inputController, SDL_BINDING_BUTTON);
@ -424,6 +435,11 @@ void Window::setupMenu(QMenuBar* menubar) {
quickSaveMenu->addAction(quickSave); quickSaveMenu->addAction(quickSave);
} }
#ifndef Q_OS_MAC
fileMenu->addSeparator();
#endif
fileMenu->addAction(tr("Settings"), this, SLOT(openSettingsWindow()));
#ifndef Q_OS_MAC #ifndef Q_OS_MAC
fileMenu->addSeparator(); fileMenu->addSeparator();
fileMenu->addAction(tr("E&xit"), this, SLOT(close()), QKeySequence::Quit); fileMenu->addAction(tr("E&xit"), this, SLOT(close()), QKeySequence::Quit);
@ -526,7 +542,7 @@ void Window::setupMenu(QMenuBar* menubar) {
avMenu->addSeparator(); avMenu->addSeparator();
QMenu* buffersMenu = avMenu->addMenu(tr("Buffer &size")); QMenu* buffersMenu = avMenu->addMenu(tr("Audio buffer &size"));
ConfigOption* buffers = m_config->addOption("audioBuffers"); ConfigOption* buffers = m_config->addOption("audioBuffers");
buffers->connect([this](const QVariant& value) { emit audioBufferSamplesChanged(value.toInt()); }); buffers->connect([this](const QVariant& value) { emit audioBufferSamplesChanged(value.toInt()); });
buffers->addValue(tr("512"), 512, buffersMenu); buffers->addValue(tr("512"), 512, buffersMenu);

View File

@ -61,6 +61,7 @@ public slots:
void saveConfig(); void saveConfig();
void openKeymapWindow(); void openKeymapWindow();
void openSettingsWindow();
#ifdef BUILD_SDL #ifdef BUILD_SDL
void openGamepadWindow(); void openGamepadWindow();