summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/citra_qt/CMakeLists.txt15
-rw-r--r--src/citra_qt/config.cpp80
-rw-r--r--src/citra_qt/configure.ui109
-rw-r--r--src/citra_qt/configure_debug.cpp32
-rw-r--r--src/citra_qt/configure_debug.h29
-rw-r--r--src/citra_qt/configure_debug.ui102
-rw-r--r--src/citra_qt/configure_dialog.cpp29
-rw-r--r--src/citra_qt/configure_dialog.h29
-rw-r--r--src/citra_qt/configure_general.cpp43
-rw-r--r--src/citra_qt/configure_general.h29
-rw-r--r--src/citra_qt/configure_general.ui166
-rw-r--r--src/citra_qt/game_list.cpp13
-rw-r--r--src/citra_qt/game_list.h4
-rw-r--r--src/citra_qt/hotkeys.cpp54
-rw-r--r--src/citra_qt/hotkeys.h8
-rw-r--r--src/citra_qt/hotkeys.ui47
-rw-r--r--src/citra_qt/main.cpp163
-rw-r--r--src/citra_qt/main.h8
-rw-r--r--src/citra_qt/main.ui51
-rw-r--r--src/citra_qt/ui_settings.cpp11
-rw-r--r--src/citra_qt/ui_settings.h47
21 files changed, 807 insertions, 262 deletions
diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt
index 9b3eb2cd6..6660d9879 100644
--- a/src/citra_qt/CMakeLists.txt
+++ b/src/citra_qt/CMakeLists.txt
@@ -17,12 +17,16 @@ set(SRCS
17 debugger/profiler.cpp 17 debugger/profiler.cpp
18 debugger/ramview.cpp 18 debugger/ramview.cpp
19 debugger/registers.cpp 19 debugger/registers.cpp
20 game_list.cpp
21 util/spinbox.cpp 20 util/spinbox.cpp
22 util/util.cpp 21 util/util.cpp
23 bootmanager.cpp 22 bootmanager.cpp
23 configure_debug.cpp
24 configure_dialog.cpp
25 configure_general.cpp
26 game_list.cpp
24 hotkeys.cpp 27 hotkeys.cpp
25 main.cpp 28 main.cpp
29 ui_settings.cpp
26 citra-qt.rc 30 citra-qt.rc
27 Info.plist 31 Info.plist
28 ) 32 )
@@ -44,12 +48,16 @@ set(HEADERS
44 debugger/profiler.h 48 debugger/profiler.h
45 debugger/ramview.h 49 debugger/ramview.h
46 debugger/registers.h 50 debugger/registers.h
47 game_list.h
48 util/spinbox.h 51 util/spinbox.h
49 util/util.h 52 util/util.h
50 bootmanager.h 53 bootmanager.h
54 configure_debug.h
55 configure_dialog.h
56 configure_general.h
57 game_list.h
51 hotkeys.h 58 hotkeys.h
52 main.h 59 main.h
60 ui_settings.h
53 version.h 61 version.h
54 ) 62 )
55 63
@@ -59,6 +67,9 @@ set(UIS
59 debugger/disassembler.ui 67 debugger/disassembler.ui
60 debugger/profiler.ui 68 debugger/profiler.ui
61 debugger/registers.ui 69 debugger/registers.ui
70 configure.ui
71 configure_debug.ui
72 configure_general.ui
62 hotkeys.ui 73 hotkeys.ui
63 main.ui 74 main.ui
64 ) 75 )
diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp
index 8e247ff5c..ecf5c5a75 100644
--- a/src/citra_qt/config.cpp
+++ b/src/citra_qt/config.cpp
@@ -7,12 +7,12 @@
7#include <QStringList> 7#include <QStringList>
8 8
9#include "citra_qt/config.h" 9#include "citra_qt/config.h"
10#include "citra_qt/ui_settings.h"
10 11
11#include "common/file_util.h" 12#include "common/file_util.h"
12#include "core/settings.h" 13#include "core/settings.h"
13 14
14Config::Config() { 15Config::Config() {
15
16 // TODO: Don't hardcode the path; let the frontend decide where to put the config files. 16 // TODO: Don't hardcode the path; let the frontend decide where to put the config files.
17 qt_config_loc = FileUtil::GetUserPath(D_CONFIG_IDX) + "qt-config.ini"; 17 qt_config_loc = FileUtil::GetUserPath(D_CONFIG_IDX) + "qt-config.ini";
18 FileUtil::CreateFullPath(qt_config_loc); 18 FileUtil::CreateFullPath(qt_config_loc);
@@ -67,6 +67,51 @@ void Config::ReadValues() {
67 Settings::values.use_gdbstub = qt_config->value("use_gdbstub", false).toBool(); 67 Settings::values.use_gdbstub = qt_config->value("use_gdbstub", false).toBool();
68 Settings::values.gdbstub_port = qt_config->value("gdbstub_port", 24689).toInt(); 68 Settings::values.gdbstub_port = qt_config->value("gdbstub_port", 24689).toInt();
69 qt_config->endGroup(); 69 qt_config->endGroup();
70
71 qt_config->beginGroup("UI");
72
73 qt_config->beginGroup("UILayout");
74 UISettings::values.geometry = qt_config->value("geometry").toByteArray();
75 UISettings::values.state = qt_config->value("state").toByteArray();
76 UISettings::values.renderwindow_geometry = qt_config->value("geometryRenderWindow").toByteArray();
77 UISettings::values.gamelist_header_state = qt_config->value("gameListHeaderState").toByteArray();
78 UISettings::values.microprofile_geometry = qt_config->value("microProfileDialogGeometry").toByteArray();
79 UISettings::values.microprofile_visible = qt_config->value("microProfileDialogVisible", false).toBool();
80 qt_config->endGroup();
81
82 qt_config->beginGroup("Paths");
83 UISettings::values.roms_path = qt_config->value("romsPath").toString();
84 UISettings::values.symbols_path = qt_config->value("symbolsPath").toString();
85 UISettings::values.gamedir = qt_config->value("gameListRootDir", ".").toString();
86 UISettings::values.gamedir_deepscan = qt_config->value("gameListDeepScan", false).toBool();
87 UISettings::values.recent_files = qt_config->value("recentFiles").toStringList();
88 qt_config->endGroup();
89
90 qt_config->beginGroup("Shortcuts");
91 QStringList groups = qt_config->childGroups();
92 for (auto group : groups) {
93 qt_config->beginGroup(group);
94
95 QStringList hotkeys = qt_config->childGroups();
96 for (auto hotkey : hotkeys) {
97 qt_config->beginGroup(hotkey);
98 UISettings::values.shortcuts.emplace_back(
99 UISettings::Shortcut(group + "/" + hotkey,
100 UISettings::ContextualShortcut(qt_config->value("KeySeq").toString(),
101 qt_config->value("Context").toInt())));
102 qt_config->endGroup();
103 }
104
105 qt_config->endGroup();
106 }
107 qt_config->endGroup();
108
109 UISettings::values.single_window_mode = qt_config->value("singleWindowMode", true).toBool();
110 UISettings::values.display_titlebar = qt_config->value("displayTitleBars", true).toBool();
111 UISettings::values.confirm_before_closing = qt_config->value("confirmClose",true).toBool();
112 UISettings::values.first_start = qt_config->value("firstStart", true).toBool();
113
114 qt_config->endGroup();
70} 115}
71 116
72void Config::SaveValues() { 117void Config::SaveValues() {
@@ -107,6 +152,39 @@ void Config::SaveValues() {
107 qt_config->setValue("use_gdbstub", Settings::values.use_gdbstub); 152 qt_config->setValue("use_gdbstub", Settings::values.use_gdbstub);
108 qt_config->setValue("gdbstub_port", Settings::values.gdbstub_port); 153 qt_config->setValue("gdbstub_port", Settings::values.gdbstub_port);
109 qt_config->endGroup(); 154 qt_config->endGroup();
155
156 qt_config->beginGroup("UI");
157
158 qt_config->beginGroup("UILayout");
159 qt_config->setValue("geometry", UISettings::values.geometry);
160 qt_config->setValue("state", UISettings::values.state);
161 qt_config->setValue("geometryRenderWindow", UISettings::values.renderwindow_geometry);
162 qt_config->setValue("gameListHeaderState", UISettings::values.gamelist_header_state);
163 qt_config->setValue("microProfileDialogGeometry", UISettings::values.microprofile_geometry);
164 qt_config->setValue("microProfileDialogVisible", UISettings::values.microprofile_visible);
165 qt_config->endGroup();
166
167 qt_config->beginGroup("Paths");
168 qt_config->setValue("romsPath", UISettings::values.roms_path);
169 qt_config->setValue("symbolsPath", UISettings::values.symbols_path);
170 qt_config->setValue("gameListRootDir", UISettings::values.gamedir);
171 qt_config->setValue("gameListDeepScan", UISettings::values.gamedir_deepscan);
172 qt_config->setValue("recentFiles", UISettings::values.recent_files);
173 qt_config->endGroup();
174
175 qt_config->beginGroup("Shortcuts");
176 for (auto shortcut : UISettings::values.shortcuts ) {
177 qt_config->setValue(shortcut.first + "/KeySeq", shortcut.second.first);
178 qt_config->setValue(shortcut.first + "/Context", shortcut.second.second);
179 }
180 qt_config->endGroup();
181
182 qt_config->setValue("singleWindowMode", UISettings::values.single_window_mode);
183 qt_config->setValue("displayTitleBars", UISettings::values.display_titlebar);
184 qt_config->setValue("confirmClose", UISettings::values.confirm_before_closing);
185 qt_config->setValue("firstStart", UISettings::values.first_start);
186
187 qt_config->endGroup();
110} 188}
111 189
112void Config::Reload() { 190void Config::Reload() {
diff --git a/src/citra_qt/configure.ui b/src/citra_qt/configure.ui
new file mode 100644
index 000000000..3c1f2ebba
--- /dev/null
+++ b/src/citra_qt/configure.ui
@@ -0,0 +1,109 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>ConfigureDialog</class>
4 <widget class="QDialog" name="ConfigureDialog">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>441</width>
10 <height>501</height>
11 </rect>
12 </property>
13 <property name="minimumSize">
14 <size>
15 <width>370</width>
16 <height>219</height>
17 </size>
18 </property>
19 <property name="windowTitle">
20 <string>Citra Configuration</string>
21 </property>
22 <layout class="QVBoxLayout" name="verticalLayout">
23 <item>
24 <widget class="QTabWidget" name="tabWidget">
25 <property name="minimumSize">
26 <size>
27 <width>371</width>
28 <height>221</height>
29 </size>
30 </property>
31 <property name="currentIndex">
32 <number>0</number>
33 </property>
34 <widget class="ConfigureGeneral" name="generalTab">
35 <attribute name="title">
36 <string>General</string>
37 </attribute>
38 </widget>
39 <widget class="QWidget" name="inputTab">
40 <attribute name="title">
41 <string>Input</string>
42 </attribute>
43 </widget>
44 <widget class="ConfigureDebug" name="debugTab">
45 <attribute name="title">
46 <string>Debug</string>
47 </attribute>
48 </widget>
49 </widget>
50 </item>
51 <item>
52 <widget class="QDialogButtonBox" name="buttonBox">
53 <property name="standardButtons">
54 <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
55 </property>
56 </widget>
57 </item>
58 </layout>
59 </widget>
60 <customwidgets>
61 <customwidget>
62 <class>ConfigureGeneral</class>
63 <extends>QWidget</extends>
64 <header>configure_general.h</header>
65 <container>1</container>
66 </customwidget>
67 <customwidget>
68 <class>ConfigureDebug</class>
69 <extends>QWidget</extends>
70 <header>configure_debug.h</header>
71 <container>1</container>
72 </customwidget>
73 </customwidgets>
74 <resources/>
75 <connections>
76 <connection>
77 <sender>buttonBox</sender>
78 <signal>accepted()</signal>
79 <receiver>ConfigureDialog</receiver>
80 <slot>accept()</slot>
81 <hints>
82 <hint type="sourcelabel">
83 <x>220</x>
84 <y>380</y>
85 </hint>
86 <hint type="destinationlabel">
87 <x>220</x>
88 <y>200</y>
89 </hint>
90 </hints>
91 </connection>
92 <connection>
93 <sender>buttonBox</sender>
94 <signal>rejected()</signal>
95 <receiver>ConfigureDialog</receiver>
96 <slot>reject()</slot>
97 <hints>
98 <hint type="sourcelabel">
99 <x>220</x>
100 <y>380</y>
101 </hint>
102 <hint type="destinationlabel">
103 <x>220</x>
104 <y>200</y>
105 </hint>
106 </hints>
107 </connection>
108 </connections>
109</ui>
diff --git a/src/citra_qt/configure_debug.cpp b/src/citra_qt/configure_debug.cpp
new file mode 100644
index 000000000..ba66d0833
--- /dev/null
+++ b/src/citra_qt/configure_debug.cpp
@@ -0,0 +1,32 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "citra_qt/configure_debug.h"
6#include "ui_configure_debug.h"
7
8#include "core/gdbstub/gdbstub.h"
9#include "core/settings.h"
10
11ConfigureDebug::ConfigureDebug(QWidget *parent) :
12 QWidget(parent),
13 ui(new Ui::ConfigureDebug)
14{
15 ui->setupUi(this);
16 this->setConfiguration();
17}
18
19ConfigureDebug::~ConfigureDebug() {
20}
21
22void ConfigureDebug::setConfiguration() {
23 ui->toogle_gdbstub->setChecked(Settings::values.use_gdbstub);
24 ui->gdbport_spinbox->setEnabled(Settings::values.use_gdbstub);
25 ui->gdbport_spinbox->setValue(Settings::values.gdbstub_port);
26}
27
28void ConfigureDebug::applyConfiguration() {
29 GDBStub::ToggleServer(ui->toogle_gdbstub->isChecked());
30 Settings::values.use_gdbstub = ui->toogle_gdbstub->isChecked();
31 Settings::values.gdbstub_port = ui->gdbport_spinbox->value();
32}
diff --git a/src/citra_qt/configure_debug.h b/src/citra_qt/configure_debug.h
new file mode 100644
index 000000000..ab58ebbdc
--- /dev/null
+++ b/src/citra_qt/configure_debug.h
@@ -0,0 +1,29 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <QWidget>
9
10namespace Ui {
11class ConfigureDebug;
12}
13
14class ConfigureDebug : public QWidget
15{
16 Q_OBJECT
17
18public:
19 explicit ConfigureDebug(QWidget *parent = nullptr);
20 ~ConfigureDebug();
21
22 void applyConfiguration();
23
24private:
25 void setConfiguration();
26
27private:
28 std::unique_ptr<Ui::ConfigureDebug> ui;
29};
diff --git a/src/citra_qt/configure_debug.ui b/src/citra_qt/configure_debug.ui
new file mode 100644
index 000000000..3ba7f44da
--- /dev/null
+++ b/src/citra_qt/configure_debug.ui
@@ -0,0 +1,102 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>ConfigureDebug</class>
4 <widget class="QWidget" name="ConfigureDebug">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>400</width>
10 <height>300</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Form</string>
15 </property>
16 <layout class="QVBoxLayout" name="verticalLayout">
17 <item>
18 <layout class="QVBoxLayout" name="verticalLayout_3">
19 <item>
20 <widget class="QGroupBox" name="groupBox">
21 <property name="title">
22 <string>GDB</string>
23 </property>
24 <layout class="QVBoxLayout" name="verticalLayout_2">
25 <item>
26 <layout class="QHBoxLayout" name="horizontalLayout_3">
27 <item>
28 <widget class="QCheckBox" name="toogle_gdbstub">
29 <property name="text">
30 <string>Enable GDB Stub</string>
31 </property>
32 </widget>
33 </item>
34 <item>
35 <spacer name="horizontalSpacer">
36 <property name="orientation">
37 <enum>Qt::Horizontal</enum>
38 </property>
39 <property name="sizeHint" stdset="0">
40 <size>
41 <width>40</width>
42 <height>20</height>
43 </size>
44 </property>
45 </spacer>
46 </item>
47 <item>
48 <widget class="QLabel" name="label">
49 <property name="text">
50 <string>Port:</string>
51 </property>
52 </widget>
53 </item>
54 <item>
55 <widget class="QSpinBox" name="gdbport_spinbox">
56 <property name="maximum">
57 <number>65536</number>
58 </property>
59 </widget>
60 </item>
61 </layout>
62 </item>
63 </layout>
64 </widget>
65 </item>
66 </layout>
67 </item>
68 <item>
69 <spacer name="verticalSpacer">
70 <property name="orientation">
71 <enum>Qt::Vertical</enum>
72 </property>
73 <property name="sizeHint" stdset="0">
74 <size>
75 <width>20</width>
76 <height>40</height>
77 </size>
78 </property>
79 </spacer>
80 </item>
81 </layout>
82 </widget>
83 <resources/>
84 <connections>
85 <connection>
86 <sender>toogle_gdbstub</sender>
87 <signal>toggled(bool)</signal>
88 <receiver>gdbport_spinbox</receiver>
89 <slot>setEnabled(bool)</slot>
90 <hints>
91 <hint type="sourcelabel">
92 <x>84</x>
93 <y>157</y>
94 </hint>
95 <hint type="destinationlabel">
96 <x>342</x>
97 <y>158</y>
98 </hint>
99 </hints>
100 </connection>
101 </connections>
102</ui>
diff --git a/src/citra_qt/configure_dialog.cpp b/src/citra_qt/configure_dialog.cpp
new file mode 100644
index 000000000..87c26c715
--- /dev/null
+++ b/src/citra_qt/configure_dialog.cpp
@@ -0,0 +1,29 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "citra_qt/config.h"
6#include "citra_qt/configure_dialog.h"
7#include "ui_configure.h"
8
9
10#include "core/settings.h"
11
12ConfigureDialog::ConfigureDialog(QWidget *parent) :
13 QDialog(parent),
14 ui(new Ui::ConfigureDialog)
15{
16 ui->setupUi(this);
17 this->setConfiguration();
18}
19
20ConfigureDialog::~ConfigureDialog() {
21}
22
23void ConfigureDialog::setConfiguration() {
24}
25
26void ConfigureDialog::applyConfiguration() {
27 ui->generalTab->applyConfiguration();
28 ui->debugTab->applyConfiguration();
29}
diff --git a/src/citra_qt/configure_dialog.h b/src/citra_qt/configure_dialog.h
new file mode 100644
index 000000000..89020eeb4
--- /dev/null
+++ b/src/citra_qt/configure_dialog.h
@@ -0,0 +1,29 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <QDialog>
9
10namespace Ui {
11class ConfigureDialog;
12}
13
14class ConfigureDialog : public QDialog
15{
16 Q_OBJECT
17
18public:
19 explicit ConfigureDialog(QWidget *parent = nullptr);
20 ~ConfigureDialog();
21
22 void applyConfiguration();
23
24private:
25 void setConfiguration();
26
27private:
28 std::unique_ptr<Ui::ConfigureDialog> ui;
29};
diff --git a/src/citra_qt/configure_general.cpp b/src/citra_qt/configure_general.cpp
new file mode 100644
index 000000000..350bd794d
--- /dev/null
+++ b/src/citra_qt/configure_general.cpp
@@ -0,0 +1,43 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "citra_qt/configure_general.h"
6#include "citra_qt/ui_settings.h"
7#include "ui_configure_general.h"
8
9#include "core/settings.h"
10
11#include "video_core/video_core.h"
12
13ConfigureGeneral::ConfigureGeneral(QWidget *parent) :
14 QWidget(parent),
15 ui(new Ui::ConfigureGeneral)
16{
17 ui->setupUi(this);
18 this->setConfiguration();
19}
20
21ConfigureGeneral::~ConfigureGeneral() {
22}
23
24void ConfigureGeneral::setConfiguration() {
25 ui->toogle_deepscan->setChecked(UISettings::values.gamedir_deepscan);
26 ui->toogle_check_exit->setChecked(UISettings::values.confirm_before_closing);
27 ui->region_combobox->setCurrentIndex(Settings::values.region_value);
28 ui->toogle_hw_renderer->setChecked(Settings::values.use_hw_renderer);
29 ui->toogle_shader_jit->setChecked(Settings::values.use_shader_jit);
30}
31
32void ConfigureGeneral::applyConfiguration() {
33 UISettings::values.gamedir_deepscan = ui->toogle_deepscan->isChecked();
34 UISettings::values.confirm_before_closing = ui->toogle_check_exit->isChecked();
35
36 Settings::values.region_value = ui->region_combobox->currentIndex();
37
38 VideoCore::g_hw_renderer_enabled =
39 Settings::values.use_hw_renderer = ui->toogle_hw_renderer->isChecked();
40
41 VideoCore::g_shader_jit_enabled =
42 Settings::values.use_shader_jit = ui->toogle_shader_jit->isChecked();
43}
diff --git a/src/citra_qt/configure_general.h b/src/citra_qt/configure_general.h
new file mode 100644
index 000000000..a6c68e62d
--- /dev/null
+++ b/src/citra_qt/configure_general.h
@@ -0,0 +1,29 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <QWidget>
9
10namespace Ui {
11class ConfigureGeneral;
12}
13
14class ConfigureGeneral : public QWidget
15{
16 Q_OBJECT
17
18public:
19 explicit ConfigureGeneral(QWidget *parent = nullptr);
20 ~ConfigureGeneral();
21
22 void applyConfiguration();
23
24private:
25 void setConfiguration();
26
27private:
28 std::unique_ptr<Ui::ConfigureGeneral> ui;
29};
diff --git a/src/citra_qt/configure_general.ui b/src/citra_qt/configure_general.ui
new file mode 100644
index 000000000..47184c5c6
--- /dev/null
+++ b/src/citra_qt/configure_general.ui
@@ -0,0 +1,166 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>ConfigureGeneral</class>
4 <widget class="QWidget" name="ConfigureGeneral">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>300</width>
10 <height>377</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Form</string>
15 </property>
16 <layout class="QHBoxLayout" name="horizontalLayout">
17 <item>
18 <layout class="QVBoxLayout" name="verticalLayout">
19 <item>
20 <widget class="QGroupBox" name="groupBox">
21 <property name="title">
22 <string>General</string>
23 </property>
24 <layout class="QHBoxLayout" name="horizontalLayout_3">
25 <item>
26 <layout class="QVBoxLayout" name="verticalLayout_2">
27 <item>
28 <widget class="QCheckBox" name="toogle_deepscan">
29 <property name="text">
30 <string>Recursive scan for game folder</string>
31 </property>
32 </widget>
33 </item>
34 <item>
35 <widget class="QCheckBox" name="toogle_check_exit">
36 <property name="text">
37 <string>Confirm exit while emulation is running</string>
38 </property>
39 </widget>
40 </item>
41 </layout>
42 </item>
43 </layout>
44 </widget>
45 </item>
46 <item>
47 <widget class="QGroupBox" name="groupBox_4">
48 <property name="title">
49 <string>Emulation</string>
50 </property>
51 <layout class="QHBoxLayout" name="horizontalLayout_5">
52 <item>
53 <layout class="QVBoxLayout" name="verticalLayout_6">
54 <item>
55 <layout class="QHBoxLayout" name="horizontalLayout_6">
56 <item>
57 <widget class="QLabel" name="label">
58 <property name="text">
59 <string>Region:</string>
60 </property>
61 </widget>
62 </item>
63 <item>
64 <widget class="QComboBox" name="region_combobox">
65 <item>
66 <property name="text">
67 <string notr="true">JPN</string>
68 </property>
69 </item>
70 <item>
71 <property name="text">
72 <string notr="true">USA</string>
73 </property>
74 </item>
75 <item>
76 <property name="text">
77 <string notr="true">EUR</string>
78 </property>
79 </item>
80 <item>
81 <property name="text">
82 <string notr="true">AUS</string>
83 </property>
84 </item>
85 <item>
86 <property name="text">
87 <string notr="true">CHN</string>
88 </property>
89 </item>
90 <item>
91 <property name="text">
92 <string notr="true">KOR</string>
93 </property>
94 </item>
95 <item>
96 <property name="text">
97 <string notr="true">TWN</string>
98 </property>
99 </item>
100 </widget>
101 </item>
102 </layout>
103 </item>
104 </layout>
105 </item>
106 </layout>
107 </widget>
108 </item>
109 <item>
110 <widget class="QGroupBox" name="groupBox_2">
111 <property name="title">
112 <string>Performance</string>
113 </property>
114 <layout class="QHBoxLayout" name="horizontalLayout_2">
115 <item>
116 <layout class="QVBoxLayout" name="verticalLayout_3">
117 <item>
118 <widget class="QCheckBox" name="toogle_hw_renderer">
119 <property name="text">
120 <string>Enable hardware renderer</string>
121 </property>
122 </widget>
123 </item>
124 <item>
125 <widget class="QCheckBox" name="toogle_shader_jit">
126 <property name="text">
127 <string>Enable shader JIT</string>
128 </property>
129 </widget>
130 </item>
131 </layout>
132 </item>
133 </layout>
134 </widget>
135 </item>
136 <item>
137 <widget class="QGroupBox" name="groupBox_3">
138 <property name="title">
139 <string>Hotkeys</string>
140 </property>
141 <layout class="QHBoxLayout" name="horizontalLayout_4">
142 <item>
143 <layout class="QVBoxLayout" name="verticalLayout_4">
144 <item>
145 <widget class="GHotkeysDialog" name="widget" native="true"/>
146 </item>
147 </layout>
148 </item>
149 </layout>
150 </widget>
151 </item>
152 </layout>
153 </item>
154 </layout>
155 </widget>
156 <customwidgets>
157 <customwidget>
158 <class>GHotkeysDialog</class>
159 <extends>QWidget</extends>
160 <header>hotkeys.h</header>
161 <container>1</container>
162 </customwidget>
163 </customwidgets>
164 <resources/>
165 <connections/>
166</ui>
diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp
index ffcab1f03..d14532102 100644
--- a/src/citra_qt/game_list.cpp
+++ b/src/citra_qt/game_list.cpp
@@ -8,6 +8,7 @@
8 8
9#include "game_list.h" 9#include "game_list.h"
10#include "game_list_p.h" 10#include "game_list_p.h"
11#include "ui_settings.h"
11 12
12#include "core/loader/loader.h" 13#include "core/loader/loader.h"
13 14
@@ -100,19 +101,15 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan)
100 current_worker = std::move(worker); 101 current_worker = std::move(worker);
101} 102}
102 103
103void GameList::SaveInterfaceLayout(QSettings& settings) 104void GameList::SaveInterfaceLayout()
104{ 105{
105 settings.beginGroup("UILayout"); 106 UISettings::values.gamelist_header_state = tree_view->header()->saveState();
106 settings.setValue("gameListHeaderState", tree_view->header()->saveState());
107 settings.endGroup();
108} 107}
109 108
110void GameList::LoadInterfaceLayout(QSettings& settings) 109void GameList::LoadInterfaceLayout()
111{ 110{
112 auto header = tree_view->header(); 111 auto header = tree_view->header();
113 settings.beginGroup("UILayout"); 112 header->restoreState(UISettings::values.gamelist_header_state);
114 header->restoreState(settings.value("gameListHeaderState").toByteArray());
115 settings.endGroup();
116 113
117 item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder()); 114 item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder());
118} 115}
diff --git a/src/citra_qt/game_list.h b/src/citra_qt/game_list.h
index 0950d9622..48febdc60 100644
--- a/src/citra_qt/game_list.h
+++ b/src/citra_qt/game_list.h
@@ -31,8 +31,8 @@ public:
31 31
32 void PopulateAsync(const QString& dir_path, bool deep_scan); 32 void PopulateAsync(const QString& dir_path, bool deep_scan);
33 33
34 void SaveInterfaceLayout(QSettings& settings); 34 void SaveInterfaceLayout();
35 void LoadInterfaceLayout(QSettings& settings); 35 void LoadInterfaceLayout();
36 36
37public slots: 37public slots:
38 void AddEntry(QList<QStandardItem*> entry_items); 38 void AddEntry(QList<QStandardItem*> entry_items);
diff --git a/src/citra_qt/hotkeys.cpp b/src/citra_qt/hotkeys.cpp
index ed6b12fc4..41f95c63d 100644
--- a/src/citra_qt/hotkeys.cpp
+++ b/src/citra_qt/hotkeys.cpp
@@ -4,11 +4,12 @@
4 4
5#include <map> 5#include <map>
6 6
7#include <QtGlobal>
7#include <QKeySequence> 8#include <QKeySequence>
8#include <QSettings>
9#include <QShortcut> 9#include <QShortcut>
10 10
11#include "citra_qt/hotkeys.h" 11#include "citra_qt/hotkeys.h"
12#include "citra_qt/ui_settings.h"
12 13
13struct Hotkey 14struct Hotkey
14{ 15{
@@ -24,54 +25,39 @@ typedef std::map<QString, HotkeyMap> HotkeyGroupMap;
24 25
25HotkeyGroupMap hotkey_groups; 26HotkeyGroupMap hotkey_groups;
26 27
27void SaveHotkeys(QSettings& settings) 28void SaveHotkeys()
28{ 29{
29 settings.beginGroup("Shortcuts"); 30 UISettings::values.shortcuts.clear();
30
31 for (auto group : hotkey_groups) 31 for (auto group : hotkey_groups)
32 { 32 {
33 settings.beginGroup(group.first);
34 for (auto hotkey : group.second) 33 for (auto hotkey : group.second)
35 { 34 {
36 settings.beginGroup(hotkey.first); 35 UISettings::values.shortcuts.emplace_back(
37 settings.setValue(QString("KeySeq"), hotkey.second.keyseq.toString()); 36 UISettings::Shortcut(group.first + "/" + hotkey.first,
38 settings.setValue(QString("Context"), hotkey.second.context); 37 UISettings::ContextualShortcut(hotkey.second.keyseq.toString(),
39 settings.endGroup(); 38 hotkey.second.context)));
40 } 39 }
41 settings.endGroup();
42 } 40 }
43 settings.endGroup();
44} 41}
45 42
46void LoadHotkeys(QSettings& settings) 43void LoadHotkeys()
47{ 44{
48 settings.beginGroup("Shortcuts");
49
50 // Make sure NOT to use a reference here because it would become invalid once we call beginGroup() 45 // Make sure NOT to use a reference here because it would become invalid once we call beginGroup()
51 QStringList groups = settings.childGroups(); 46 for (auto shortcut : UISettings::values.shortcuts)
52 for (auto group : groups)
53 { 47 {
54 settings.beginGroup(group); 48 QStringList cat = shortcut.first.split("/");
49 Q_ASSERT(cat.size() >= 2);
55 50
56 QStringList hotkeys = settings.childGroups(); 51 // RegisterHotkey assigns default keybindings, so use old values as default parameters
57 for (auto hotkey : hotkeys) 52 Hotkey& hk = hotkey_groups[cat[0]][cat[1]];
53 if (!shortcut.second.first.isEmpty())
58 { 54 {
59 settings.beginGroup(hotkey); 55 hk.keyseq = QKeySequence::fromString(shortcut.second.first);
60 56 hk.context = (Qt::ShortcutContext)shortcut.second.second;
61 // RegisterHotkey assigns default keybindings, so use old values as default parameters
62 Hotkey& hk = hotkey_groups[group][hotkey];
63 hk.keyseq = QKeySequence::fromString(settings.value("KeySeq", hk.keyseq.toString()).toString());
64 hk.context = (Qt::ShortcutContext)settings.value("Context", hk.context).toInt();
65 if (hk.shortcut)
66 hk.shortcut->setKey(hk.keyseq);
67
68 settings.endGroup();
69 } 57 }
70 58 if (hk.shortcut)
71 settings.endGroup(); 59 hk.shortcut->setKey(hk.keyseq);
72 } 60 }
73
74 settings.endGroup();
75} 61}
76 62
77void RegisterHotkey(const QString& group, const QString& action, const QKeySequence& default_keyseq, Qt::ShortcutContext default_context) 63void RegisterHotkey(const QString& group, const QString& action, const QKeySequence& default_keyseq, Qt::ShortcutContext default_context)
@@ -94,7 +80,7 @@ QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widge
94} 80}
95 81
96 82
97GHotkeysDialog::GHotkeysDialog(QWidget* parent): QDialog(parent) 83GHotkeysDialog::GHotkeysDialog(QWidget* parent): QWidget(parent)
98{ 84{
99 ui.setupUi(this); 85 ui.setupUi(this);
100 86
diff --git a/src/citra_qt/hotkeys.h b/src/citra_qt/hotkeys.h
index 2fe635882..38aa5f012 100644
--- a/src/citra_qt/hotkeys.h
+++ b/src/citra_qt/hotkeys.h
@@ -2,6 +2,8 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once
6
5#include "ui_hotkeys.h" 7#include "ui_hotkeys.h"
6 8
7class QDialog; 9class QDialog;
@@ -33,16 +35,16 @@ QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widge
33 * 35 *
34 * @note Each hotkey group will be stored a settings group; For each hotkey inside that group, a settings group will be created to store the key sequence and the hotkey context. 36 * @note Each hotkey group will be stored a settings group; For each hotkey inside that group, a settings group will be created to store the key sequence and the hotkey context.
35 */ 37 */
36void SaveHotkeys(QSettings& settings); 38void SaveHotkeys();
37 39
38/** 40/**
39 * Loads hotkeys from the settings file. 41 * Loads hotkeys from the settings file.
40 * 42 *
41 * @note Yet unregistered hotkeys which are present in the settings will automatically be registered. 43 * @note Yet unregistered hotkeys which are present in the settings will automatically be registered.
42 */ 44 */
43void LoadHotkeys(QSettings& settings); 45void LoadHotkeys();
44 46
45class GHotkeysDialog : public QDialog 47class GHotkeysDialog : public QWidget
46{ 48{
47 Q_OBJECT 49 Q_OBJECT
48 50
diff --git a/src/citra_qt/hotkeys.ui b/src/citra_qt/hotkeys.ui
index 38a9a14d1..050fe064e 100644
--- a/src/citra_qt/hotkeys.ui
+++ b/src/citra_qt/hotkeys.ui
@@ -1,7 +1,7 @@
1<?xml version="1.0" encoding="UTF-8"?> 1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0"> 2<ui version="4.0">
3 <class>hotkeys</class> 3 <class>hotkeys</class>
4 <widget class="QDialog" name="hotkeys"> 4 <widget class="QWidget" name="hotkeys">
5 <property name="geometry"> 5 <property name="geometry">
6 <rect> 6 <rect>
7 <x>0</x> 7 <x>0</x>
@@ -39,51 +39,8 @@
39 </column> 39 </column>
40 </widget> 40 </widget>
41 </item> 41 </item>
42 <item>
43 <widget class="QDialogButtonBox" name="buttonBox">
44 <property name="orientation">
45 <enum>Qt::Horizontal</enum>
46 </property>
47 <property name="standardButtons">
48 <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset</set>
49 </property>
50 </widget>
51 </item>
52 </layout> 42 </layout>
53 </widget> 43 </widget>
54 <resources/> 44 <resources/>
55 <connections> 45 <connections/>
56 <connection>
57 <sender>buttonBox</sender>
58 <signal>accepted()</signal>
59 <receiver>hotkeys</receiver>
60 <slot>accept()</slot>
61 <hints>
62 <hint type="sourcelabel">
63 <x>248</x>
64 <y>254</y>
65 </hint>
66 <hint type="destinationlabel">
67 <x>157</x>
68 <y>274</y>
69 </hint>
70 </hints>
71 </connection>
72 <connection>
73 <sender>buttonBox</sender>
74 <signal>rejected()</signal>
75 <receiver>hotkeys</receiver>
76 <slot>reject()</slot>
77 <hints>
78 <hint type="sourcelabel">
79 <x>316</x>
80 <y>260</y>
81 </hint>
82 <hint type="destinationlabel">
83 <x>286</x>
84 <y>274</y>
85 </hint>
86 </hints>
87 </connection>
88 </connections>
89</ui> 46</ui>
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index ca0ae6f7b..23eb28259 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -14,9 +14,11 @@
14 14
15#include "citra_qt/bootmanager.h" 15#include "citra_qt/bootmanager.h"
16#include "citra_qt/config.h" 16#include "citra_qt/config.h"
17#include "citra_qt/configure_dialog.h"
17#include "citra_qt/game_list.h" 18#include "citra_qt/game_list.h"
18#include "citra_qt/hotkeys.h" 19#include "citra_qt/hotkeys.h"
19#include "citra_qt/main.h" 20#include "citra_qt/main.h"
21#include "citra_qt/ui_settings.h"
20 22
21// Debugger 23// Debugger
22#include "citra_qt/debugger/callstack.h" 24#include "citra_qt/debugger/callstack.h"
@@ -50,12 +52,10 @@
50 52
51#include "video_core/video_core.h" 53#include "video_core/video_core.h"
52 54
53GMainWindow::GMainWindow() : emu_thread(nullptr) 55GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr)
54{ 56{
55 Pica::g_debug_context = Pica::DebugContext::Construct(); 57 Pica::g_debug_context = Pica::DebugContext::Construct();
56 58
57 Config config;
58
59 ui.setupUi(this); 59 ui.setupUi(this);
60 statusBar()->hide(); 60 statusBar()->hide();
61 61
@@ -133,33 +133,21 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
133 setGeometry(x, y, w, h); 133 setGeometry(x, y, w, h);
134 134
135 // Restore UI state 135 // Restore UI state
136 QSettings settings; 136 restoreGeometry(UISettings::values.geometry);
137 137 restoreState(UISettings::values.state);
138 settings.beginGroup("UILayout"); 138 render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
139 restoreGeometry(settings.value("geometry").toByteArray()); 139 microProfileDialog->restoreGeometry(UISettings::values.microprofile_geometry);
140 restoreState(settings.value("state").toByteArray()); 140 microProfileDialog->setVisible(UISettings::values.microprofile_visible);
141 render_window->restoreGeometry(settings.value("geometryRenderWindow").toByteArray());
142 microProfileDialog->restoreGeometry(settings.value("microProfileDialogGeometry").toByteArray());
143 microProfileDialog->setVisible(settings.value("microProfileDialogVisible").toBool());
144 settings.endGroup();
145
146 game_list->LoadInterfaceLayout(settings);
147 141
148 ui.action_Use_Gdbstub->setChecked(Settings::values.use_gdbstub); 142 game_list->LoadInterfaceLayout();
149 SetGdbstubEnabled(ui.action_Use_Gdbstub->isChecked());
150 143
144 GDBStub::ToggleServer(Settings::values.use_gdbstub);
151 GDBStub::SetServerPort(static_cast<u32>(Settings::values.gdbstub_port)); 145 GDBStub::SetServerPort(static_cast<u32>(Settings::values.gdbstub_port));
152 146
153 ui.action_Use_Hardware_Renderer->setChecked(Settings::values.use_hw_renderer); 147 ui.action_Single_Window_Mode->setChecked(UISettings::values.single_window_mode);
154 SetHardwareRendererEnabled(ui.action_Use_Hardware_Renderer->isChecked());
155
156 ui.action_Use_Shader_JIT->setChecked(Settings::values.use_shader_jit);
157 SetShaderJITEnabled(ui.action_Use_Shader_JIT->isChecked());
158
159 ui.action_Single_Window_Mode->setChecked(settings.value("singleWindowMode", true).toBool());
160 ToggleWindowMode(); 148 ToggleWindowMode();
161 149
162 ui.actionDisplay_widget_title_bars->setChecked(settings.value("displayTitleBars", true).toBool()); 150 ui.actionDisplay_widget_title_bars->setChecked(UISettings::values.display_titlebar);
163 OnDisplayTitleBars(ui.actionDisplay_widget_title_bars->isChecked()); 151 OnDisplayTitleBars(ui.actionDisplay_widget_title_bars->isChecked());
164 152
165 // Prepare actions for recent files 153 // Prepare actions for recent files
@@ -172,21 +160,16 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
172 } 160 }
173 UpdateRecentFiles(); 161 UpdateRecentFiles();
174 162
175 confirm_before_closing = settings.value("confirmClose", true).toBool();
176
177 // Setup connections 163 // Setup connections
178 connect(game_list, SIGNAL(GameChosen(QString)), this, SLOT(OnGameListLoadFile(QString))); 164 connect(game_list, SIGNAL(GameChosen(QString)), this, SLOT(OnGameListLoadFile(QString)), Qt::DirectConnection);
179 connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile())); 165 connect(ui.action_Configure, SIGNAL(triggered()), this, SLOT(OnConfigure()));
166 connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile()),Qt::DirectConnection);
180 connect(ui.action_Load_Symbol_Map, SIGNAL(triggered()), this, SLOT(OnMenuLoadSymbolMap())); 167 connect(ui.action_Load_Symbol_Map, SIGNAL(triggered()), this, SLOT(OnMenuLoadSymbolMap()));
181 connect(ui.action_Select_Game_List_Root, SIGNAL(triggered()), this, SLOT(OnMenuSelectGameListRoot())); 168 connect(ui.action_Select_Game_List_Root, SIGNAL(triggered()), this, SLOT(OnMenuSelectGameListRoot()));
182 connect(ui.action_Start, SIGNAL(triggered()), this, SLOT(OnStartGame())); 169 connect(ui.action_Start, SIGNAL(triggered()), this, SLOT(OnStartGame()));
183 connect(ui.action_Pause, SIGNAL(triggered()), this, SLOT(OnPauseGame())); 170 connect(ui.action_Pause, SIGNAL(triggered()), this, SLOT(OnPauseGame()));
184 connect(ui.action_Stop, SIGNAL(triggered()), this, SLOT(OnStopGame())); 171 connect(ui.action_Stop, SIGNAL(triggered()), this, SLOT(OnStopGame()));
185 connect(ui.action_Use_Hardware_Renderer, SIGNAL(triggered(bool)), this, SLOT(SetHardwareRendererEnabled(bool)));
186 connect(ui.action_Use_Shader_JIT, SIGNAL(triggered(bool)), this, SLOT(SetShaderJITEnabled(bool)));
187 connect(ui.action_Use_Gdbstub, SIGNAL(triggered(bool)), this, SLOT(SetGdbstubEnabled(bool)));
188 connect(ui.action_Single_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(ToggleWindowMode())); 172 connect(ui.action_Single_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(ToggleWindowMode()));
189 connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog()));
190 173
191 connect(this, SIGNAL(EmulationStarting(EmuThread*)), disasmWidget, SLOT(OnEmulationStarting(EmuThread*))); 174 connect(this, SIGNAL(EmulationStarting(EmuThread*)), disasmWidget, SLOT(OnEmulationStarting(EmuThread*)));
192 connect(this, SIGNAL(EmulationStopping()), disasmWidget, SLOT(OnEmulationStopping())); 175 connect(this, SIGNAL(EmulationStopping()), disasmWidget, SLOT(OnEmulationStopping()));
@@ -201,7 +184,7 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
201 // Setup hotkeys 184 // Setup hotkeys
202 RegisterHotkey("Main Window", "Load File", QKeySequence::Open); 185 RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
203 RegisterHotkey("Main Window", "Start Emulation"); 186 RegisterHotkey("Main Window", "Start Emulation");
204 LoadHotkeys(settings); 187 LoadHotkeys();
205 188
206 connect(GetHotkey("Main Window", "Load File", this), SIGNAL(activated()), this, SLOT(OnMenuLoadFile())); 189 connect(GetHotkey("Main Window", "Load File", this), SIGNAL(activated()), this, SLOT(OnMenuLoadFile()));
207 connect(GetHotkey("Main Window", "Start Emulation", this), SIGNAL(activated()), this, SLOT(OnStartGame())); 190 connect(GetHotkey("Main Window", "Start Emulation", this), SIGNAL(activated()), this, SLOT(OnStartGame()));
@@ -211,7 +194,7 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
211 194
212 show(); 195 show();
213 196
214 game_list->PopulateAsync(settings.value("gameListRootDir", ".").toString(), settings.value("gameListDeepScan", false).toBool()); 197 game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
215 198
216 QStringList args = QApplication::arguments(); 199 QStringList args = QApplication::arguments();
217 if (args.length() >= 2) { 200 if (args.length() >= 2) {
@@ -375,32 +358,24 @@ void GMainWindow::ShutdownGame() {
375 emulation_running = false; 358 emulation_running = false;
376} 359}
377 360
378void GMainWindow::StoreRecentFile(const std::string& filename) 361void GMainWindow::StoreRecentFile(const std::string& filename) {
379{ 362 UISettings::values.recent_files.prepend(QString::fromStdString(filename));
380 QSettings settings; 363 UISettings::values.recent_files.removeDuplicates();
381 QStringList recent_files = settings.value("recentFiles").toStringList(); 364 while (UISettings::values.recent_files.size() > max_recent_files_item) {
382 recent_files.prepend(QString::fromStdString(filename)); 365 UISettings::values.recent_files.removeLast();
383 recent_files.removeDuplicates();
384 while (recent_files.size() > max_recent_files_item) {
385 recent_files.removeLast();
386 } 366 }
387 367
388 settings.setValue("recentFiles", recent_files);
389
390 UpdateRecentFiles(); 368 UpdateRecentFiles();
391} 369}
392 370
393void GMainWindow::UpdateRecentFiles() { 371void GMainWindow::UpdateRecentFiles() {
394 QSettings settings; 372 unsigned int num_recent_files = std::min(UISettings::values.recent_files.size(), static_cast<int>(max_recent_files_item));
395 QStringList recent_files = settings.value("recentFiles").toStringList();
396
397 unsigned int num_recent_files = std::min(recent_files.size(), static_cast<int>(max_recent_files_item));
398 373
399 for (unsigned int i = 0; i < num_recent_files; i++) { 374 for (unsigned int i = 0; i < num_recent_files; i++) {
400 QString text = QString("&%1. %2").arg(i + 1).arg(QFileInfo(recent_files[i]).fileName()); 375 QString text = QString("&%1. %2").arg(i + 1).arg(QFileInfo(UISettings::values.recent_files[i]).fileName());
401 actions_recent_files[i]->setText(text); 376 actions_recent_files[i]->setText(text);
402 actions_recent_files[i]->setData(recent_files[i]); 377 actions_recent_files[i]->setData(UISettings::values.recent_files[i]);
403 actions_recent_files[i]->setToolTip(recent_files[i]); 378 actions_recent_files[i]->setToolTip(UISettings::values.recent_files[i]);
404 actions_recent_files[i]->setVisible(true); 379 actions_recent_files[i]->setVisible(true);
405 } 380 }
406 381
@@ -421,36 +396,28 @@ void GMainWindow::OnGameListLoadFile(QString game_path) {
421} 396}
422 397
423void GMainWindow::OnMenuLoadFile() { 398void GMainWindow::OnMenuLoadFile() {
424 QSettings settings; 399 QString filename = QFileDialog::getOpenFileName(this, tr("Load File"), UISettings::values.roms_path, tr("3DS executable (*.3ds *.3dsx *.elf *.axf *.cci *.cxi)"));
425 QString rom_path = settings.value("romsPath", QString()).toString();
426
427 QString filename = QFileDialog::getOpenFileName(this, tr("Load File"), rom_path, tr("3DS executable (*.3ds *.3dsx *.elf *.axf *.cci *.cxi)"));
428 if (!filename.isEmpty()) { 400 if (!filename.isEmpty()) {
429 settings.setValue("romsPath", QFileInfo(filename).path()); 401 UISettings::values.roms_path = QFileInfo(filename).path();
430 402
431 BootGame(filename.toStdString()); 403 BootGame(filename.toStdString());
432 } 404 }
433} 405}
434 406
435void GMainWindow::OnMenuLoadSymbolMap() { 407void GMainWindow::OnMenuLoadSymbolMap() {
436 QSettings settings; 408 QString filename = QFileDialog::getOpenFileName(this, tr("Load Symbol Map"), UISettings::values.symbols_path, tr("Symbol map (*)"));
437 QString symbol_path = settings.value("symbolsPath", QString()).toString();
438
439 QString filename = QFileDialog::getOpenFileName(this, tr("Load Symbol Map"), symbol_path, tr("Symbol map (*)"));
440 if (!filename.isEmpty()) { 409 if (!filename.isEmpty()) {
441 settings.setValue("symbolsPath", QFileInfo(filename).path()); 410 UISettings::values.symbols_path = QFileInfo(filename).path();
442 411
443 LoadSymbolMap(filename.toStdString()); 412 LoadSymbolMap(filename.toStdString());
444 } 413 }
445} 414}
446 415
447void GMainWindow::OnMenuSelectGameListRoot() { 416void GMainWindow::OnMenuSelectGameListRoot() {
448 QSettings settings;
449
450 QString dir_path = QFileDialog::getExistingDirectory(this, tr("Select Directory")); 417 QString dir_path = QFileDialog::getExistingDirectory(this, tr("Select Directory"));
451 if (!dir_path.isEmpty()) { 418 if (!dir_path.isEmpty()) {
452 settings.setValue("gameListRootDir", dir_path); 419 UISettings::values.gamedir = dir_path;
453 game_list->PopulateAsync(dir_path, settings.value("gameListDeepScan").toBool()); 420 game_list->PopulateAsync(dir_path, UISettings::values.gamedir_deepscan);
454 } 421 }
455} 422}
456 423
@@ -466,10 +433,7 @@ void GMainWindow::OnMenuRecentFile() {
466 // Display an error message and remove the file from the list. 433 // Display an error message and remove the file from the list.
467 QMessageBox::information(this, tr("File not found"), tr("File \"%1\" not found").arg(filename)); 434 QMessageBox::information(this, tr("File not found"), tr("File \"%1\" not found").arg(filename));
468 435
469 QSettings settings; 436 UISettings::values.recent_files.removeOne(filename);
470 QStringList recent_files = settings.value("recentFiles").toStringList();
471 recent_files.removeOne(filename);
472 settings.setValue("recentFiles", recent_files);
473 UpdateRecentFiles(); 437 UpdateRecentFiles();
474 } 438 }
475} 439}
@@ -496,31 +460,6 @@ void GMainWindow::OnStopGame() {
496 ShutdownGame(); 460 ShutdownGame();
497} 461}
498 462
499void GMainWindow::OnOpenHotkeysDialog() {
500 GHotkeysDialog dialog(this);
501 dialog.exec();
502}
503
504void GMainWindow::SetHardwareRendererEnabled(bool enabled) {
505 VideoCore::g_hw_renderer_enabled = enabled;
506
507 Config config;
508 Settings::values.use_hw_renderer = enabled;
509 config.Save();
510}
511
512void GMainWindow::SetGdbstubEnabled(bool enabled) {
513 GDBStub::ToggleServer(enabled);
514}
515
516void GMainWindow::SetShaderJITEnabled(bool enabled) {
517 VideoCore::g_shader_jit_enabled = enabled;
518
519 Config config;
520 Settings::values.use_shader_jit = enabled;
521 config.Save();
522}
523
524void GMainWindow::ToggleWindowMode() { 463void GMainWindow::ToggleWindowMode() {
525 if (ui.action_Single_Window_Mode->isChecked()) { 464 if (ui.action_Single_Window_Mode->isChecked()) {
526 // Render in the main window... 465 // Render in the main window...
@@ -547,11 +486,17 @@ void GMainWindow::ToggleWindowMode() {
547} 486}
548 487
549void GMainWindow::OnConfigure() { 488void GMainWindow::OnConfigure() {
550 //GControllerConfigDialog* dialog = new GControllerConfigDialog(controller_ports, this); 489 ConfigureDialog configureDialog(this);
490 auto result = configureDialog.exec();
491 if (result == QDialog::Accepted)
492 {
493 configureDialog.applyConfiguration();
494 config->Save();
495 }
551} 496}
552 497
553bool GMainWindow::ConfirmClose() { 498bool GMainWindow::ConfirmClose() {
554 if (emu_thread == nullptr || !confirm_before_closing) 499 if (emu_thread == nullptr || !UISettings::values.confirm_before_closing)
555 return true; 500 return true;
556 501
557 auto answer = QMessageBox::question(this, tr("Citra"), 502 auto answer = QMessageBox::question(this, tr("Citra"),
@@ -566,23 +511,18 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
566 return; 511 return;
567 } 512 }
568 513
569 // Save window layout 514 UISettings::values.geometry = saveGeometry();
570 QSettings settings(QSettings::IniFormat, QSettings::UserScope, "Citra team", "Citra"); 515 UISettings::values.state = saveState();
516 UISettings::values.renderwindow_geometry = render_window->saveGeometry();
517 UISettings::values.microprofile_geometry = microProfileDialog->saveGeometry();
518 UISettings::values.microprofile_visible = microProfileDialog->isVisible();
571 519
572 settings.beginGroup("UILayout"); 520 UISettings::values.single_window_mode = ui.action_Single_Window_Mode->isChecked();
573 settings.setValue("geometry", saveGeometry()); 521 UISettings::values.display_titlebar = ui.actionDisplay_widget_title_bars->isChecked();
574 settings.setValue("state", saveState()); 522 UISettings::values.first_start = false;
575 settings.setValue("geometryRenderWindow", render_window->saveGeometry());
576 settings.setValue("microProfileDialogGeometry", microProfileDialog->saveGeometry());
577 settings.setValue("microProfileDialogVisible", microProfileDialog->isVisible());
578 settings.endGroup();
579 523
580 settings.setValue("singleWindowMode", ui.action_Single_Window_Mode->isChecked()); 524 game_list->SaveInterfaceLayout();
581 settings.setValue("displayTitleBars", ui.actionDisplay_widget_title_bars->isChecked()); 525 SaveHotkeys();
582 settings.setValue("firstStart", false);
583 settings.setValue("confirmClose", confirm_before_closing);
584 game_list->SaveInterfaceLayout(settings);
585 SaveHotkeys(settings);
586 526
587 // Shutdown session if the emu thread is active... 527 // Shutdown session if the emu thread is active...
588 if (emu_thread != nullptr) 528 if (emu_thread != nullptr)
@@ -607,7 +547,6 @@ int main(int argc, char* argv[]) {
607 }); 547 });
608 548
609 // Init settings params 549 // Init settings params
610 QSettings::setDefaultFormat(QSettings::IniFormat);
611 QCoreApplication::setOrganizationName("Citra team"); 550 QCoreApplication::setOrganizationName("Citra team");
612 QCoreApplication::setApplicationName("Citra"); 551 QCoreApplication::setApplicationName("Citra");
613 552
diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h
index 6e4e56689..477db5c5c 100644
--- a/src/citra_qt/main.h
+++ b/src/citra_qt/main.h
@@ -10,6 +10,7 @@
10 10
11#include "ui_main.h" 11#include "ui_main.h"
12 12
13class Config;
13class GameList; 14class GameList;
14class GImageInfo; 15class GImageInfo;
15class GRenderWindow; 16class GRenderWindow;
@@ -104,12 +105,8 @@ private slots:
104 /// Called whenever a user selects the "File->Select Game List Root" menu item 105 /// Called whenever a user selects the "File->Select Game List Root" menu item
105 void OnMenuSelectGameListRoot(); 106 void OnMenuSelectGameListRoot();
106 void OnMenuRecentFile(); 107 void OnMenuRecentFile();
107 void OnOpenHotkeysDialog();
108 void OnConfigure(); 108 void OnConfigure();
109 void OnDisplayTitleBars(bool); 109 void OnDisplayTitleBars(bool);
110 void SetHardwareRendererEnabled(bool);
111 void SetGdbstubEnabled(bool);
112 void SetShaderJITEnabled(bool);
113 void ToggleWindowMode(); 110 void ToggleWindowMode();
114 111
115private: 112private:
@@ -118,6 +115,8 @@ private:
118 GRenderWindow* render_window; 115 GRenderWindow* render_window;
119 GameList* game_list; 116 GameList* game_list;
120 117
118 std::unique_ptr<Config> config;
119
121 // Whether emulation is currently running in Citra. 120 // Whether emulation is currently running in Citra.
122 bool emulation_running = false; 121 bool emulation_running = false;
123 std::unique_ptr<EmuThread> emu_thread; 122 std::unique_ptr<EmuThread> emu_thread;
@@ -131,7 +130,6 @@ private:
131 GPUCommandListWidget* graphicsCommandsWidget; 130 GPUCommandListWidget* graphicsCommandsWidget;
132 131
133 QAction* actions_recent_files[max_recent_files_item]; 132 QAction* actions_recent_files[max_recent_files_item];
134 bool confirm_before_closing;
135}; 133};
136 134
137#endif // _CITRA_QT_MAIN_HXX_ 135#endif // _CITRA_QT_MAIN_HXX_
diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui
index 1e8a07cfb..441e0b81e 100644
--- a/src/citra_qt/main.ui
+++ b/src/citra_qt/main.ui
@@ -45,7 +45,7 @@
45 <x>0</x> 45 <x>0</x>
46 <y>0</y> 46 <y>0</y>
47 <width>1081</width> 47 <width>1081</width>
48 <height>22</height> 48 <height>19</height>
49 </rect> 49 </rect>
50 </property> 50 </property>
51 <widget class="QMenu" name="menu_File"> 51 <widget class="QMenu" name="menu_File">
@@ -73,9 +73,6 @@
73 <addaction name="action_Pause"/> 73 <addaction name="action_Pause"/>
74 <addaction name="action_Stop"/> 74 <addaction name="action_Stop"/>
75 <addaction name="separator"/> 75 <addaction name="separator"/>
76 <addaction name="action_Use_Hardware_Renderer"/>
77 <addaction name="action_Use_Shader_JIT"/>
78 <addaction name="action_Use_Gdbstub"/>
79 <addaction name="action_Configure"/> 76 <addaction name="action_Configure"/>
80 </widget> 77 </widget>
81 <widget class="QMenu" name="menu_View"> 78 <widget class="QMenu" name="menu_View">
@@ -84,7 +81,6 @@
84 </property> 81 </property>
85 <addaction name="action_Single_Window_Mode"/> 82 <addaction name="action_Single_Window_Mode"/>
86 <addaction name="actionDisplay_widget_title_bars"/> 83 <addaction name="actionDisplay_widget_title_bars"/>
87 <addaction name="action_Hotkeys"/>
88 </widget> 84 </widget>
89 <widget class="QMenu" name="menu_Help"> 85 <widget class="QMenu" name="menu_Help">
90 <property name="title"> 86 <property name="title">
@@ -150,35 +146,6 @@
150 <string>Single Window Mode</string> 146 <string>Single Window Mode</string>
151 </property> 147 </property>
152 </action> 148 </action>
153 <action name="action_Hotkeys">
154 <property name="text">
155 <string>Configure &amp;Hotkeys ...</string>
156 </property>
157 </action>
158 <action name="action_Use_Hardware_Renderer">
159 <property name="checkable">
160 <bool>true</bool>
161 </property>
162 <property name="text">
163 <string>Use Hardware Renderer</string>
164 </property>
165 </action>
166 <action name="action_Use_Shader_JIT">
167 <property name="checkable">
168 <bool>true</bool>
169 </property>
170 <property name="text">
171 <string>Use Shader JIT</string>
172 </property>
173 </action>
174 <action name="action_Use_Gdbstub">
175 <property name="checkable">
176 <bool>true</bool>
177 </property>
178 <property name="text">
179 <string>Use Gdbstub</string>
180 </property>
181 </action>
182 <action name="action_Configure"> 149 <action name="action_Configure">
183 <property name="text"> 150 <property name="text">
184 <string>Configure ...</string> 151 <string>Configure ...</string>
@@ -220,22 +187,6 @@
220 </hints> 187 </hints>
221 </connection> 188 </connection>
222 <connection> 189 <connection>
223 <sender>action_Configure</sender>
224 <signal>triggered()</signal>
225 <receiver>MainWindow</receiver>
226 <slot>OnConfigure()</slot>
227 <hints>
228 <hint type="sourcelabel">
229 <x>-1</x>
230 <y>-1</y>
231 </hint>
232 <hint type="destinationlabel">
233 <x>540</x>
234 <y>364</y>
235 </hint>
236 </hints>
237 </connection>
238 <connection>
239 <sender>actionDisplay_widget_title_bars</sender> 190 <sender>actionDisplay_widget_title_bars</sender>
240 <signal>triggered(bool)</signal> 191 <signal>triggered(bool)</signal>
241 <receiver>MainWindow</receiver> 192 <receiver>MainWindow</receiver>
diff --git a/src/citra_qt/ui_settings.cpp b/src/citra_qt/ui_settings.cpp
new file mode 100644
index 000000000..5f2215899
--- /dev/null
+++ b/src/citra_qt/ui_settings.cpp
@@ -0,0 +1,11 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "ui_settings.h"
6
7namespace UISettings {
8
9Values values = {};
10
11}
diff --git a/src/citra_qt/ui_settings.h b/src/citra_qt/ui_settings.h
new file mode 100644
index 000000000..62db4a73e
--- /dev/null
+++ b/src/citra_qt/ui_settings.h
@@ -0,0 +1,47 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <QByteArray>
8#include <QStringList>
9#include <QString>
10
11#include <vector>
12
13namespace UISettings {
14
15using ContextualShortcut = std::pair<QString, int> ;
16using Shortcut = std::pair<QString, ContextualShortcut>;
17
18struct Values {
19 QByteArray geometry;
20 QByteArray state;
21
22 QByteArray renderwindow_geometry;
23
24 QByteArray gamelist_header_state;
25
26 QByteArray microprofile_geometry;
27 bool microprofile_visible;
28
29 bool single_window_mode;
30 bool display_titlebar;
31
32 bool confirm_before_closing;
33 bool first_start;
34
35 QString roms_path;
36 QString symbols_path;
37 QString gamedir;
38 bool gamedir_deepscan;
39 QStringList recent_files;
40
41 // Shortcut name <Shortcut, context>
42 std::vector<Shortcut> shortcuts;
43};
44
45extern Values values;
46
47}