mirror of
				https://github.com/dolphin-emu/dolphin.git
				synced 2025-10-25 09:29:43 +00:00 
			
		
		
		
	SPDX standardizes how source code conveys its copyright and licensing information. See https://spdx.github.io/spdx-spec/1-rationale/ . SPDX tags are adopted in many large projects, including things like the Linux kernel.
		
			
				
	
	
		
			302 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			302 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright 2017 Dolphin Emulator Project
 | |
| // SPDX-License-Identifier: GPL-2.0-or-later
 | |
| 
 | |
| #include "DolphinQt/Settings/InterfacePane.h"
 | |
| 
 | |
| #include <QCheckBox>
 | |
| #include <QComboBox>
 | |
| #include <QFileInfo>
 | |
| #include <QFormLayout>
 | |
| #include <QGroupBox>
 | |
| #include <QLabel>
 | |
| #include <QVBoxLayout>
 | |
| #include <QWidget>
 | |
| 
 | |
| #include "Common/CommonPaths.h"
 | |
| #include "Common/FileSearch.h"
 | |
| #include "Common/FileUtil.h"
 | |
| #include "Common/MsgHandler.h"
 | |
| #include "Common/StringUtil.h"
 | |
| 
 | |
| #include "Core/Config/MainSettings.h"
 | |
| #include "Core/Config/UISettings.h"
 | |
| #include "Core/ConfigManager.h"
 | |
| 
 | |
| #include "DolphinQt/QtUtils/ModalMessageBox.h"
 | |
| #include "DolphinQt/Settings.h"
 | |
| 
 | |
| #include "UICommon/GameFile.h"
 | |
| 
 | |
| static QComboBox* MakeLanguageComboBox()
 | |
| {
 | |
|   static const struct
 | |
|   {
 | |
|     const QString name;
 | |
|     const char* id;
 | |
|   } languages[] = {
 | |
|       {QStringLiteral(u"Bahasa Melayu"), "ms"},               // Malay
 | |
|       {QStringLiteral(u"Catal\u00E0"), "ca"},                 // Catalan
 | |
|       {QStringLiteral(u"\u010Ce\u0161tina"), "cs"},           // Czech
 | |
|       {QStringLiteral(u"Dansk"), "da"},                       // Danish
 | |
|       {QStringLiteral(u"Deutsch"), "de"},                     // German
 | |
|       {QStringLiteral(u"English"), "en"},                     // English
 | |
|       {QStringLiteral(u"Espa\u00F1ol"), "es"},                // Spanish
 | |
|       {QStringLiteral(u"Fran\u00E7ais"), "fr"},               // French
 | |
|       {QStringLiteral(u"Hrvatski"), "hr"},                    // Croatian
 | |
|       {QStringLiteral(u"Italiano"), "it"},                    // Italian
 | |
|       {QStringLiteral(u"Magyar"), "hu"},                      // Hungarian
 | |
|       {QStringLiteral(u"Nederlands"), "nl"},                  // Dutch
 | |
|       {QStringLiteral(u"Norsk bokm\u00E5l"), "nb"},           // Norwegian
 | |
|       {QStringLiteral(u"Polski"), "pl"},                      // Polish
 | |
|       {QStringLiteral(u"Portugu\u00EAs"), "pt"},              // Portuguese
 | |
|       {QStringLiteral(u"Portugu\u00EAs (Brasil)"), "pt_BR"},  // Portuguese (Brazil)
 | |
|       {QStringLiteral(u"Rom\u00E2n\u0103"), "ro"},            // Romanian
 | |
|       {QStringLiteral(u"Srpski"), "sr"},                      // Serbian
 | |
|       {QStringLiteral(u"Svenska"), "sv"},                     // Swedish
 | |
|       {QStringLiteral(u"T\u00FCrk\u00E7e"), "tr"},            // Turkish
 | |
|       {QStringLiteral(u"\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC"), "el"},  // Greek
 | |
|       {QStringLiteral(u"\u0420\u0443\u0441\u0441\u043A\u0438\u0439"), "ru"},        // Russian
 | |
|       {QStringLiteral(u"\u0627\u0644\u0639\u0631\u0628\u064A\u0629"), "ar"},        // Arabic
 | |
|       {QStringLiteral(u"\u0641\u0627\u0631\u0633\u06CC"), "fa"},                    // Farsi
 | |
|       {QStringLiteral(u"\uD55C\uAD6D\uC5B4"), "ko"},                                // Korean
 | |
|       {QStringLiteral(u"\u65E5\u672C\u8A9E"), "ja"},                                // Japanese
 | |
|       {QStringLiteral(u"\u7B80\u4F53\u4E2D\u6587"), "zh_CN"},  // Simplified Chinese
 | |
|       {QStringLiteral(u"\u7E41\u9AD4\u4E2D\u6587"), "zh_TW"},  // Traditional Chinese
 | |
|   };
 | |
| 
 | |
|   auto* combobox = new QComboBox();
 | |
|   combobox->addItem(QObject::tr("<System Language>"), QString{});
 | |
|   for (const auto& lang : languages)
 | |
|     combobox->addItem(lang.name, QString::fromLatin1(lang.id));
 | |
| 
 | |
|   // The default, QComboBox::AdjustToContentsOnFirstShow, causes a noticeable pause when opening the
 | |
|   // SettingWindow for the first time. The culprit seems to be non-Latin graphemes in the above
 | |
|   // list. QComboBox::AdjustToContents still has some lag but it's much less noticeable.
 | |
|   combobox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
 | |
| 
 | |
|   return combobox;
 | |
| }
 | |
| 
 | |
| InterfacePane::InterfacePane(QWidget* parent) : QWidget(parent)
 | |
| {
 | |
|   CreateLayout();
 | |
|   LoadConfig();
 | |
|   ConnectLayout();
 | |
| }
 | |
| 
 | |
| void InterfacePane::CreateLayout()
 | |
| {
 | |
|   m_main_layout = new QVBoxLayout;
 | |
|   // Create layout here
 | |
|   CreateUI();
 | |
|   CreateInGame();
 | |
| 
 | |
|   m_main_layout->addStretch(1);
 | |
|   setLayout(m_main_layout);
 | |
| }
 | |
| 
 | |
| void InterfacePane::CreateUI()
 | |
| {
 | |
|   auto* groupbox = new QGroupBox(tr("User Interface"));
 | |
|   auto* groupbox_layout = new QVBoxLayout;
 | |
|   groupbox->setLayout(groupbox_layout);
 | |
|   m_main_layout->addWidget(groupbox);
 | |
| 
 | |
|   auto* combobox_layout = new QFormLayout;
 | |
|   combobox_layout->setFormAlignment(Qt::AlignLeft | Qt::AlignTop);
 | |
|   combobox_layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
 | |
| 
 | |
|   groupbox_layout->addLayout(combobox_layout);
 | |
| 
 | |
|   m_combobox_language = MakeLanguageComboBox();
 | |
|   combobox_layout->addRow(tr("&Language:"), m_combobox_language);
 | |
| 
 | |
|   // Theme Combobox
 | |
|   m_combobox_theme = new QComboBox;
 | |
|   combobox_layout->addRow(tr("&Theme:"), m_combobox_theme);
 | |
| 
 | |
|   // List avalable themes
 | |
|   auto theme_search_results =
 | |
|       Common::DoFileSearch({File::GetUserPath(D_THEMES_IDX), File::GetSysDirectory() + THEMES_DIR});
 | |
|   for (const std::string& path : theme_search_results)
 | |
|   {
 | |
|     const QString qt_name = QString::fromStdString(PathToFileName(path));
 | |
|     m_combobox_theme->addItem(qt_name);
 | |
|   }
 | |
| 
 | |
|   // User Style Combobox
 | |
|   m_combobox_userstyle = new QComboBox;
 | |
|   m_label_userstyle = new QLabel(tr("User Style:"));
 | |
|   combobox_layout->addRow(m_label_userstyle, m_combobox_userstyle);
 | |
| 
 | |
|   auto userstyle_search_results = Common::DoFileSearch({File::GetUserPath(D_STYLES_IDX)});
 | |
| 
 | |
|   m_combobox_userstyle->addItem(tr("(None)"), QString{});
 | |
| 
 | |
|   for (const std::string& path : userstyle_search_results)
 | |
|   {
 | |
|     const QFileInfo file_info(QString::fromStdString(path));
 | |
|     m_combobox_userstyle->addItem(file_info.completeBaseName(), file_info.fileName());
 | |
|   }
 | |
| 
 | |
|   // Checkboxes
 | |
|   m_checkbox_use_builtin_title_database = new QCheckBox(tr("Use Built-In Database of Game Names"));
 | |
|   m_checkbox_use_userstyle = new QCheckBox(tr("Use Custom User Style"));
 | |
|   m_checkbox_use_covers =
 | |
|       new QCheckBox(tr("Download Game Covers from GameTDB.com for Use in Grid Mode"));
 | |
|   m_checkbox_show_debugging_ui = new QCheckBox(tr("Show Debugging UI"));
 | |
|   m_checkbox_focused_hotkeys = new QCheckBox(tr("Hotkeys Require Window Focus"));
 | |
|   m_checkbox_disable_screensaver = new QCheckBox(tr("Inhibit Screensaver During Emulation"));
 | |
| 
 | |
|   groupbox_layout->addWidget(m_checkbox_use_builtin_title_database);
 | |
|   groupbox_layout->addWidget(m_checkbox_use_userstyle);
 | |
|   groupbox_layout->addWidget(m_checkbox_use_covers);
 | |
|   groupbox_layout->addWidget(m_checkbox_show_debugging_ui);
 | |
|   groupbox_layout->addWidget(m_checkbox_focused_hotkeys);
 | |
|   groupbox_layout->addWidget(m_checkbox_disable_screensaver);
 | |
| }
 | |
