summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-11-28 14:02:29 -0500
committerGravatar Zach Hilman2018-12-03 17:21:25 -0500
commit60e27252a52e9cb4f2d9671036c0bfc811979a15 (patch)
treede45874133b6ff34847cefa833470c30175a2467 /src
parentloader: Add support for reading the name of game's developer (diff)
downloadyuzu-60e27252a52e9cb4f2d9671036c0bfc811979a15.tar.gz
yuzu-60e27252a52e9cb4f2d9671036c0bfc811979a15.tar.xz
yuzu-60e27252a52e9cb4f2d9671036c0bfc811979a15.zip
qt: Add UI to display game properties and disable add-ons
Diffstat (limited to 'src')
-rw-r--r--src/yuzu/CMakeLists.txt3
-rw-r--r--src/yuzu/configuration/configure_per_general.cpp166
-rw-r--r--src/yuzu/configuration/configure_per_general.h56
-rw-r--r--src/yuzu/configuration/configure_per_general.ui276
4 files changed, 501 insertions, 0 deletions
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index cfca8f4a8..3232aa8fb 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -35,6 +35,8 @@ add_executable(yuzu
35 configuration/configure_mouse_advanced.h 35 configuration/configure_mouse_advanced.h
36 configuration/configure_system.cpp 36 configuration/configure_system.cpp
37 configuration/configure_system.h 37 configuration/configure_system.h
38 configuration/configure_per_general.cpp
39 configuration/configure_per_general.h
38 configuration/configure_touchscreen_advanced.cpp 40 configuration/configure_touchscreen_advanced.cpp
39 configuration/configure_touchscreen_advanced.h 41 configuration/configure_touchscreen_advanced.h
40 configuration/configure_web.cpp 42 configuration/configure_web.cpp
@@ -86,6 +88,7 @@ set(UIS
86 configuration/configure_input.ui 88 configuration/configure_input.ui
87 configuration/configure_input_player.ui 89 configuration/configure_input_player.ui
88 configuration/configure_mouse_advanced.ui 90 configuration/configure_mouse_advanced.ui
91 configuration/configure_per_general.ui
89 configuration/configure_system.ui 92 configuration/configure_system.ui
90 configuration/configure_touchscreen_advanced.ui 93 configuration/configure_touchscreen_advanced.ui
91 configuration/configure_web.ui 94 configuration/configure_web.ui
diff --git a/src/yuzu/configuration/configure_per_general.cpp b/src/yuzu/configuration/configure_per_general.cpp
new file mode 100644
index 000000000..ed85f84a9
--- /dev/null
+++ b/src/yuzu/configuration/configure_per_general.cpp
@@ -0,0 +1,166 @@
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 <algorithm>
6#include <memory>
7#include <utility>
8#include <QMenu>
9#include <QMessageBox>
10#include <QStandardItemModel>
11#include <QString>
12#include <QTimer>
13#include <QTreeView>
14#include "common/param_package.h"
15#include "core/file_sys/control_metadata.h"
16#include "core/file_sys/patch_manager.h"
17#include "core/file_sys/xts_archive.h"
18#include "core/loader/loader.h"
19#include "input_common/main.h"
20#include "yuzu/configuration/config.h"
21#include "yuzu/configuration/configure_input.h"
22#include "yuzu/configuration/configure_per_general.h"
23#include "yuzu/ui_settings.h"
24
25ConfigurePerGameGeneral::ConfigurePerGameGeneral(u64 title_id, QWidget* parent)
26 : QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGameGeneral>()), title_id(title_id) {
27
28 ui->setupUi(this);
29 setFocusPolicy(Qt::ClickFocus);
30 setWindowTitle(tr("Properties"));
31
32 layout = new QVBoxLayout;
33 tree_view = new QTreeView;
34 item_model = new QStandardItemModel(tree_view);
35 tree_view->setModel(item_model);
36 tree_view->setAlternatingRowColors(true);
37 tree_view->setSelectionMode(QHeaderView::SingleSelection);
38 tree_view->setSelectionBehavior(QHeaderView::SelectRows);
39 tree_view->setVerticalScrollMode(QHeaderView::ScrollPerPixel);
40 tree_view->setHorizontalScrollMode(QHeaderView::ScrollPerPixel);
41 tree_view->setSortingEnabled(true);
42 tree_view->setEditTriggers(QHeaderView::NoEditTriggers);
43 tree_view->setUniformRowHeights(true);
44 tree_view->setContextMenuPolicy(Qt::NoContextMenu);
45
46 item_model->insertColumns(0, 2);
47 item_model->setHeaderData(0, Qt::Horizontal, "Patch Name");
48 item_model->setHeaderData(1, Qt::Horizontal, "Version");
49
50 // We must register all custom types with the Qt Automoc system so that we are able to use it
51 // with signals/slots. In this case, QList falls under the umbrells of custom types.
52 qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>");
53
54 layout->setContentsMargins(0, 0, 0, 0);
55 layout->setSpacing(0);
56 layout->addWidget(tree_view);
57
58 ui->scrollArea->setLayout(layout);
59
60 scene = new QGraphicsScene;
61 ui->icon_view->setScene(scene);
62
63 connect(item_model, &QStandardItemModel::itemChanged,
64 [&]() { UISettings::values.is_game_list_reload_pending.exchange(true); });
65
66 this->loadConfiguration();
67}
68
69void ConfigurePerGameGeneral::applyConfiguration() {
70 std::vector<std::string> disabled_addons;
71
72 for (const auto& item : list_items) {
73 const auto disabled = item.front()->checkState() == Qt::Unchecked;
74 if (disabled)
75 disabled_addons.push_back(item.front()->text().toStdString());
76 }
77
78 Settings::values.disabled_addons[title_id] = disabled_addons;
79}
80
81void ConfigurePerGameGeneral::loadFromFile(FileSys::VirtualFile file) {
82 this->file = std::move(file);
83 this->loadConfiguration();
84}
85
86void ConfigurePerGameGeneral::loadConfiguration() {
87 if (file == nullptr)
88 return;
89
90 const auto loader = Loader::GetLoader(file);
91
92 ui->display_title_id->setText(fmt::format("{:016X}", title_id).c_str());
93
94 FileSys::PatchManager pm{title_id};
95 const auto control = pm.GetControlMetadata();
96
97 if (control.first != nullptr) {
98 ui->display_version->setText(QString::fromStdString(control.first->GetVersionString()));
99 ui->display_name->setText(QString::fromStdString(control.first->GetApplicationName()));
100 ui->display_developer->setText(QString::fromStdString(control.first->GetDeveloperName()));
101 } else {
102 std::string title;
103 if (loader->ReadTitle(title) == Loader::ResultStatus::Success)
104 ui->display_name->setText(QString::fromStdString(title));
105
106 std::string developer;
107 if (loader->ReadDeveloper(developer) == Loader::ResultStatus::Success)
108 ui->display_developer->setText(QString::fromStdString(developer));
109
110 ui->display_version->setText("1.0.0");
111 }
112
113 if (control.second != nullptr) {
114 scene->clear();
115
116 QPixmap map;
117 const auto bytes = control.second->ReadAllBytes();
118 map.loadFromData(bytes.data(), bytes.size());
119
120 scene->addPixmap(map.scaled(ui->icon_view->width(), ui->icon_view->height(),
121 Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
122 } else {
123 std::vector<u8> bytes;
124 if (loader->ReadIcon(bytes) == Loader::ResultStatus::Success) {
125 scene->clear();
126
127 QPixmap map;
128 map.loadFromData(bytes.data(), bytes.size());
129
130 scene->addPixmap(map.scaled(ui->icon_view->width(), ui->icon_view->height(),
131 Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
132 }
133 }
134
135 FileSys::VirtualFile update_raw;
136 loader->ReadUpdateRaw(update_raw);
137
138 const auto& disabled = Settings::values.disabled_addons[title_id];
139
140 for (const auto& patch : pm.GetPatchVersionNames(update_raw)) {
141 QStandardItem* first_item = new QStandardItem;
142 const auto name = QString::fromStdString(patch.first).replace("[D] ", "");
143 first_item->setText(name);
144 first_item->setCheckable(true);
145
146 const auto patch_disabled =
147 std::find(disabled.begin(), disabled.end(), name.toStdString()) != disabled.end();
148
149 first_item->setCheckState(patch_disabled ? Qt::Unchecked : Qt::Checked);
150
151 list_items.push_back(QList<QStandardItem*>{
152 first_item, new QStandardItem{QString::fromStdString(patch.second)}});
153 item_model->appendRow(list_items.back());
154 }
155
156 tree_view->setColumnWidth(0, 5 * tree_view->width() / 16);
157
158 ui->display_filename->setText(QString::fromStdString(file->GetName()));
159
160 ui->display_format->setText(
161 QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())));
162
163 QLocale locale = this->locale();
164 QString valueText = locale.formattedDataSize(file->GetSize());
165 ui->display_size->setText(valueText);
166}
diff --git a/src/yuzu/configuration/configure_per_general.h b/src/yuzu/configuration/configure_per_general.h
new file mode 100644
index 000000000..5f958bbba
--- /dev/null
+++ b/src/yuzu/configuration/configure_per_general.h
@@ -0,0 +1,56 @@
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 <array>
8#include <functional>
9#include <memory>
10#include <string>
11#include <unordered_map>
12#include <QKeyEvent>
13#include <QList>
14#include <QWidget>
15#include <boost/optional.hpp>
16#include "common/param_package.h"
17#include "core/file_sys/vfs.h"
18#include "core/settings.h"
19#include "input_common/main.h"
20#include "ui_configure_per_general.h"
21#include "yuzu/configuration/config.h"
22
23class QTreeView;
24class QGraphicsScene;
25class QStandardItem;
26class QStandardItemModel;
27
28namespace Ui {
29class ConfigurePerGameGeneral;
30}
31
32class ConfigurePerGameGeneral : public QDialog {
33 Q_OBJECT
34
35public:
36 explicit ConfigurePerGameGeneral(u64 title_id, QWidget* parent = nullptr);
37
38 /// Save all button configurations to settings file
39 void applyConfiguration();
40
41 void loadFromFile(FileSys::VirtualFile file);
42
43private:
44 std::unique_ptr<Ui::ConfigurePerGameGeneral> ui;
45 FileSys::VirtualFile file;
46 u64 title_id;
47
48 QVBoxLayout* layout;
49 QTreeView* tree_view;
50 QStandardItemModel* item_model;
51 QGraphicsScene* scene;
52
53 std::vector<QList<QStandardItem*>> list_items;
54
55 void loadConfiguration();
56};
diff --git a/src/yuzu/configuration/configure_per_general.ui b/src/yuzu/configuration/configure_per_general.ui
new file mode 100644
index 000000000..8fdd96fa4
--- /dev/null
+++ b/src/yuzu/configuration/configure_per_general.ui
@@ -0,0 +1,276 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>ConfigurePerGameGeneral</class>
4 <widget class="QDialog" name="ConfigurePerGameGeneral">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>400</width>
10 <height>520</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>ConfigurePerGameGeneral</string>
15 </property>
16 <layout class="QHBoxLayout" name="HorizontalLayout">
17 <item>
18 <layout class="QVBoxLayout" name="VerticalLayout">
19 <item>
20 <widget class="QGroupBox" name="GeneralGroupBox">
21 <property name="title">
22 <string>Info</string>
23 </property>
24 <layout class="QHBoxLayout" name="GeneralHorizontalLayout">
25 <item>
26 <layout class="QGridLayout" name="gridLayout_2">
27 <item row="6" column="1" colspan="2">
28 <widget class="QLineEdit" name="display_filename">
29 <property name="enabled">
30 <bool>true</bool>
31 </property>
32 <property name="readOnly">
33 <bool>true</bool>
34 </property>
35 </widget>
36 </item>
37 <item row="0" column="1">
38 <widget class="QLineEdit" name="display_name">
39 <property name="enabled">
40 <bool>true</bool>
41 </property>
42 <property name="readOnly">
43 <bool>true</bool>
44 </property>
45 </widget>
46 </item>
47 <item row="1" column="0">
48 <widget class="QLabel" name="label_2">
49 <property name="text">
50 <string>Developer</string>
51 </property>
52 </widget>
53 </item>
54 <item row="5" column="1" colspan="2">
55 <widget class="QLineEdit" name="display_size">
56 <property name="enabled">
57 <bool>true</bool>
58 </property>
59 <property name="readOnly">
60 <bool>true</bool>
61 </property>
62 </widget>
63 </item>
64 <item row="0" column="0">
65 <widget class="QLabel" name="label">
66 <property name="text">
67 <string>Name</string>
68 </property>
69 </widget>
70 </item>
71 <item row="6" column="0">
72 <widget class="QLabel" name="label_7">
73 <property name="text">
74 <string>Filename</string>
75 </property>
76 </widget>
77 </item>
78 <item row="2" column="0">
79 <widget class="QLabel" name="label_3">
80 <property name="text">
81 <string>Version</string>
82 </property>
83 </widget>
84 </item>
85 <item row="4" column="0">
86 <widget class="QLabel" name="label_5">
87 <property name="text">
88 <string>Format</string>
89 </property>
90 </widget>
91 </item>
92 <item row="2" column="1">
93 <widget class="QLineEdit" name="display_version">
94 <property name="enabled">
95 <bool>true</bool>
96 </property>
97 <property name="readOnly">
98 <bool>true</bool>
99 </property>
100 </widget>
101 </item>
102 <item row="4" column="1">
103 <widget class="QLineEdit" name="display_format">
104 <property name="enabled">
105 <bool>true</bool>
106 </property>
107 <property name="readOnly">
108 <bool>true</bool>
109 </property>
110 </widget>
111 </item>
112 <item row="5" column="0">
113 <widget class="QLabel" name="label_6">
114 <property name="text">
115 <string>Size</string>
116 </property>
117 </widget>
118 </item>
119 <item row="1" column="1">
120 <widget class="QLineEdit" name="display_developer">
121 <property name="enabled">
122 <bool>true</bool>
123 </property>
124 <property name="readOnly">
125 <bool>true</bool>
126 </property>
127 </widget>
128 </item>
129 <item row="3" column="0">
130 <widget class="QLabel" name="label_4">
131 <property name="text">
132 <string>Title ID</string>
133 </property>
134 </widget>
135 </item>
136 <item row="3" column="1">
137 <widget class="QLineEdit" name="display_title_id">
138 <property name="enabled">
139 <bool>true</bool>
140 </property>
141 <property name="readOnly">
142 <bool>true</bool>
143 </property>
144 </widget>
145 </item>
146 <item row="0" column="2" rowspan="5">
147 <widget class="QGraphicsView" name="icon_view">
148 <property name="sizePolicy">
149 <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
150 <horstretch>0</horstretch>
151 <verstretch>0</verstretch>
152 </sizepolicy>
153 </property>
154 <property name="minimumSize">
155 <size>
156 <width>128</width>
157 <height>128</height>
158 </size>
159 </property>
160 <property name="maximumSize">
161 <size>
162 <width>128</width>
163 <height>128</height>
164 </size>
165 </property>
166 <property name="verticalScrollBarPolicy">
167 <enum>Qt::ScrollBarAlwaysOff</enum>
168 </property>
169 <property name="horizontalScrollBarPolicy">
170 <enum>Qt::ScrollBarAlwaysOff</enum>
171 </property>
172 <property name="sizeAdjustPolicy">
173 <enum>QAbstractScrollArea::AdjustToContents</enum>
174 </property>
175 <property name="interactive">
176 <bool>false</bool>
177 </property>
178 </widget>
179 </item>
180 </layout>
181 </item>
182 </layout>
183 </widget>
184 </item>
185 <item>
186 <widget class="QGroupBox" name="PerformanceGroupBox">
187 <property name="title">
188 <string>Add-Ons</string>
189 </property>
190 <layout class="QHBoxLayout" name="PerformanceHorizontalLayout">
191 <item>
192 <widget class="QScrollArea" name="scrollArea">
193 <property name="widgetResizable">
194 <bool>true</bool>
195 </property>
196 <widget class="QWidget" name="scrollAreaWidgetContents">
197 <property name="geometry">
198 <rect>
199 <x>0</x>
200 <y>0</y>
201 <width>350</width>
202 <height>169</height>
203 </rect>
204 </property>
205 </widget>
206 </widget>
207 </item>
208 <item>
209 <layout class="QVBoxLayout" name="PerformanceVerticalLayout"/>
210 </item>
211 </layout>
212 </widget>
213 </item>
214 <item>
215 <spacer name="verticalSpacer">
216 <property name="orientation">
217 <enum>Qt::Vertical</enum>
218 </property>
219 <property name="sizeType">
220 <enum>QSizePolicy::Fixed</enum>
221 </property>
222 <property name="sizeHint" stdset="0">
223 <size>
224 <width>20</width>
225 <height>40</height>
226 </size>
227 </property>
228 </spacer>
229 </item>
230 <item>
231 <widget class="QDialogButtonBox" name="buttonBox">
232 <property name="standardButtons">
233 <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
234 </property>
235 </widget>
236 </item>
237 </layout>
238 </item>
239 </layout>
240 </widget>
241 <resources/>
242 <connections>
243 <connection>
244 <sender>buttonBox</sender>
245 <signal>accepted()</signal>
246 <receiver>ConfigurePerGameGeneral</receiver>
247 <slot>accept()</slot>
248 <hints>
249 <hint type="sourcelabel">
250 <x>269</x>
251 <y>567</y>
252 </hint>
253 <hint type="destinationlabel">
254 <x>269</x>
255 <y>294</y>
256 </hint>
257 </hints>
258 </connection>
259 <connection>
260 <sender>buttonBox</sender>
261 <signal>rejected()</signal>
262 <receiver>ConfigurePerGameGeneral</receiver>
263 <slot>reject()</slot>
264 <hints>
265 <hint type="sourcelabel">
266 <x>269</x>
267 <y>567</y>
268 </hint>
269 <hint type="destinationlabel">
270 <x>269</x>
271 <y>294</y>
272 </hint>
273 </hints>
274 </connection>
275 </connections>
276</ui>