mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Merge pull request #4259 from zhaowenlan1779/game-list
citra_qt: Add Game List configuration
This commit is contained in:
		
						commit
						9458ae0977
					
				
					 15 changed files with 427 additions and 121 deletions
				
			
		|  | @ -43,6 +43,8 @@ add_executable(citra-qt | |||
|     configuration/configure_motion_touch.h | ||||
|     configuration/configure_system.cpp | ||||
|     configuration/configure_system.h | ||||
|     configuration/configure_ui.cpp | ||||
|     configuration/configure_ui.h | ||||
|     configuration/configure_web.cpp | ||||
|     configuration/configure_web.h | ||||
|     debugger/console.h | ||||
|  | @ -119,6 +121,7 @@ set(UIS | |||
|     configuration/configure_input.ui | ||||
|     configuration/configure_motion_touch.ui | ||||
|     configuration/configure_system.ui | ||||
|     configuration/configure_ui.ui | ||||
|     configuration/configure_web.ui | ||||
|     debugger/registers.ui | ||||
|     multiplayer/direct_connect.ui | ||||
|  |  | |||
|  | @ -219,6 +219,28 @@ void Config::ReadValues() { | |||
|         ReadSetting("microProfileDialogVisible", false).toBool(); | ||||
|     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"); | ||||
|     UISettings::values.roms_path = ReadSetting("romsPath").toString(); | ||||
|     UISettings::values.symbols_path = ReadSetting("symbolsPath").toString(); | ||||
|  | @ -448,6 +470,13 @@ void Config::SaveValues() { | |||
|     WriteSetting("microProfileDialogVisible", UISettings::values.microprofile_visible, false); | ||||
|     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"); | ||||
|     WriteSetting("romsPath", UISettings::values.roms_path); | ||||
|     WriteSetting("symbolsPath", UISettings::values.symbols_path); | ||||
|  |  | |||
|  | @ -63,6 +63,11 @@ | |||
|          <string>Web</string> | ||||
|         </attribute> | ||||
|        </widget> | ||||
|        <widget class="ConfigureUi" name="uiTab"> | ||||
|         <attribute name="title"> | ||||
|          <string>UI</string> | ||||
|         </attribute> | ||||
|        </widget> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|  | @ -125,6 +130,12 @@ | |||
|    <header>configuration/configure_web.h</header> | ||||
|    <container>1</container> | ||||
|   </customwidget> | ||||
|   <customwidget> | ||||
|    <class>ConfigureUi</class> | ||||
|    <extends>QWidget</extends> | ||||
|    <header>configuration/configure_ui.h</header> | ||||
|    <container>1</container> | ||||
|   </customwidget> | ||||
|  </customwidgets> | ||||
|  <resources/> | ||||
|  <connections> | ||||
|  |  | |||
|  | @ -16,8 +16,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry | |||
|     ui->generalTab->PopulateHotkeyList(registry); | ||||
|     this->setConfiguration(); | ||||
|     this->PopulateSelectionList(); | ||||
|     connect(ui->generalTab, &ConfigureGeneral::languageChanged, this, | ||||
|             &ConfigureDialog::onLanguageChanged); | ||||
|     connect(ui->uiTab, &ConfigureUi::languageChanged, this, &ConfigureDialog::onLanguageChanged); | ||||
|     connect(ui->selectorList, &QListWidget::itemSelectionChanged, this, | ||||
|             &ConfigureDialog::UpdateVisibleTabs); | ||||
| 
 | ||||
|  | @ -39,6 +38,7 @@ void ConfigureDialog::applyConfiguration() { | |||
|     ui->cameraTab->applyConfiguration(); | ||||
|     ui->debugTab->applyConfiguration(); | ||||
|     ui->webTab->applyConfiguration(); | ||||
|     ui->uiTab->applyConfiguration(); | ||||
|     Settings::Apply(); | ||||
|     Settings::LogSettings(); | ||||
| } | ||||
|  | @ -46,7 +46,7 @@ void ConfigureDialog::applyConfiguration() { | |||
| void ConfigureDialog::PopulateSelectionList() { | ||||
| 
 | ||||
|     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("Graphics"), {tr("Graphics")}}, | ||||
|          {tr("Controls"), {tr("Input")}}}}; | ||||
|  | @ -70,6 +70,7 @@ void ConfigureDialog::onLanguageChanged(const QString& locale) { | |||
|     ui->cameraTab->retranslateUi(); | ||||
|     ui->debugTab->retranslateUi(); | ||||
|     ui->webTab->retranslateUi(); | ||||
|     ui->uiTab->retranslateUi(); | ||||
| } | ||||
| 
 | ||||
| void ConfigureDialog::UpdateVisibleTabs() { | ||||
|  | @ -77,11 +78,15 @@ void ConfigureDialog::UpdateVisibleTabs() { | |||
|     if (items.isEmpty()) | ||||
|         return; | ||||
| 
 | ||||
|     const QHash<QString, QWidget*> widgets = { | ||||
|         {tr("General"), ui->generalTab}, {tr("System"), ui->systemTab}, | ||||
|         {tr("Input"), ui->inputTab},     {tr("Graphics"), ui->graphicsTab}, | ||||
|         {tr("Audio"), ui->audioTab},     {tr("Camera"), ui->cameraTab}, | ||||
|         {tr("Debug"), ui->debugTab},     {tr("Web"), ui->webTab}}; | ||||
|     const QHash<QString, QWidget*> widgets = {{tr("General"), ui->generalTab}, | ||||
|                                               {tr("System"), ui->systemTab}, | ||||
|                                               {tr("Input"), ui->inputTab}, | ||||
|                                               {tr("Graphics"), ui->graphicsTab}, | ||||
|                                               {tr("Audio"), ui->audioTab}, | ||||
|                                               {tr("Camera"), ui->cameraTab}, | ||||
|                                               {tr("Debug"), ui->debugTab}, | ||||
|                                               {tr("Web"), ui->webTab}, | ||||
|                                               {tr("UI"), ui->uiTab}}; | ||||
| 
 | ||||
|     ui->tabWidget->clear(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ | |||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <QDirIterator> | ||||
| #include "citra_qt/configuration/configure_general.h" | ||||
| #include "citra_qt/ui_settings.h" | ||||
| #include "core/core.h" | ||||
|  | @ -13,28 +12,6 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent) | |||
|     : QWidget(parent), ui(new Ui::ConfigureGeneral) { | ||||
| 
 | ||||
|     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(); | ||||
| 
 | ||||
|     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
 | ||||
|     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) { | ||||
|  | @ -62,8 +35,6 @@ void ConfigureGeneral::PopulateHotkeyList(const HotkeyRegistry& registry) { | |||
| 
 | ||||
| void ConfigureGeneral::applyConfiguration() { | ||||
|     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.update_on_close = ui->toggle_auto_update->isChecked(); | ||||
|  | @ -71,13 +42,6 @@ void ConfigureGeneral::applyConfiguration() { | |||
|     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() { | ||||
|     ui->retranslateUi(this); | ||||
|     ui->hotkeysDialog->retranslateUi(); | ||||
|  |  | |||
|  | @ -24,12 +24,6 @@ public: | |||
|     void applyConfiguration(); | ||||
|     void retranslateUi(); | ||||
| 
 | ||||
| private slots: | ||||
|     void onLanguageChanged(int index); | ||||
| 
 | ||||
| signals: | ||||
|     void languageChanged(const QString& locale); | ||||
| 
 | ||||
| private: | ||||
|     void setConfiguration(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -31,20 +31,6 @@ | |||
|             </property> | ||||
|            </widget> | ||||
|           </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> | ||||
|         </item> | ||||
|        </layout> | ||||
|  | @ -145,33 +131,6 @@ | |||
|        </layout> | ||||
|       </widget> | ||||
|      </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> | ||||
|       <widget class="QGroupBox" name="groupBox_3"> | ||||
|        <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; | ||||
|             }(); | ||||
| 
 | ||||
|             if (!Loader::IsValidSMDH(smdh) && UISettings::values.game_list_hide_no_icon) { | ||||
|                 // Skip this invalid entry
 | ||||
|                 return true; | ||||
|             } | ||||
| 
 | ||||
|             auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); | ||||
| 
 | ||||
|             // The game list uses this as compatibility number for untested games
 | ||||
|  |  | |||
|  | @ -62,6 +62,8 @@ public: | |||
| 
 | ||||
|     QString FindGameByProgramID(u64 program_id); | ||||
| 
 | ||||
|     void RefreshGameDirectory(); | ||||
| 
 | ||||
|     static const QStringList supported_file_extensions; | ||||
| 
 | ||||
| signals: | ||||
|  | @ -87,8 +89,6 @@ private: | |||
|     void ValidateEntry(const QModelIndex& item); | ||||
|     void DonePopulating(QStringList watch_list); | ||||
| 
 | ||||
|     void RefreshGameDirectory(); | ||||
| 
 | ||||
|     void PopupContextMenu(const QPoint& menu_location); | ||||
|     void AddGamePopup(QMenu& context_menu, const QString& path, u64 program_id, u64 extdata_id); | ||||
|     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. | ||||
|  * 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(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)) { | ||||
|             // 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; | ||||
|         } | ||||
| 
 | ||||
|  | @ -155,7 +171,8 @@ public: | |||
|         memcpy(&smdh, smdh_data.data(), sizeof(Loader::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
 | ||||
|         setData(GetQStringShortTitleFromSMDH(smdh, Loader::SMDH::TitleLanguage::English), | ||||
|  | @ -171,29 +188,23 @@ public: | |||
|             std::string path, filename, extension; | ||||
|             Common::SplitPath(data(FullPathRole).toString().toStdString(), &path, &filename, | ||||
|                               &extension); | ||||
|             QString title = data(TitleRole).toString(); | ||||
|             QString second_name = QString::fromStdString(filename + extension); | ||||
|             static QRegExp installed_pattern( | ||||
|                 QString::fromStdString( | ||||
|                     FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) + | ||||
|                     "Nintendo " | ||||
|                     "3DS/00000000000000000000000000000000/00000000000000000000000000000000/" | ||||
|                     "title/0004000(0|e)/[0-9a-f]{8}/content/") | ||||
|                     .replace("\\", "\\\\")); | ||||
|             static QRegExp system_pattern( | ||||
|                 QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) + | ||||
|                                        "00000000000000000000000000000000/" | ||||
|                                        "title/00040010/[0-9a-f]{8}/content/") | ||||
|                     .replace("\\", "\\\\")); | ||||
|             if (installed_pattern.exactMatch(QString::fromStdString(path)) || | ||||
|                 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)); | ||||
| 
 | ||||
|             const std::unordered_map<UISettings::GameListText, QString> display_texts{ | ||||
|                 {UISettings::GameListText::FileName, QString::fromStdString(filename + extension)}, | ||||
|                 {UISettings::GameListText::FullPath, data(FullPathRole).toString()}, | ||||
|                 {UISettings::GameListText::TitleName, data(TitleRole).toString()}, | ||||
|                 {UISettings::GameListText::TitleID, | ||||
|                  QString::fromStdString(fmt::format("{:016X}", data(ProgramIdRole).toULongLong()))}, | ||||
|             }; | ||||
| 
 | ||||
|             const QString& row1 = display_texts.at(UISettings::values.game_list_row_1); | ||||
| 
 | ||||
|             QString row2; | ||||
|             auto row_2_id = UISettings::values.game_list_row_2; | ||||
|             if (row_2_id != UISettings::GameListText::NoText) { | ||||
|                 row2 = (row1.isEmpty() ? "" : "\n     ") + display_texts.at(row_2_id); | ||||
|             } | ||||
|             return title + (title.isEmpty() ? "" : "\n     ") + second_name; | ||||
|             return row1 + row2; | ||||
|         } else { | ||||
|             return GameListItem::data(role); | ||||
|         } | ||||
|  | @ -320,18 +331,20 @@ public: | |||
| 
 | ||||
|         UISettings::GameDir* game_dir = &directory; | ||||
|         setData(QVariant::fromValue(game_dir), GameDirRole); | ||||
| 
 | ||||
|         int icon_size = IconSizes.at(UISettings::values.game_list_icon_size); | ||||
|         switch (dir_type) { | ||||
|         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); | ||||
|             break; | ||||
|         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); | ||||
|             break; | ||||
|         case GameListItemType::CustomDir: | ||||
|             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); | ||||
|             break; | ||||
|         }; | ||||
|  | @ -349,7 +362,9 @@ class GameListAddDir : public GameListItem { | |||
| public: | ||||
|     explicit GameListAddDir() { | ||||
|         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); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1286,6 +1286,7 @@ void GMainWindow::OnConfigure() { | |||
|             SetDiscordEnabled(UISettings::values.enable_discord_presence); | ||||
|         emit UpdateThemedIcons(); | ||||
|         SyncMenuUISettings(); | ||||
|         game_list->RefreshGameDirectory(); | ||||
|         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 { | ||||
|     QByteArray geometry; | ||||
|     QByteArray state; | ||||
|  | @ -58,6 +72,12 @@ struct Values { | |||
|     // Discord RPC
 | ||||
|     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 symbols_path; | ||||
|     QString movie_record_path; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue