mirror of
https://github.com/citra-emu/citra-nightly.git
synced 2024-12-27 10:35:40 +00:00
Merge pull request #4259 from zhaowenlan1779/game-list
citra_qt: Add Game List configuration
This commit is contained in:
commit
9458ae0977
|
@ -43,6 +43,8 @@ add_executable(citra-qt
|
||||||
configuration/configure_motion_touch.h
|
configuration/configure_motion_touch.h
|
||||||
configuration/configure_system.cpp
|
configuration/configure_system.cpp
|
||||||
configuration/configure_system.h
|
configuration/configure_system.h
|
||||||
|
configuration/configure_ui.cpp
|
||||||
|
configuration/configure_ui.h
|
||||||
configuration/configure_web.cpp
|
configuration/configure_web.cpp
|
||||||
configuration/configure_web.h
|
configuration/configure_web.h
|
||||||
debugger/console.h
|
debugger/console.h
|
||||||
|
@ -119,6 +121,7 @@ set(UIS
|
||||||
configuration/configure_input.ui
|
configuration/configure_input.ui
|
||||||
configuration/configure_motion_touch.ui
|
configuration/configure_motion_touch.ui
|
||||||
configuration/configure_system.ui
|
configuration/configure_system.ui
|
||||||
|
configuration/configure_ui.ui
|
||||||
configuration/configure_web.ui
|
configuration/configure_web.ui
|
||||||
debugger/registers.ui
|
debugger/registers.ui
|
||||||
multiplayer/direct_connect.ui
|
multiplayer/direct_connect.ui
|
||||||
|
|
|
@ -219,6 +219,28 @@ void Config::ReadValues() {
|
||||||
ReadSetting("microProfileDialogVisible", false).toBool();
|
ReadSetting("microProfileDialogVisible", false).toBool();
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
|
|
||||||
|
qt_config->beginGroup("GameList");
|
||||||
|
int icon_size = ReadSetting("iconSize", 2).toInt();
|
||||||
|
if (icon_size < 0 || icon_size > 2) {
|
||||||
|
icon_size = 2;
|
||||||
|
}
|
||||||
|
UISettings::values.game_list_icon_size = UISettings::GameListIconSize{icon_size};
|
||||||
|
|
||||||
|
int row_1 = ReadSetting("row1", 2).toInt();
|
||||||
|
if (row_1 < 0 || row_1 > 3) {
|
||||||
|
row_1 = 2;
|
||||||
|
}
|
||||||
|
UISettings::values.game_list_row_1 = UISettings::GameListText{row_1};
|
||||||
|
|
||||||
|
int row_2 = ReadSetting("row2", 0).toInt();
|
||||||
|
if (row_2 < -1 || row_2 > 3) {
|
||||||
|
row_2 = 0;
|
||||||
|
}
|
||||||
|
UISettings::values.game_list_row_2 = UISettings::GameListText{row_2};
|
||||||
|
|
||||||
|
UISettings::values.game_list_hide_no_icon = ReadSetting("hideNoIcon", false).toBool();
|
||||||
|
qt_config->endGroup();
|
||||||
|
|
||||||
qt_config->beginGroup("Paths");
|
qt_config->beginGroup("Paths");
|
||||||
UISettings::values.roms_path = ReadSetting("romsPath").toString();
|
UISettings::values.roms_path = ReadSetting("romsPath").toString();
|
||||||
UISettings::values.symbols_path = ReadSetting("symbolsPath").toString();
|
UISettings::values.symbols_path = ReadSetting("symbolsPath").toString();
|
||||||
|
@ -448,6 +470,13 @@ void Config::SaveValues() {
|
||||||
WriteSetting("microProfileDialogVisible", UISettings::values.microprofile_visible, false);
|
WriteSetting("microProfileDialogVisible", UISettings::values.microprofile_visible, false);
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
|
|
||||||
|
qt_config->beginGroup("GameList");
|
||||||
|
WriteSetting("iconSize", static_cast<int>(UISettings::values.game_list_icon_size), 2);
|
||||||
|
WriteSetting("row1", static_cast<int>(UISettings::values.game_list_row_1), 2);
|
||||||
|
WriteSetting("row2", static_cast<int>(UISettings::values.game_list_row_2), 0);
|
||||||
|
WriteSetting("hideNoIcon", UISettings::values.game_list_hide_no_icon, false);
|
||||||
|
qt_config->endGroup();
|
||||||
|
|
||||||
qt_config->beginGroup("Paths");
|
qt_config->beginGroup("Paths");
|
||||||
WriteSetting("romsPath", UISettings::values.roms_path);
|
WriteSetting("romsPath", UISettings::values.roms_path);
|
||||||
WriteSetting("symbolsPath", UISettings::values.symbols_path);
|
WriteSetting("symbolsPath", UISettings::values.symbols_path);
|
||||||
|
|
|
@ -63,6 +63,11 @@
|
||||||
<string>Web</string>
|
<string>Web</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="ConfigureUi" name="uiTab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>UI</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -125,6 +130,12 @@
|
||||||
<header>configuration/configure_web.h</header>
|
<header>configuration/configure_web.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>ConfigureUi</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>configuration/configure_ui.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections>
|
||||||
|
|
|
@ -16,8 +16,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry
|
||||||
ui->generalTab->PopulateHotkeyList(registry);
|
ui->generalTab->PopulateHotkeyList(registry);
|
||||||
this->setConfiguration();
|
this->setConfiguration();
|
||||||
this->PopulateSelectionList();
|
this->PopulateSelectionList();
|
||||||
connect(ui->generalTab, &ConfigureGeneral::languageChanged, this,
|
connect(ui->uiTab, &ConfigureUi::languageChanged, this, &ConfigureDialog::onLanguageChanged);
|
||||||
&ConfigureDialog::onLanguageChanged);
|
|
||||||
connect(ui->selectorList, &QListWidget::itemSelectionChanged, this,
|
connect(ui->selectorList, &QListWidget::itemSelectionChanged, this,
|
||||||
&ConfigureDialog::UpdateVisibleTabs);
|
&ConfigureDialog::UpdateVisibleTabs);
|
||||||
|
|
||||||
|
@ -39,6 +38,7 @@ void ConfigureDialog::applyConfiguration() {
|
||||||
ui->cameraTab->applyConfiguration();
|
ui->cameraTab->applyConfiguration();
|
||||||
ui->debugTab->applyConfiguration();
|
ui->debugTab->applyConfiguration();
|
||||||
ui->webTab->applyConfiguration();
|
ui->webTab->applyConfiguration();
|
||||||
|
ui->uiTab->applyConfiguration();
|
||||||
Settings::Apply();
|
Settings::Apply();
|
||||||
Settings::LogSettings();
|
Settings::LogSettings();
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ void ConfigureDialog::applyConfiguration() {
|
||||||
void ConfigureDialog::PopulateSelectionList() {
|
void ConfigureDialog::PopulateSelectionList() {
|
||||||
|
|
||||||
const std::array<std::pair<QString, QStringList>, 4> items{
|
const std::array<std::pair<QString, QStringList>, 4> items{
|
||||||
{{tr("General"), {tr("General"), tr("Web"), tr("Debug")}},
|
{{tr("General"), {tr("General"), tr("Web"), tr("Debug"), tr("UI")}},
|
||||||
{tr("System"), {tr("System"), tr("Audio"), tr("Camera")}},
|
{tr("System"), {tr("System"), tr("Audio"), tr("Camera")}},
|
||||||
{tr("Graphics"), {tr("Graphics")}},
|
{tr("Graphics"), {tr("Graphics")}},
|
||||||
{tr("Controls"), {tr("Input")}}}};
|
{tr("Controls"), {tr("Input")}}}};
|
||||||
|
@ -70,6 +70,7 @@ void ConfigureDialog::onLanguageChanged(const QString& locale) {
|
||||||
ui->cameraTab->retranslateUi();
|
ui->cameraTab->retranslateUi();
|
||||||
ui->debugTab->retranslateUi();
|
ui->debugTab->retranslateUi();
|
||||||
ui->webTab->retranslateUi();
|
ui->webTab->retranslateUi();
|
||||||
|
ui->uiTab->retranslateUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureDialog::UpdateVisibleTabs() {
|
void ConfigureDialog::UpdateVisibleTabs() {
|
||||||
|
@ -77,11 +78,15 @@ void ConfigureDialog::UpdateVisibleTabs() {
|
||||||
if (items.isEmpty())
|
if (items.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const QHash<QString, QWidget*> widgets = {
|
const QHash<QString, QWidget*> widgets = {{tr("General"), ui->generalTab},
|
||||||
{tr("General"), ui->generalTab}, {tr("System"), ui->systemTab},
|
{tr("System"), ui->systemTab},
|
||||||
{tr("Input"), ui->inputTab}, {tr("Graphics"), ui->graphicsTab},
|
{tr("Input"), ui->inputTab},
|
||||||
{tr("Audio"), ui->audioTab}, {tr("Camera"), ui->cameraTab},
|
{tr("Graphics"), ui->graphicsTab},
|
||||||
{tr("Debug"), ui->debugTab}, {tr("Web"), ui->webTab}};
|
{tr("Audio"), ui->audioTab},
|
||||||
|
{tr("Camera"), ui->cameraTab},
|
||||||
|
{tr("Debug"), ui->debugTab},
|
||||||
|
{tr("Web"), ui->webTab},
|
||||||
|
{tr("UI"), ui->uiTab}};
|
||||||
|
|
||||||
ui->tabWidget->clear();
|
ui->tabWidget->clear();
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <QDirIterator>
|
|
||||||
#include "citra_qt/configuration/configure_general.h"
|
#include "citra_qt/configuration/configure_general.h"
|
||||||
#include "citra_qt/ui_settings.h"
|
#include "citra_qt/ui_settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
@ -13,28 +12,6 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
||||||
: QWidget(parent), ui(new Ui::ConfigureGeneral) {
|
: QWidget(parent), ui(new Ui::ConfigureGeneral) {
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->language_combobox->addItem(tr("<System>"), QString(""));
|
|
||||||
ui->language_combobox->addItem(tr("English"), QString("en"));
|
|
||||||
QDirIterator it(":/languages", QDirIterator::NoIteratorFlags);
|
|
||||||
while (it.hasNext()) {
|
|
||||||
QString locale = it.next();
|
|
||||||
locale.truncate(locale.lastIndexOf('.'));
|
|
||||||
locale.remove(0, locale.lastIndexOf('/') + 1);
|
|
||||||
QString lang = QLocale::languageToString(QLocale(locale).language());
|
|
||||||
ui->language_combobox->addItem(lang, locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unlike other configuration changes, interface language changes need to be reflected on the
|
|
||||||
// interface immediately. This is done by passing a signal to the main window, and then
|
|
||||||
// retranslating when passing back.
|
|
||||||
connect(ui->language_combobox,
|
|
||||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
|
||||||
&ConfigureGeneral::onLanguageChanged);
|
|
||||||
|
|
||||||
for (const auto& theme : UISettings::themes) {
|
|
||||||
ui->theme_combobox->addItem(theme.first, theme.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->setConfiguration();
|
this->setConfiguration();
|
||||||
|
|
||||||
ui->updateBox->setVisible(UISettings::values.updater_found);
|
ui->updateBox->setVisible(UISettings::values.updater_found);
|
||||||
|
@ -50,10 +27,6 @@ void ConfigureGeneral::setConfiguration() {
|
||||||
|
|
||||||
// The first item is "auto-select" with actual value -1, so plus one here will do the trick
|
// The first item is "auto-select" with actual value -1, so plus one here will do the trick
|
||||||
ui->region_combobox->setCurrentIndex(Settings::values.region_value + 1);
|
ui->region_combobox->setCurrentIndex(Settings::values.region_value + 1);
|
||||||
|
|
||||||
ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme));
|
|
||||||
ui->language_combobox->setCurrentIndex(
|
|
||||||
ui->language_combobox->findData(UISettings::values.language));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGeneral::PopulateHotkeyList(const HotkeyRegistry& registry) {
|
void ConfigureGeneral::PopulateHotkeyList(const HotkeyRegistry& registry) {
|
||||||
|
@ -62,8 +35,6 @@ void ConfigureGeneral::PopulateHotkeyList(const HotkeyRegistry& registry) {
|
||||||
|
|
||||||
void ConfigureGeneral::applyConfiguration() {
|
void ConfigureGeneral::applyConfiguration() {
|
||||||
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
|
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
|
||||||
UISettings::values.theme =
|
|
||||||
ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString();
|
|
||||||
|
|
||||||
UISettings::values.check_for_update_on_start = ui->toggle_update_check->isChecked();
|
UISettings::values.check_for_update_on_start = ui->toggle_update_check->isChecked();
|
||||||
UISettings::values.update_on_close = ui->toggle_auto_update->isChecked();
|
UISettings::values.update_on_close = ui->toggle_auto_update->isChecked();
|
||||||
|
@ -71,13 +42,6 @@ void ConfigureGeneral::applyConfiguration() {
|
||||||
Settings::values.region_value = ui->region_combobox->currentIndex() - 1;
|
Settings::values.region_value = ui->region_combobox->currentIndex() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGeneral::onLanguageChanged(int index) {
|
|
||||||
if (index == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
emit languageChanged(ui->language_combobox->itemData(index).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureGeneral::retranslateUi() {
|
void ConfigureGeneral::retranslateUi() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
ui->hotkeysDialog->retranslateUi();
|
ui->hotkeysDialog->retranslateUi();
|
||||||
|
|
|
@ -24,12 +24,6 @@ public:
|
||||||
void applyConfiguration();
|
void applyConfiguration();
|
||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onLanguageChanged(int index);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void languageChanged(const QString& locale);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setConfiguration();
|
void setConfiguration();
|
||||||
|
|
||||||
|
|
|
@ -31,20 +31,6 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="language_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Interface language</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="language_combobox"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -145,33 +131,6 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="theme_group_box">
|
|
||||||
<property name="title">
|
|
||||||
<string>Theme</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="theme_qhbox_layout">
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="theme_qvbox_layout">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="theme_qhbox_layout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="theme_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Theme:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="theme_combobox"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_3">
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
|
72
src/citra_qt/configuration/configure_ui.cpp
Normal file
72
src/citra_qt/configuration/configure_ui.cpp
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
// Copyright 2018 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <QDirIterator>
|
||||||
|
#include "citra_qt/configuration/configure_ui.h"
|
||||||
|
#include "citra_qt/ui_settings.h"
|
||||||
|
#include "ui_configure_ui.h"
|
||||||
|
|
||||||
|
ConfigureUi::ConfigureUi(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureUi) {
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->language_combobox->addItem(tr("<System>"), QString(""));
|
||||||
|
ui->language_combobox->addItem(tr("English"), QString("en"));
|
||||||
|
QDirIterator it(":/languages", QDirIterator::NoIteratorFlags);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
QString locale = it.next();
|
||||||
|
locale.truncate(locale.lastIndexOf('.'));
|
||||||
|
locale.remove(0, locale.lastIndexOf('/') + 1);
|
||||||
|
QString lang = QLocale::languageToString(QLocale(locale).language());
|
||||||
|
ui->language_combobox->addItem(lang, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlike other configuration changes, interface language changes need to be reflected on the
|
||||||
|
// interface immediately. This is done by passing a signal to the main window, and then
|
||||||
|
// retranslating when passing back.
|
||||||
|
connect(ui->language_combobox,
|
||||||
|
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||||
|
&ConfigureUi::onLanguageChanged);
|
||||||
|
|
||||||
|
for (const auto& theme : UISettings::themes) {
|
||||||
|
ui->theme_combobox->addItem(theme.first, theme.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->setConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigureUi::~ConfigureUi() = default;
|
||||||
|
|
||||||
|
void ConfigureUi::setConfiguration() {
|
||||||
|
ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme));
|
||||||
|
ui->language_combobox->setCurrentIndex(
|
||||||
|
ui->language_combobox->findData(UISettings::values.language));
|
||||||
|
ui->icon_size_combobox->setCurrentIndex(
|
||||||
|
static_cast<int>(UISettings::values.game_list_icon_size));
|
||||||
|
ui->row_1_text_combobox->setCurrentIndex(static_cast<int>(UISettings::values.game_list_row_1));
|
||||||
|
ui->row_2_text_combobox->setCurrentIndex(static_cast<int>(UISettings::values.game_list_row_2) +
|
||||||
|
1);
|
||||||
|
ui->toggle_hide_no_icon->setChecked(UISettings::values.game_list_hide_no_icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureUi::applyConfiguration() {
|
||||||
|
UISettings::values.theme =
|
||||||
|
ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString();
|
||||||
|
UISettings::values.game_list_icon_size =
|
||||||
|
static_cast<UISettings::GameListIconSize>(ui->icon_size_combobox->currentIndex());
|
||||||
|
UISettings::values.game_list_row_1 =
|
||||||
|
static_cast<UISettings::GameListText>(ui->row_1_text_combobox->currentIndex());
|
||||||
|
UISettings::values.game_list_row_2 =
|
||||||
|
static_cast<UISettings::GameListText>(ui->row_2_text_combobox->currentIndex() - 1);
|
||||||
|
UISettings::values.game_list_hide_no_icon = ui->toggle_hide_no_icon->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureUi::onLanguageChanged(int index) {
|
||||||
|
if (index == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
emit languageChanged(ui->language_combobox->itemData(index).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureUi::retranslateUi() {
|
||||||
|
ui->retranslateUi(this);
|
||||||
|
}
|
34
src/citra_qt/configuration/configure_ui.h
Normal file
34
src/citra_qt/configuration/configure_ui.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright 2018 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ConfigureUi;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigureUi : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ConfigureUi(QWidget* parent = nullptr);
|
||||||
|
~ConfigureUi();
|
||||||
|
|
||||||
|
void applyConfiguration();
|
||||||
|
void retranslateUi();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onLanguageChanged(int index);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void languageChanged(const QString& locale);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setConfiguration();
|
||||||
|
|
||||||
|
std::unique_ptr<Ui::ConfigureUi> ui;
|
||||||
|
};
|
194
src/citra_qt/configuration/configure_ui.ui
Normal file
194
src/citra_qt/configuration/configure_ui.ui
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ConfigureUi</class>
|
||||||
|
<widget class="QWidget" name="ConfigureUi">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>290</width>
|
||||||
|
<height>280</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="general_groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>General</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="language_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Interface language:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="language_combobox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="theme_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Theme:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="theme_combobox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="game_list_groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Game List</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="icon_size_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Icon Size:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="icon_size_combobox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>None</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Small (24x24)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Large (48x48)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="row_1_text_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Row 1 Text:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="row_1_text_combobox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>File Name</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Full Path</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Title Name</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Title ID</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="row_2_text_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Row 2 Text:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="row_2_text_combobox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>None</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>File Name</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Full Path</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Title Name</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Title ID</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="toggle_hide_no_icon">
|
||||||
|
<property name="text">
|
||||||
|
<string>Hide Titles without Icon</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -723,6 +723,11 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
|
||||||
return update_smdh;
|
return update_smdh;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
if (!Loader::IsValidSMDH(smdh) && UISettings::values.game_list_hide_no_icon) {
|
||||||
|
// Skip this invalid entry
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
|
auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
|
||||||
|
|
||||||
// The game list uses this as compatibility number for untested games
|
// The game list uses this as compatibility number for untested games
|
||||||
|
|
|
@ -62,6 +62,8 @@ public:
|
||||||
|
|
||||||
QString FindGameByProgramID(u64 program_id);
|
QString FindGameByProgramID(u64 program_id);
|
||||||
|
|
||||||
|
void RefreshGameDirectory();
|
||||||
|
|
||||||
static const QStringList supported_file_extensions;
|
static const QStringList supported_file_extensions;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -87,8 +89,6 @@ private:
|
||||||
void ValidateEntry(const QModelIndex& item);
|
void ValidateEntry(const QModelIndex& item);
|
||||||
void DonePopulating(QStringList watch_list);
|
void DonePopulating(QStringList watch_list);
|
||||||
|
|
||||||
void RefreshGameDirectory();
|
|
||||||
|
|
||||||
void PopupContextMenu(const QPoint& menu_location);
|
void PopupContextMenu(const QPoint& menu_location);
|
||||||
void AddGamePopup(QMenu& context_menu, const QString& path, u64 program_id, u64 extdata_id);
|
void AddGamePopup(QMenu& context_menu, const QString& path, u64 program_id, u64 extdata_id);
|
||||||
void AddCustomDirPopup(QMenu& context_menu, QModelIndex selected);
|
void AddCustomDirPopup(QMenu& context_menu, QModelIndex selected);
|
||||||
|
|
|
@ -124,6 +124,13 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Game list icon sizes (in px)
|
||||||
|
static const std::unordered_map<UISettings::GameListIconSize, int> IconSizes{
|
||||||
|
{UISettings::GameListIconSize::NoIcon, 0},
|
||||||
|
{UISettings::GameListIconSize::SmallIcon, 24},
|
||||||
|
{UISettings::GameListIconSize::LargeIcon, 48},
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specialization of GameListItem for path values.
|
* A specialization of GameListItem for path values.
|
||||||
* This class ensures that for every full path value it holds, a correct string representation
|
* This class ensures that for every full path value it holds, a correct string representation
|
||||||
|
@ -145,9 +152,18 @@ public:
|
||||||
setData(qulonglong(program_id), ProgramIdRole);
|
setData(qulonglong(program_id), ProgramIdRole);
|
||||||
setData(qulonglong(extdata_id), ExtdataIdRole);
|
setData(qulonglong(extdata_id), ExtdataIdRole);
|
||||||
|
|
||||||
|
if (UISettings::values.game_list_icon_size == UISettings::GameListIconSize::NoIcon) {
|
||||||
|
// Do not display icons
|
||||||
|
setData(QPixmap(), Qt::DecorationRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool large =
|
||||||
|
UISettings::values.game_list_icon_size == UISettings::GameListIconSize::LargeIcon;
|
||||||
|
|
||||||
if (!Loader::IsValidSMDH(smdh_data)) {
|
if (!Loader::IsValidSMDH(smdh_data)) {
|
||||||
// SMDH is not valid, set a default icon
|
// SMDH is not valid, set a default icon
|
||||||
setData(GetDefaultIcon(true), Qt::DecorationRole);
|
if (UISettings::values.game_list_icon_size != UISettings::GameListIconSize::NoIcon)
|
||||||
|
setData(GetDefaultIcon(large), Qt::DecorationRole);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +171,8 @@ public:
|
||||||
memcpy(&smdh, smdh_data.data(), sizeof(Loader::SMDH));
|
memcpy(&smdh, smdh_data.data(), sizeof(Loader::SMDH));
|
||||||
|
|
||||||
// Get icon from SMDH
|
// Get icon from SMDH
|
||||||
setData(GetQPixmapFromSMDH(smdh, true), Qt::DecorationRole);
|
if (UISettings::values.game_list_icon_size != UISettings::GameListIconSize::NoIcon)
|
||||||
|
setData(GetQPixmapFromSMDH(smdh, large), Qt::DecorationRole);
|
||||||
|
|
||||||
// Get title from SMDH
|
// Get title from SMDH
|
||||||
setData(GetQStringShortTitleFromSMDH(smdh, Loader::SMDH::TitleLanguage::English),
|
setData(GetQStringShortTitleFromSMDH(smdh, Loader::SMDH::TitleLanguage::English),
|
||||||
|
@ -171,29 +188,23 @@ public:
|
||||||
std::string path, filename, extension;
|
std::string path, filename, extension;
|
||||||
Common::SplitPath(data(FullPathRole).toString().toStdString(), &path, &filename,
|
Common::SplitPath(data(FullPathRole).toString().toStdString(), &path, &filename,
|
||||||
&extension);
|
&extension);
|
||||||
QString title = data(TitleRole).toString();
|
|
||||||
QString second_name = QString::fromStdString(filename + extension);
|
const std::unordered_map<UISettings::GameListText, QString> display_texts{
|
||||||
static QRegExp installed_pattern(
|
{UISettings::GameListText::FileName, QString::fromStdString(filename + extension)},
|
||||||
QString::fromStdString(
|
{UISettings::GameListText::FullPath, data(FullPathRole).toString()},
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) +
|
{UISettings::GameListText::TitleName, data(TitleRole).toString()},
|
||||||
"Nintendo "
|
{UISettings::GameListText::TitleID,
|
||||||
"3DS/00000000000000000000000000000000/00000000000000000000000000000000/"
|
QString::fromStdString(fmt::format("{:016X}", data(ProgramIdRole).toULongLong()))},
|
||||||
"title/0004000(0|e)/[0-9a-f]{8}/content/")
|
};
|
||||||
.replace("\\", "\\\\"));
|
|
||||||
static QRegExp system_pattern(
|
const QString& row1 = display_texts.at(UISettings::values.game_list_row_1);
|
||||||
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
|
|
||||||
"00000000000000000000000000000000/"
|
QString row2;
|
||||||
"title/00040010/[0-9a-f]{8}/content/")
|
auto row_2_id = UISettings::values.game_list_row_2;
|
||||||
.replace("\\", "\\\\"));
|
if (row_2_id != UISettings::GameListText::NoText) {
|
||||||
if (installed_pattern.exactMatch(QString::fromStdString(path)) ||
|
row2 = (row1.isEmpty() ? "" : "\n ") + display_texts.at(row_2_id);
|
||||||
system_pattern.exactMatch(QString::fromStdString(path))) {
|
|
||||||
// Use a different mechanism for system / installed titles showing program ID
|
|
||||||
second_name = QString("%1-%2")
|
|
||||||
.arg(data(ProgramIdRole).toULongLong(), 16, 16, QChar('0'))
|
|
||||||
.toUpper()
|
|
||||||
.arg(QString::fromStdString(filename));
|
|
||||||
}
|
}
|
||||||
return title + (title.isEmpty() ? "" : "\n ") + second_name;
|
return row1 + row2;
|
||||||
} else {
|
} else {
|
||||||
return GameListItem::data(role);
|
return GameListItem::data(role);
|
||||||
}
|
}
|
||||||
|
@ -320,18 +331,20 @@ public:
|
||||||
|
|
||||||
UISettings::GameDir* game_dir = &directory;
|
UISettings::GameDir* game_dir = &directory;
|
||||||
setData(QVariant::fromValue(game_dir), GameDirRole);
|
setData(QVariant::fromValue(game_dir), GameDirRole);
|
||||||
|
|
||||||
|
int icon_size = IconSizes.at(UISettings::values.game_list_icon_size);
|
||||||
switch (dir_type) {
|
switch (dir_type) {
|
||||||
case GameListItemType::InstalledDir:
|
case GameListItemType::InstalledDir:
|
||||||
setData(QIcon::fromTheme("sd_card").pixmap(48), Qt::DecorationRole);
|
setData(QIcon::fromTheme("sd_card").pixmap(icon_size), Qt::DecorationRole);
|
||||||
setData("Installed Titles", Qt::DisplayRole);
|
setData("Installed Titles", Qt::DisplayRole);
|
||||||
break;
|
break;
|
||||||
case GameListItemType::SystemDir:
|
case GameListItemType::SystemDir:
|
||||||
setData(QIcon::fromTheme("chip").pixmap(48), Qt::DecorationRole);
|
setData(QIcon::fromTheme("chip").pixmap(icon_size), Qt::DecorationRole);
|
||||||
setData("System Titles", Qt::DisplayRole);
|
setData("System Titles", Qt::DisplayRole);
|
||||||
break;
|
break;
|
||||||
case GameListItemType::CustomDir:
|
case GameListItemType::CustomDir:
|
||||||
QString icon_name = QFileInfo::exists(game_dir->path) ? "folder" : "bad_folder";
|
QString icon_name = QFileInfo::exists(game_dir->path) ? "folder" : "bad_folder";
|
||||||
setData(QIcon::fromTheme(icon_name).pixmap(48), Qt::DecorationRole);
|
setData(QIcon::fromTheme(icon_name).pixmap(icon_size), Qt::DecorationRole);
|
||||||
setData(game_dir->path, Qt::DisplayRole);
|
setData(game_dir->path, Qt::DisplayRole);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
@ -349,7 +362,9 @@ class GameListAddDir : public GameListItem {
|
||||||
public:
|
public:
|
||||||
explicit GameListAddDir() {
|
explicit GameListAddDir() {
|
||||||
setData(type(), TypeRole);
|
setData(type(), TypeRole);
|
||||||
setData(QIcon::fromTheme("plus").pixmap(48), Qt::DecorationRole);
|
|
||||||
|
int icon_size = IconSizes.at(UISettings::values.game_list_icon_size);
|
||||||
|
setData(QIcon::fromTheme("plus").pixmap(icon_size), Qt::DecorationRole);
|
||||||
setData("Add New Game Directory", Qt::DisplayRole);
|
setData("Add New Game Directory", Qt::DisplayRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1286,6 +1286,7 @@ void GMainWindow::OnConfigure() {
|
||||||
SetDiscordEnabled(UISettings::values.enable_discord_presence);
|
SetDiscordEnabled(UISettings::values.enable_discord_presence);
|
||||||
emit UpdateThemedIcons();
|
emit UpdateThemedIcons();
|
||||||
SyncMenuUISettings();
|
SyncMenuUISettings();
|
||||||
|
game_list->RefreshGameDirectory();
|
||||||
config->Save();
|
config->Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,20 @@ struct GameDir {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class GameListIconSize {
|
||||||
|
NoIcon, ///< Do not display icons
|
||||||
|
SmallIcon, ///< Display a small (24x24) icon
|
||||||
|
LargeIcon, ///< Display a large (48x48) icon
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class GameListText {
|
||||||
|
NoText = -1, ///< No text
|
||||||
|
FileName, ///< Display the file name of the entry
|
||||||
|
FullPath, ///< Display the full path of the entry
|
||||||
|
TitleName, ///< Display the name of the title
|
||||||
|
TitleID, ///< Display the title ID
|
||||||
|
};
|
||||||
|
|
||||||
struct Values {
|
struct Values {
|
||||||
QByteArray geometry;
|
QByteArray geometry;
|
||||||
QByteArray state;
|
QByteArray state;
|
||||||
|
@ -58,6 +72,12 @@ struct Values {
|
||||||
// Discord RPC
|
// Discord RPC
|
||||||
bool enable_discord_presence;
|
bool enable_discord_presence;
|
||||||
|
|
||||||
|
// Game List
|
||||||
|
GameListIconSize game_list_icon_size;
|
||||||
|
GameListText game_list_row_1;
|
||||||
|
GameListText game_list_row_2;
|
||||||
|
bool game_list_hide_no_icon;
|
||||||
|
|
||||||
QString roms_path;
|
QString roms_path;
|
||||||
QString symbols_path;
|
QString symbols_path;
|
||||||
QString movie_record_path;
|
QString movie_record_path;
|
||||||
|
|
Loading…
Reference in a new issue