| 
 | |
| void InterfacePane::CreateInGame()
 | |
| {
 | |
|   auto* groupbox = new QGroupBox(tr("Render Window"));
 | |
|   auto* groupbox_layout = new QVBoxLayout;
 | |
|   groupbox->setLayout(groupbox_layout);
 | |
|   m_main_layout->addWidget(groupbox);
 | |
| 
 | |
|   m_checkbox_top_window = new QCheckBox(tr("Keep Window on Top"));
 | |
|   m_checkbox_confirm_on_stop = new QCheckBox(tr("Confirm on Stop"));
 | |
|   m_checkbox_use_panic_handlers = new QCheckBox(tr("Use Panic Handlers"));
 | |
|   m_checkbox_enable_osd = new QCheckBox(tr("Show On-Screen Display Messages"));
 | |
|   m_checkbox_show_active_title = new QCheckBox(tr("Show Active Title in Window Title"));
 | |
|   m_checkbox_pause_on_focus_lost = new QCheckBox(tr("Pause on Focus Loss"));
 | |
|   m_checkbox_hide_mouse = new QCheckBox(tr("Always Hide Mouse Cursor"));
 | |
|   m_checkbox_lock_mouse = new QCheckBox(tr("Lock Mouse Cursor"));
 | |
| 
 | |
|   m_checkbox_hide_mouse->setToolTip(
 | |
|       tr("Will immediately hide the Mouse Cursor when it hovers on top of the Render Widget, "
 | |
|          "otherwise "
 | |
|          "there is a delay.\nIf \"Lock Mouse Cursor\" is enabled, it will hide on Mouse locked"));
 | |
|   m_checkbox_lock_mouse->setToolTip(tr("Will lock the Mouse Cursor to the Render Widget as long as "
 | |
|                                        "it has focus. You can set a hotkey to unlock it."));
 | |
| 
 | |
|   groupbox_layout->addWidget(m_checkbox_top_window);
 | |
|   groupbox_layout->addWidget(m_checkbox_confirm_on_stop);
 | |
|   groupbox_layout->addWidget(m_checkbox_use_panic_handlers);
 | |
|   groupbox_layout->addWidget(m_checkbox_enable_osd);
 | |
|   groupbox_layout->addWidget(m_checkbox_show_active_title);
 | |
|   groupbox_layout->addWidget(m_checkbox_pause_on_focus_lost);
 | |
|   groupbox_layout->addWidget(m_checkbox_hide_mouse);
 | |
| #ifdef _WIN32
 | |
|   groupbox_layout->addWidget(m_checkbox_lock_mouse);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void InterfacePane::ConnectLayout()
 | |
| {
 | |
|   connect(m_checkbox_use_builtin_title_database, &QCheckBox::toggled, this,
 | |
|           &InterfacePane::OnSaveConfig);
 | |
|   connect(m_checkbox_use_covers, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
 | |
|   connect(m_checkbox_disable_screensaver, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
 | |
|   connect(m_checkbox_show_debugging_ui, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
 | |
|   connect(m_checkbox_focused_hotkeys, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
 | |
|   connect(m_combobox_theme, qOverload<int>(&QComboBox::currentIndexChanged), this,
 | |
|           [=](int index) { Settings::Instance().SetThemeName(m_combobox_theme->itemText(index)); });
 | |
|   connect(m_combobox_userstyle, qOverload<int>(&QComboBox::currentIndexChanged), this,
 | |
|           &InterfacePane::OnSaveConfig);
 | |
|   connect(m_combobox_language, qOverload<int>(&QComboBox::currentIndexChanged), this,
 | |
|           &InterfacePane::OnSaveConfig);
 | |
|   connect(m_checkbox_top_window, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
 | |
|   connect(m_checkbox_confirm_on_stop, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
 | |
|   connect(m_checkbox_use_panic_handlers, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
 | |
|   connect(m_checkbox_show_active_title, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
 | |
|   connect(m_checkbox_enable_osd, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
 | |
|   connect(m_checkbox_pause_on_focus_lost, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
 | |
|   connect(m_checkbox_hide_mouse, &QCheckBox::toggled, &Settings::Instance(),
 | |
|           &Settings::SetHideCursor);
 | |
|   connect(m_checkbox_lock_mouse, &QCheckBox::toggled, &Settings::Instance(),
 | |
|           &Settings::SetLockCursor);
 | |
|   connect(m_checkbox_use_userstyle, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
 | |
| }
 | |
| 
 | |
| void InterfacePane::LoadConfig()
 | |
| {
 | |
|   const SConfig& startup_params = SConfig::GetInstance();
 | |
|   m_checkbox_use_builtin_title_database->setChecked(startup_params.m_use_builtin_title_database);
 | |
|   m_checkbox_show_debugging_ui->setChecked(Settings::Instance().IsDebugModeEnabled());
 | |
|   m_combobox_language->setCurrentIndex(m_combobox_language->findData(
 | |
|       QString::fromStdString(SConfig::GetInstance().m_InterfaceLanguage)));
 | |
|   m_combobox_theme->setCurrentIndex(
 | |
|       m_combobox_theme->findText(QString::fromStdString(SConfig::GetInstance().theme_name)));
 | |
| 
 | |
|   const QString userstyle = Settings::Instance().GetCurrentUserStyle();
 | |
|   const int index = m_combobox_userstyle->findData(QFileInfo(userstyle).fileName());
 | |
| 
 | |
|   if (index > 0)
 | |
|     m_combobox_userstyle->setCurrentIndex(index);
 | |
| 
 | |
|   m_checkbox_use_userstyle->setChecked(Settings::Instance().AreUserStylesEnabled());
 | |
| 
 | |
|   const bool visible = m_checkbox_use_userstyle->isChecked();
 | |
| 
 | |
|   m_combobox_userstyle->setVisible(visible);
 | |
|   m_label_userstyle->setVisible(visible);
 | |
| 
 | |
|   // Render Window Options
 | |
|   m_checkbox_top_window->setChecked(Settings::Instance().IsKeepWindowOnTopEnabled());
 | |
|   m_checkbox_confirm_on_stop->setChecked(startup_params.bConfirmStop);
 | |
|   m_checkbox_use_panic_handlers->setChecked(Config::Get(Config::MAIN_USE_PANIC_HANDLERS));
 | |
|   m_checkbox_enable_osd->setChecked(Config::Get(Config::MAIN_OSD_MESSAGES));
 | |
|   m_checkbox_show_active_title->setChecked(startup_params.m_show_active_title);
 | |
|   m_checkbox_pause_on_focus_lost->setChecked(startup_params.m_PauseOnFocusLost);
 | |
|   m_checkbox_use_covers->setChecked(Config::Get(Config::MAIN_USE_GAME_COVERS));
 | |
|   m_checkbox_focused_hotkeys->setChecked(Config::Get(Config::MAIN_FOCUSED_HOTKEYS));
 | |
|   m_checkbox_hide_mouse->setChecked(Settings::Instance().GetHideCursor());
 | |
|   m_checkbox_lock_mouse->setChecked(Settings::Instance().GetLockCursor());
 | |
|   m_checkbox_disable_screensaver->setChecked(Config::Get(Config::MAIN_DISABLE_SCREENSAVER));
 | |
| }
 | |
| 
 | |
| void InterfacePane::OnSaveConfig()
 | |
| {
 | |
|   SConfig& settings = SConfig::GetInstance();
 | |
|   settings.m_use_builtin_title_database = m_checkbox_use_builtin_title_database->isChecked();
 | |
|   Settings::Instance().SetDebugModeEnabled(m_checkbox_show_debugging_ui->isChecked());
 | |
|   Settings::Instance().SetUserStylesEnabled(m_checkbox_use_userstyle->isChecked());
 | |
|   Settings::Instance().SetCurrentUserStyle(m_combobox_userstyle->currentData().toString());
 | |
| 
 | |
|   const bool visible = m_checkbox_use_userstyle->isChecked();
 | |
| 
 | |
|   m_combobox_userstyle->setVisible(visible);
 | |
|   m_label_userstyle->setVisible(visible);
 | |
| 
 | |
|   // Render Window Options
 | |
|   Settings::Instance().SetKeepWindowOnTop(m_checkbox_top_window->isChecked());
 | |
|   settings.bConfirmStop = m_checkbox_confirm_on_stop->isChecked();
 | |
|   Config::SetBase(Config::MAIN_USE_PANIC_HANDLERS, m_checkbox_use_panic_handlers->isChecked());
 | |
|   Config::SetBase(Config::MAIN_OSD_MESSAGES, m_checkbox_enable_osd->isChecked());
 | |
|   settings.m_show_active_title = m_checkbox_show_active_title->isChecked();
 | |
|   settings.m_PauseOnFocusLost = m_checkbox_pause_on_focus_lost->isChecked();
 | |
| 
 | |
|   Common::SetEnableAlert(Config::Get(Config::MAIN_USE_PANIC_HANDLERS));
 | |
| 
 | |
|   auto new_language = m_combobox_language->currentData().toString().toStdString();
 | |
|   if (new_language != SConfig::GetInstance().m_InterfaceLanguage)
 | |
|   {
 | |
|     SConfig::GetInstance().m_InterfaceLanguage = new_language;
 | |
|     ModalMessageBox::information(
 | |
|         this, tr("Restart Required"),
 | |
|         tr("You must restart Dolphin in order for the change to take effect."));
 | |
|   }
 | |
| 
 | |
|   const bool use_covers = m_checkbox_use_covers->isChecked();
 | |
| 
 | |
|   if (use_covers != Config::Get(Config::MAIN_USE_GAME_COVERS))
 | |
|   {
 | |
|     Config::SetBase(Config::MAIN_USE_GAME_COVERS, use_covers);
 | |
|     Settings::Instance().RefreshMetadata();
 | |
|   }
 | |
| 
 | |
|   Config::SetBase(Config::MAIN_FOCUSED_HOTKEYS, m_checkbox_focused_hotkeys->isChecked());
 | |
|   Config::SetBase(Config::MAIN_DISABLE_SCREENSAVER, m_checkbox_disable_screensaver->isChecked());
 | |
| 
 | |
|   settings.SaveSettings();
 | |
| }
 |