Merge pull request #12315 from Dentomologist/interfacepane_add_balloontips

InterfacePane: Add BalloonTips
This commit is contained in:
Admiral H. Curtiss 2024-05-31 19:41:55 +02:00 committed by GitHub
commit 171596ac74
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 348 additions and 224 deletions

View File

@ -30,3 +30,60 @@ void ConfigChoice::Update(int choice)
{ {
Config::SetBaseOrCurrent(m_setting, choice); Config::SetBaseOrCurrent(m_setting, choice);
} }
ConfigStringChoice::ConfigStringChoice(const std::vector<std::string>& options,
const Config::Info<std::string>& setting)
: m_setting(setting), m_text_is_data(true)
{
for (const auto& op : options)
addItem(QString::fromStdString(op));
Connect();
Load();
}
ConfigStringChoice::ConfigStringChoice(const std::vector<std::pair<QString, QString>>& options,
const Config::Info<std::string>& setting)
: m_setting(setting), m_text_is_data(false)
{
for (const auto& [option_text, option_data] : options)
addItem(option_text, option_data);
Connect();
Load();
}
void ConfigStringChoice::Connect()
{
const auto on_config_changed = [this]() {
QFont bf = font();
bf.setBold(Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base);
setFont(bf);
Load();
};
connect(&Settings::Instance(), &Settings::ConfigChanged, this, on_config_changed);
connect(this, &QComboBox::currentIndexChanged, this, &ConfigStringChoice::Update);
}
void ConfigStringChoice::Update(int index)
{
if (m_text_is_data)
{
Config::SetBaseOrCurrent(m_setting, itemText(index).toStdString());
}
else
{
Config::SetBaseOrCurrent(m_setting, itemData(index).toString().toStdString());
}
}
void ConfigStringChoice::Load()
{
const QString setting_value = QString::fromStdString(Config::Get(m_setting));
const int index = m_text_is_data ? findText(setting_value) : findData(setting_value);
const QSignalBlocker blocker(this);
setCurrentIndex(index);
}

View File

@ -3,6 +3,10 @@
#pragma once #pragma once
#include <string>
#include <utility>
#include <vector>
#include "DolphinQt/Config/ToolTipControls/ToolTipComboBox.h" #include "DolphinQt/Config/ToolTipControls/ToolTipComboBox.h"
#include "Common/Config/Config.h" #include "Common/Config/Config.h"
@ -18,3 +22,21 @@ private:
Config::Info<int> m_setting; Config::Info<int> m_setting;
}; };
class ConfigStringChoice : public ToolTipComboBox
{
Q_OBJECT
public:
ConfigStringChoice(const std::vector<std::string>& options,
const Config::Info<std::string>& setting);
ConfigStringChoice(const std::vector<std::pair<QString, QString>>& options,
const Config::Info<std::string>& setting);
private:
void Connect();
void Update(int index);
void Load();
Config::Info<std::string> m_setting;
bool m_text_is_data = false;
};

View File

@ -27,8 +27,13 @@ ConfigRadioInt::ConfigRadioInt(const QString& label, const Config::Info<int>& se
void ConfigRadioInt::Update() void ConfigRadioInt::Update()
{ {
if (!isChecked()) if (isChecked())
return; {
Config::SetBaseOrCurrent(m_setting, m_value);
Config::SetBaseOrCurrent(m_setting, m_value); emit OnSelected(m_value);
}
else
{
emit OnDeselected(m_value);
}
} }

View File

@ -13,6 +13,12 @@ class ConfigRadioInt : public ToolTipRadioButton
public: public:
ConfigRadioInt(const QString& label, const Config::Info<int>& setting, int value); ConfigRadioInt(const QString& label, const Config::Info<int>& setting, int value);
signals:
// Since selecting a new radio button deselects the old one, ::toggled will generate two signals.
// These are convenience functions so you can receive only one signal if desired.
void OnSelected(int new_value);
void OnDeselected(int old_value);
private: private:
void Update(); void Update();

View File

@ -118,9 +118,8 @@ QSettings& Settings::GetQSettings()
return settings; return settings;
} }
void Settings::SetThemeName(const QString& theme_name) void Settings::TriggerThemeChanged()
{ {
Config::SetBaseOrCurrent(Config::MAIN_THEME_NAME, theme_name.toStdString());
emit ThemeChanged(); emit ThemeChanged();
} }
@ -419,23 +418,11 @@ void Settings::SetStateSlot(int slot)
GetQSettings().setValue(QStringLiteral("Emulation/StateSlot"), slot); GetQSettings().setValue(QStringLiteral("Emulation/StateSlot"), slot);
} }
void Settings::SetCursorVisibility(Config::ShowCursor hideCursor)
{
Config::SetBaseOrCurrent(Config::MAIN_SHOW_CURSOR, hideCursor);
emit CursorVisibilityChanged();
}
Config::ShowCursor Settings::GetCursorVisibility() const Config::ShowCursor Settings::GetCursorVisibility() const
{ {
return Config::Get(Config::MAIN_SHOW_CURSOR); return Config::Get(Config::MAIN_SHOW_CURSOR);
} }
void Settings::SetLockCursor(bool lock_cursor)
{
Config::SetBaseOrCurrent(Config::MAIN_LOCK_CURSOR, lock_cursor);
emit LockCursorChanged();
}
bool Settings::GetLockCursor() const bool Settings::GetLockCursor() const
{ {
return Config::Get(Config::MAIN_LOCK_CURSOR); return Config::Get(Config::MAIN_LOCK_CURSOR);
@ -446,7 +433,6 @@ void Settings::SetKeepWindowOnTop(bool top)
if (IsKeepWindowOnTopEnabled() == top) if (IsKeepWindowOnTopEnabled() == top)
return; return;
Config::SetBaseOrCurrent(Config::MAIN_KEEP_WINDOW_ON_TOP, top);
emit KeepWindowOnTopChanged(top); emit KeepWindowOnTopChanged(top);
} }

View File

@ -51,7 +51,7 @@ public:
static QSettings& GetQSettings(); static QSettings& GetQSettings();
// UI // UI
void SetThemeName(const QString& theme_name); void TriggerThemeChanged();
void InitDefaultPalette(); void InitDefaultPalette();
void UpdateSystemDark(); void UpdateSystemDark();
void SetSystemDark(bool dark); void SetSystemDark(bool dark);
@ -122,9 +122,7 @@ public:
void SetUSBKeyboardConnected(bool connected); void SetUSBKeyboardConnected(bool connected);
// Graphics // Graphics
void SetCursorVisibility(Config::ShowCursor hideCursor);
Config::ShowCursor GetCursorVisibility() const; Config::ShowCursor GetCursorVisibility() const;
void SetLockCursor(bool lock_cursor);
bool GetLockCursor() const; bool GetLockCursor() const;
void SetKeepWindowOnTop(bool top); void SetKeepWindowOnTop(bool top);
bool IsKeepWindowOnTopEnabled() const; bool IsKeepWindowOnTopEnabled() const;

View File

@ -23,55 +23,60 @@
#include "Core/Config/MainSettings.h" #include "Core/Config/MainSettings.h"
#include "Core/Config/UISettings.h" #include "Core/Config/UISettings.h"
#include "DolphinQt/Config/ConfigControls/ConfigBool.h"
#include "DolphinQt/Config/ConfigControls/ConfigChoice.h"
#include "DolphinQt/Config/ConfigControls/ConfigRadio.h"
#include "DolphinQt/Config/ToolTipControls/ToolTipCheckBox.h" #include "DolphinQt/Config/ToolTipControls/ToolTipCheckBox.h"
#include "DolphinQt/Config/ToolTipControls/ToolTipComboBox.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/SignalBlocking.h" #include "DolphinQt/QtUtils/SignalBlocking.h"
#include "DolphinQt/Settings.h" #include "DolphinQt/Settings.h"
#include "UICommon/GameFile.h" #include "UICommon/GameFile.h"
static QComboBox* MakeLanguageComboBox() static ConfigStringChoice* MakeLanguageComboBox()
{ {
static const struct using QPair = std::pair<QString, QString>;
{ std::vector<QPair> languages = {
const QString name; QPair{QObject::tr("<System Language>"), QString{}},
const char* id; QPair{QStringLiteral(u"Bahasa Melayu"), QStringLiteral("ms")}, // Malay
} languages[] = { QPair{QStringLiteral(u"Catal\u00E0"), QStringLiteral("ca")}, // Catalan
{QStringLiteral(u"Bahasa Melayu"), "ms"}, // Malay QPair{QStringLiteral(u"\u010Ce\u0161tina"), QStringLiteral("cs")}, // Czech
{QStringLiteral(u"Catal\u00E0"), "ca"}, // Catalan QPair{QStringLiteral(u"Dansk"), QStringLiteral("da")}, // Danish
{QStringLiteral(u"\u010Ce\u0161tina"), "cs"}, // Czech QPair{QStringLiteral(u"Deutsch"), QStringLiteral("de")}, // German
{QStringLiteral(u"Dansk"), "da"}, // Danish QPair{QStringLiteral(u"English"), QStringLiteral("en")}, // English
{QStringLiteral(u"Deutsch"), "de"}, // German QPair{QStringLiteral(u"Espa\u00F1ol"), QStringLiteral("es")}, // Spanish
{QStringLiteral(u"English"), "en"}, // English QPair{QStringLiteral(u"Fran\u00E7ais"), QStringLiteral("fr")}, // French
{QStringLiteral(u"Espa\u00F1ol"), "es"}, // Spanish QPair{QStringLiteral(u"Hrvatski"), QStringLiteral("hr")}, // Croatian
{QStringLiteral(u"Fran\u00E7ais"), "fr"}, // French QPair{QStringLiteral(u"Italiano"), QStringLiteral("it")}, // Italian
{QStringLiteral(u"Hrvatski"), "hr"}, // Croatian QPair{QStringLiteral(u"Magyar"), QStringLiteral("hu")}, // Hungarian
{QStringLiteral(u"Italiano"), "it"}, // Italian QPair{QStringLiteral(u"Nederlands"), QStringLiteral("nl")}, // Dutch
{QStringLiteral(u"Magyar"), "hu"}, // Hungarian QPair{QStringLiteral(u"Norsk bokm\u00E5l"), QStringLiteral("nb")}, // Norwegian
{QStringLiteral(u"Nederlands"), "nl"}, // Dutch QPair{QStringLiteral(u"Polski"), QStringLiteral("pl")}, // Polish
{QStringLiteral(u"Norsk bokm\u00E5l"), "nb"}, // Norwegian QPair{QStringLiteral(u"Portugu\u00EAs"), QStringLiteral("pt")}, // Portuguese
{QStringLiteral(u"Polski"), "pl"}, // Polish QPair{QStringLiteral(u"Portugu\u00EAs (Brasil)"),
{QStringLiteral(u"Portugu\u00EAs"), "pt"}, // Portuguese QStringLiteral("pt_BR")}, // Portuguese (Brazil)
{QStringLiteral(u"Portugu\u00EAs (Brasil)"), "pt_BR"}, // Portuguese (Brazil) QPair{QStringLiteral(u"Rom\u00E2n\u0103"), QStringLiteral("ro")}, // Romanian
{QStringLiteral(u"Rom\u00E2n\u0103"), "ro"}, // Romanian QPair{QStringLiteral(u"Srpski"), QStringLiteral("sr")}, // Serbian
{QStringLiteral(u"Srpski"), "sr"}, // Serbian QPair{QStringLiteral(u"Suomi"), QStringLiteral("fi")}, // Finnish
{QStringLiteral(u"Suomi"), "fi"}, // Finnish QPair{QStringLiteral(u"Svenska"), QStringLiteral("sv")}, // Swedish
{QStringLiteral(u"Svenska"), "sv"}, // Swedish QPair{QStringLiteral(u"T\u00FCrk\u00E7e"), QStringLiteral("tr")}, // Turkish
{QStringLiteral(u"T\u00FCrk\u00E7e"), "tr"}, // Turkish QPair{QStringLiteral(u"\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC"),
{QStringLiteral(u"\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC"), "el"}, // Greek QStringLiteral("el")}, // Greek
{QStringLiteral(u"\u0420\u0443\u0441\u0441\u043A\u0438\u0439"), "ru"}, // Russian QPair{QStringLiteral(u"\u0420\u0443\u0441\u0441\u043A\u0438\u0439"),
{QStringLiteral(u"\u0627\u0644\u0639\u0631\u0628\u064A\u0629"), "ar"}, // Arabic QStringLiteral("ru")}, // Russian
{QStringLiteral(u"\u0641\u0627\u0631\u0633\u06CC"), "fa"}, // Farsi QPair{QStringLiteral(u"\u0627\u0644\u0639\u0631\u0628\u064A\u0629"),
{QStringLiteral(u"\uD55C\uAD6D\uC5B4"), "ko"}, // Korean QStringLiteral("ar")}, // Arabic
{QStringLiteral(u"\u65E5\u672C\u8A9E"), "ja"}, // Japanese QPair{QStringLiteral(u"\u0641\u0627\u0631\u0633\u06CC"), QStringLiteral("fa")}, // Farsi
{QStringLiteral(u"\u7B80\u4F53\u4E2D\u6587"), "zh_CN"}, // Simplified Chinese QPair{QStringLiteral(u"\uD55C\uAD6D\uC5B4"), QStringLiteral("ko")}, // Korean
{QStringLiteral(u"\u7E41\u9AD4\u4E2D\u6587"), "zh_TW"}, // Traditional Chinese QPair{QStringLiteral(u"\u65E5\u672C\u8A9E"), QStringLiteral("ja")}, // Japanese
QPair{QStringLiteral(u"\u7B80\u4F53\u4E2D\u6587"),
QStringLiteral("zh_CN")}, // Simplified Chinese
QPair{QStringLiteral(u"\u7E41\u9AD4\u4E2D\u6587"),
QStringLiteral("zh_TW")}, // Traditional Chinese
}; };
auto* combobox = new QComboBox(); auto* const combobox = new ConfigStringChoice(languages, Config::MAIN_INTERFACE_LANGUAGE);
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 // 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 // SettingWindow for the first time. The culprit seems to be non-Latin graphemes in the above
@ -84,11 +89,12 @@ static QComboBox* MakeLanguageComboBox()
InterfacePane::InterfacePane(QWidget* parent) : QWidget(parent) InterfacePane::InterfacePane(QWidget* parent) : QWidget(parent)
{ {
CreateLayout(); CreateLayout();
LoadConfig(); UpdateShowDebuggingCheckbox();
LoadUserStyle();
ConnectLayout(); ConnectLayout();
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
&InterfacePane::LoadConfig); &InterfacePane::UpdateShowDebuggingCheckbox);
} }
void InterfacePane::CreateLayout() void InterfacePane::CreateLayout()
@ -97,6 +103,7 @@ void InterfacePane::CreateLayout()
// Create layout here // Create layout here
CreateUI(); CreateUI();
CreateInGame(); CreateInGame();
AddDescriptions();
m_main_layout->addStretch(1); m_main_layout->addStretch(1);
setLayout(m_main_layout); setLayout(m_main_layout);
@ -118,21 +125,20 @@ void InterfacePane::CreateUI()
m_combobox_language = MakeLanguageComboBox(); m_combobox_language = MakeLanguageComboBox();
combobox_layout->addRow(tr("&Language:"), m_combobox_language); combobox_layout->addRow(tr("&Language:"), m_combobox_language);
// List avalable themes
auto theme_paths =
Common::DoFileSearch({File::GetUserPath(D_THEMES_IDX), File::GetSysDirectory() + THEMES_DIR});
std::vector<std::string> theme_names;
theme_names.reserve(theme_paths.size());
std::transform(theme_paths.cbegin(), theme_paths.cend(), std::back_inserter(theme_names),
PathToFileName);
// Theme Combobox // Theme Combobox
m_combobox_theme = new QComboBox; m_combobox_theme = new ConfigStringChoice(theme_names, Config::MAIN_THEME_NAME);
combobox_layout->addRow(tr("&Theme:"), m_combobox_theme); 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 // User Style Combobox
m_combobox_userstyle = new QComboBox; m_combobox_userstyle = new ToolTipComboBox;
m_label_userstyle = new QLabel(tr("Style:")); m_label_userstyle = new QLabel(tr("Style:"));
combobox_layout->addRow(m_label_userstyle, m_combobox_userstyle); combobox_layout->addRow(m_label_userstyle, m_combobox_userstyle);
@ -153,12 +159,16 @@ void InterfacePane::CreateUI()
} }
// Checkboxes // Checkboxes
m_checkbox_use_builtin_title_database = new QCheckBox(tr("Use Built-In Database of Game Names")); m_checkbox_use_builtin_title_database = new ConfigBool(tr("Use Built-In Database of Game Names"),
Config::MAIN_USE_BUILT_IN_TITLE_DATABASE);
m_checkbox_use_covers = m_checkbox_use_covers =
new QCheckBox(tr("Download Game Covers from GameTDB.com for Use in Grid Mode")); new ConfigBool(tr("Download Game Covers from GameTDB.com for Use in Grid Mode"),
Config::MAIN_USE_GAME_COVERS);
m_checkbox_show_debugging_ui = new ToolTipCheckBox(tr("Enable Debugging UI")); m_checkbox_show_debugging_ui = new ToolTipCheckBox(tr("Enable Debugging UI"));
m_checkbox_focused_hotkeys = new QCheckBox(tr("Hotkeys Require Window Focus")); m_checkbox_focused_hotkeys =
m_checkbox_disable_screensaver = new QCheckBox(tr("Inhibit Screensaver During Emulation")); new ConfigBool(tr("Hotkeys Require Window Focus"), Config::MAIN_FOCUSED_HOTKEYS);
m_checkbox_disable_screensaver =
new ConfigBool(tr("Inhibit Screensaver During Emulation"), Config::MAIN_DISABLE_SCREENSAVER);
groupbox_layout->addWidget(m_checkbox_use_builtin_title_database); groupbox_layout->addWidget(m_checkbox_use_builtin_title_database);
groupbox_layout->addWidget(m_checkbox_use_covers); groupbox_layout->addWidget(m_checkbox_use_covers);
@ -174,34 +184,36 @@ void InterfacePane::CreateInGame()
groupbox->setLayout(groupbox_layout); groupbox->setLayout(groupbox_layout);
m_main_layout->addWidget(groupbox); m_main_layout->addWidget(groupbox);
m_checkbox_top_window = new QCheckBox(tr("Keep Window on Top")); m_checkbox_top_window = new ConfigBool(tr("Keep Window on Top"), Config::MAIN_KEEP_WINDOW_ON_TOP);
m_checkbox_confirm_on_stop = new QCheckBox(tr("Confirm on Stop")); m_checkbox_confirm_on_stop = new ConfigBool(tr("Confirm on Stop"), Config::MAIN_CONFIRM_ON_STOP);
m_checkbox_use_panic_handlers = new QCheckBox(tr("Use Panic Handlers")); m_checkbox_use_panic_handlers =
m_checkbox_enable_osd = new QCheckBox(tr("Show On-Screen Display Messages")); new ConfigBool(tr("Use Panic Handlers"), Config::MAIN_USE_PANIC_HANDLERS);
m_checkbox_show_active_title = new QCheckBox(tr("Show Active Title in Window Title")); m_checkbox_enable_osd =
m_checkbox_pause_on_focus_lost = new QCheckBox(tr("Pause on Focus Loss")); new ConfigBool(tr("Show On-Screen Display Messages"), Config::MAIN_OSD_MESSAGES);
m_checkbox_show_active_title =
new ConfigBool(tr("Show Active Title in Window Title"), Config::MAIN_SHOW_ACTIVE_TITLE);
m_checkbox_pause_on_focus_lost =
new ConfigBool(tr("Pause on Focus Loss"), Config::MAIN_PAUSE_ON_FOCUS_LOST);
auto* mouse_groupbox = new QGroupBox(tr("Mouse Cursor Visibility")); auto* mouse_groupbox = new QGroupBox(tr("Mouse Cursor Visibility"));
auto* m_vboxlayout_hide_mouse = new QVBoxLayout; auto* m_vboxlayout_hide_mouse = new QVBoxLayout;
mouse_groupbox->setLayout(m_vboxlayout_hide_mouse); mouse_groupbox->setLayout(m_vboxlayout_hide_mouse);
m_radio_cursor_visible_movement = new QRadioButton(tr("On Movement")); m_radio_cursor_visible_movement =
m_radio_cursor_visible_movement->setToolTip( new ConfigRadioInt(tr("On Movement"), Config::MAIN_SHOW_CURSOR,
tr("Mouse Cursor hides after inactivity and returns upon Mouse Cursor movement.")); static_cast<int>(Config::ShowCursor::OnMovement));
m_radio_cursor_visible_never = new QRadioButton(tr("Never")); m_radio_cursor_visible_never = new ConfigRadioInt(tr("Never"), Config::MAIN_SHOW_CURSOR,
m_radio_cursor_visible_never->setToolTip( static_cast<int>(Config::ShowCursor::Never));
tr("Mouse Cursor will never be visible while a game is running.")); m_radio_cursor_visible_always = new ConfigRadioInt(
m_radio_cursor_visible_always = new QRadioButton(tr("Always")); tr("Always"), Config::MAIN_SHOW_CURSOR, static_cast<int>(Config::ShowCursor::Constantly));
m_radio_cursor_visible_always->setToolTip(tr("Mouse Cursor will always be visible."));
m_vboxlayout_hide_mouse->addWidget(m_radio_cursor_visible_movement); m_vboxlayout_hide_mouse->addWidget(m_radio_cursor_visible_movement);
m_vboxlayout_hide_mouse->addWidget(m_radio_cursor_visible_never); m_vboxlayout_hide_mouse->addWidget(m_radio_cursor_visible_never);
m_vboxlayout_hide_mouse->addWidget(m_radio_cursor_visible_always); m_vboxlayout_hide_mouse->addWidget(m_radio_cursor_visible_always);
m_checkbox_lock_mouse = new ConfigBool(tr("Lock Mouse Cursor"), Config::MAIN_LOCK_CURSOR);
// this ends up not being managed unless _WIN32, so lets not leak // this ends up not being managed unless _WIN32, so lets not leak
m_checkbox_lock_mouse = new QCheckBox(tr("Lock Mouse Cursor"), this); m_checkbox_lock_mouse->setParent(this);
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."));
mouse_groupbox->setLayout(m_vboxlayout_hide_mouse); mouse_groupbox->setLayout(m_vboxlayout_hide_mouse);
groupbox_layout->addWidget(m_checkbox_top_window); groupbox_layout->addWidget(m_checkbox_top_window);
@ -220,62 +232,62 @@ void InterfacePane::CreateInGame()
void InterfacePane::ConnectLayout() void InterfacePane::ConnectLayout()
{ {
connect(m_checkbox_use_builtin_title_database, &QCheckBox::toggled, this, connect(m_checkbox_use_builtin_title_database, &QCheckBox::toggled, &Settings::Instance(),
&InterfacePane::OnSaveConfig); &Settings::GameListRefreshRequested);
connect(m_checkbox_use_covers, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig); connect(m_checkbox_use_covers, &QCheckBox::toggled, &Settings::Instance(),
connect(m_checkbox_disable_screensaver, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig); &Settings::RefreshMetadata);
connect(m_checkbox_show_debugging_ui, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig); connect(m_checkbox_show_debugging_ui, &QCheckBox::toggled, &Settings::Instance(),
connect(m_checkbox_focused_hotkeys, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig); &Settings::SetDebugModeEnabled);
connect(m_combobox_theme, &QComboBox::currentIndexChanged, this, [this](int index) { connect(m_combobox_theme, &QComboBox::currentIndexChanged, this,
Settings::Instance().SetThemeName(m_combobox_theme->itemText(index)); [this](int index) { Settings::Instance().TriggerThemeChanged(); });
});
connect(m_combobox_userstyle, &QComboBox::currentIndexChanged, this, connect(m_combobox_userstyle, &QComboBox::currentIndexChanged, this,
&InterfacePane::OnSaveConfig); &InterfacePane::OnUserStyleChanged);
connect(m_combobox_language, &QComboBox::currentIndexChanged, this, &InterfacePane::OnSaveConfig); connect(m_combobox_language, &QComboBox::currentIndexChanged, this,
connect(m_checkbox_top_window, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig); [this]() { OnLanguageChanged(); });
connect(m_checkbox_confirm_on_stop, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig); connect(m_checkbox_top_window, &QCheckBox::toggled, &Settings::Instance(),
connect(m_checkbox_use_panic_handlers, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig); &Settings::KeepWindowOnTopChanged);
connect(m_checkbox_show_active_title, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig); connect(m_radio_cursor_visible_movement, &ConfigRadioInt::OnSelected, &Settings::Instance(),
connect(m_checkbox_enable_osd, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig); &Settings::CursorVisibilityChanged);
connect(m_checkbox_pause_on_focus_lost, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig); connect(m_radio_cursor_visible_never, &ConfigRadioInt::OnSelected, &Settings::Instance(),
connect(m_radio_cursor_visible_movement, &QRadioButton::toggled, this, &Settings::CursorVisibilityChanged);
&InterfacePane::OnCursorVisibleMovement); connect(m_radio_cursor_visible_always, &ConfigRadioInt::OnSelected, &Settings::Instance(),
connect(m_radio_cursor_visible_never, &QRadioButton::toggled, this, &Settings::CursorVisibilityChanged);
&InterfacePane::OnCursorVisibleNever);
connect(m_radio_cursor_visible_always, &QRadioButton::toggled, this,
&InterfacePane::OnCursorVisibleAlways);
connect(m_checkbox_lock_mouse, &QCheckBox::toggled, &Settings::Instance(), connect(m_checkbox_lock_mouse, &QCheckBox::toggled, &Settings::Instance(),
&Settings::SetLockCursor); [this]() { Settings::Instance().LockCursorChanged(); });
} }
void InterfacePane::LoadConfig() void InterfacePane::UpdateShowDebuggingCheckbox()
{ {
SignalBlocking(m_checkbox_use_builtin_title_database)
->setChecked(Config::Get(Config::MAIN_USE_BUILT_IN_TITLE_DATABASE));
SignalBlocking(m_checkbox_show_debugging_ui) SignalBlocking(m_checkbox_show_debugging_ui)
->setChecked(Settings::Instance().IsDebugModeEnabled()); ->setChecked(Settings::Instance().IsDebugModeEnabled());
static constexpr char TR_SHOW_DEBUGGING_UI_DESCRIPTION[] = QT_TR_NOOP(
"Shows Dolphin's debugging User Interface. This lets you view and modify a game's code and "
"memory contents, set debugging breakpoints, examine network requests, and more."
"<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>");
static constexpr char TR_DISABLED_IN_HARDCORE_DESCRIPTION[] =
QT_TR_NOOP("<dolphin_emphasis>Disabled in Hardcore Mode.</dolphin_emphasis>");
#ifdef USE_RETRO_ACHIEVEMENTS #ifdef USE_RETRO_ACHIEVEMENTS
bool hardcore = AchievementManager::GetInstance().IsHardcoreModeActive(); bool hardcore = AchievementManager::GetInstance().IsHardcoreModeActive();
SignalBlocking(m_checkbox_show_debugging_ui)->setEnabled(!hardcore); SignalBlocking(m_checkbox_show_debugging_ui)->setEnabled(!hardcore);
if (hardcore) if (hardcore)
{ {
m_checkbox_show_debugging_ui->SetDescription( m_checkbox_show_debugging_ui->SetDescription(tr("%1<br><br>%2")
tr("<dolphin_emphasis>Disabled in Hardcore Mode.</dolphin_emphasis>")); .arg(tr(TR_SHOW_DEBUGGING_UI_DESCRIPTION))
.arg(tr(TR_DISABLED_IN_HARDCORE_DESCRIPTION)));
} }
else else
{ {
m_checkbox_show_debugging_ui->SetDescription({}); m_checkbox_show_debugging_ui->SetDescription(tr(TR_SHOW_DEBUGGING_UI_DESCRIPTION));
} }
#else
m_checkbox_show_debugging_ui->SetDescription(tr(TR_SHOW_DEBUGGING_UI_DESCRIPTION));
#endif // USE_RETRO_ACHIEVEMENTS #endif // USE_RETRO_ACHIEVEMENTS
}
SignalBlocking(m_combobox_language) void InterfacePane::LoadUserStyle()
->setCurrentIndex(m_combobox_language->findData( {
QString::fromStdString(Config::Get(Config::MAIN_INTERFACE_LANGUAGE))));
SignalBlocking(m_combobox_theme)
->setCurrentIndex(
m_combobox_theme->findText(QString::fromStdString(Config::Get(Config::MAIN_THEME_NAME))));
const Settings::StyleType style_type = Settings::Instance().GetStyleType(); const Settings::StyleType style_type = Settings::Instance().GetStyleType();
const QString userstyle = Settings::Instance().GetUserStyleName(); const QString userstyle = Settings::Instance().GetUserStyleName();
const int index = style_type == Settings::StyleType::User ? const int index = style_type == Settings::StyleType::User ?
@ -284,37 +296,10 @@ void InterfacePane::LoadConfig()
if (index > 0) if (index > 0)
SignalBlocking(m_combobox_userstyle)->setCurrentIndex(index); SignalBlocking(m_combobox_userstyle)->setCurrentIndex(index);
// Render Window Options
SignalBlocking(m_checkbox_top_window)
->setChecked(Settings::Instance().IsKeepWindowOnTopEnabled());
SignalBlocking(m_checkbox_confirm_on_stop)->setChecked(Config::Get(Config::MAIN_CONFIRM_ON_STOP));
SignalBlocking(m_checkbox_use_panic_handlers)
->setChecked(Config::Get(Config::MAIN_USE_PANIC_HANDLERS));
SignalBlocking(m_checkbox_enable_osd)->setChecked(Config::Get(Config::MAIN_OSD_MESSAGES));
SignalBlocking(m_checkbox_show_active_title)
->setChecked(Config::Get(Config::MAIN_SHOW_ACTIVE_TITLE));
SignalBlocking(m_checkbox_pause_on_focus_lost)
->setChecked(Config::Get(Config::MAIN_PAUSE_ON_FOCUS_LOST));
SignalBlocking(m_checkbox_use_covers)->setChecked(Config::Get(Config::MAIN_USE_GAME_COVERS));
SignalBlocking(m_checkbox_focused_hotkeys)->setChecked(Config::Get(Config::MAIN_FOCUSED_HOTKEYS));
SignalBlocking(m_radio_cursor_visible_movement)
->setChecked(Settings::Instance().GetCursorVisibility() == Config::ShowCursor::OnMovement);
SignalBlocking(m_radio_cursor_visible_always)
->setChecked(Settings::Instance().GetCursorVisibility() == Config::ShowCursor::Constantly);
SignalBlocking(m_radio_cursor_visible_never)
->setChecked(Settings::Instance().GetCursorVisibility() == Config::ShowCursor::Never);
SignalBlocking(m_checkbox_lock_mouse)->setChecked(Settings::Instance().GetLockCursor());
SignalBlocking(m_checkbox_disable_screensaver)
->setChecked(Config::Get(Config::MAIN_DISABLE_SCREENSAVER));
} }
void InterfacePane::OnSaveConfig() void InterfacePane::OnUserStyleChanged()
{ {
Config::SetBase(Config::MAIN_USE_BUILT_IN_TITLE_DATABASE,
m_checkbox_use_builtin_title_database->isChecked());
Settings::Instance().SetDebugModeEnabled(m_checkbox_show_debugging_ui->isChecked());
const auto selected_style = m_combobox_userstyle->currentData(); const auto selected_style = m_combobox_userstyle->currentData();
bool is_builtin_type = false; bool is_builtin_type = false;
const int style_type_int = selected_style.toInt(&is_builtin_type); const int style_type_int = selected_style.toInt(&is_builtin_type);
@ -324,49 +309,114 @@ void InterfacePane::OnSaveConfig()
if (!is_builtin_type) if (!is_builtin_type)
Settings::Instance().SetUserStyleName(selected_style.toString()); Settings::Instance().SetUserStyleName(selected_style.toString());
Settings::Instance().ApplyStyle(); Settings::Instance().ApplyStyle();
// Render Window Options
Settings::Instance().SetKeepWindowOnTop(m_checkbox_top_window->isChecked());
Config::SetBase(Config::MAIN_CONFIRM_ON_STOP, 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());
Config::SetBase(Config::MAIN_SHOW_ACTIVE_TITLE, m_checkbox_show_active_title->isChecked());
Config::SetBase(Config::MAIN_PAUSE_ON_FOCUS_LOST, m_checkbox_pause_on_focus_lost->isChecked());
auto new_language = m_combobox_language->currentData().toString().toStdString();
if (new_language != Config::Get(Config::MAIN_INTERFACE_LANGUAGE))
{
Config::SetBase(Config::MAIN_INTERFACE_LANGUAGE, 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());
Config::Save();
} }
void InterfacePane::OnCursorVisibleMovement() void InterfacePane::OnLanguageChanged()
{ {
Settings::Instance().SetCursorVisibility(Config::ShowCursor::OnMovement); ModalMessageBox::information(
this, tr("Restart Required"),
tr("You must restart Dolphin in order for the change to take effect."));
} }
void InterfacePane::OnCursorVisibleNever() void InterfacePane::AddDescriptions()
{ {
Settings::Instance().SetCursorVisibility(Config::ShowCursor::Never); static constexpr char TR_TITLE_DATABASE_DESCRIPTION[] = QT_TR_NOOP(
} "Uses Dolphin's database of properly formatted names in the Game List Title column."
"<br><br><dolphin_emphasis>If unsure, leave this checked.</dolphin_emphasis>");
static constexpr char TR_THEME_DESCRIPTION[] =
QT_TR_NOOP("Changes the appearance and color of Dolphin's buttons."
"<br><br><dolphin_emphasis>If unsure, select Clean.</dolphin_emphasis>");
static constexpr char TR_TOP_WINDOW_DESCRIPTION[] =
QT_TR_NOOP("Forces the render window to stay on top of other windows and applications."
"<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>");
static constexpr char TR_LANGUAGE_DESCRIPTION[] = QT_TR_NOOP(
"Sets the language displayed by Dolphin's User Interface."
"<br><br>Changes to this setting only take effect once Dolphin is restarted."
"<br><br><dolphin_emphasis>If unsure, select &lt;System Language&gt;.</dolphin_emphasis>");
static constexpr char TR_FOCUSED_HOTKEYS_DESCRIPTION[] =
QT_TR_NOOP("Requires the render window to be focused for hotkeys to take effect."
"<br><br><dolphin_emphasis>If unsure, leave this checked.</dolphin_emphasis>");
static constexpr char TR_USE_COVERS_DESCRIPTION[] =
QT_TR_NOOP("Downloads full game covers from GameTDB.com to display in the Game List's Grid "
"View. If this setting is unchecked the Game List displays a banner generated "
"from the game's save files, and if the game has no save file displays a generic "
"banner instead."
"<br><br>List View will always use the save file banners."
"<br><br><dolphin_emphasis>If unsure, leave this checked.</dolphin_emphasis>");
static constexpr char TR_DISABLE_SCREENSAVER_DESCRIPTION[] =
QT_TR_NOOP("Disables your screensaver while running a game."
"<br><br><dolphin_emphasis>If unsure, leave this checked.</dolphin_emphasis>");
static constexpr char TR_CONFIRM_ON_STOP_DESCRIPTION[] =
QT_TR_NOOP("Prompts you to confirm that you want to end emulation when you press Stop."
"<br><br><dolphin_emphasis>If unsure, leave this checked.</dolphin_emphasis>");
static constexpr char TR_USE_PANIC_HANDLERS_DESCRIPTION[] =
QT_TR_NOOP("In the event of an error, Dolphin will halt to inform you of the error and "
"present choices on how to proceed. With this option disabled, Dolphin will "
"\"ignore\" all errors. Emulation will not be halted and you will not be notified."
"<br><br><dolphin_emphasis>If unsure, leave this checked.</dolphin_emphasis>");
static constexpr char TR_ENABLE_OSD_DESCRIPTION[] =
QT_TR_NOOP("Shows on-screen display messages over the render window. These messages "
"disappear after several seconds."
"<br><br><dolphin_emphasis>If unsure, leave this checked.</dolphin_emphasis>");
static constexpr char TR_SHOW_ACTIVE_TITLE_DESCRIPTION[] =
QT_TR_NOOP("Shows the active game title in the render window's title bar."
"<br><br><dolphin_emphasis>If unsure, leave this checked.</dolphin_emphasis>");
static constexpr char TR_PAUSE_ON_FOCUS_LOST_DESCRIPTION[] =
QT_TR_NOOP("Pauses the game whenever the render window isn't focused."
"<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>");
static constexpr char TR_LOCK_MOUSE_DESCRIPTION[] =
QT_TR_NOOP("Locks the Mouse Cursor to the Render Widget as long as it has focus. You can "
"set a hotkey to unlock it."
"<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>");
static constexpr char TR_CURSOR_VISIBLE_MOVEMENT_DESCRIPTION[] =
QT_TR_NOOP("Shows the Mouse Cursor briefly whenever it has recently moved, then hides it."
"<br><br><dolphin_emphasis>If unsure, select this mode.</dolphin_emphasis>");
static constexpr char TR_CURSOR_VISIBLE_NEVER_DESCRIPTION[] = QT_TR_NOOP(
"Hides the Mouse Cursor whenever it is inside the render window and the render window is "
"focused."
"<br><br><dolphin_emphasis>If unsure, select &quot;On Movement&quot;.</dolphin_emphasis>");
static constexpr char TR_CURSOR_VISIBLE_ALWAYS_DESCRIPTION[] = QT_TR_NOOP(
"Shows the Mouse Cursor at all times."
"<br><br><dolphin_emphasis>If unsure, select &quot;On Movement&quot;.</dolphin_emphasis>");
static constexpr char TR_USER_STYLE_DESCRIPTION[] =
QT_TR_NOOP("Sets the style of Dolphin's User Interface. Any Custom User Styles that you have "
"loaded will be presented here, allowing you to switch to them."
"<br><br><dolphin_emphasis>If unsure, select (System).</dolphin_emphasis>");
void InterfacePane::OnCursorVisibleAlways() m_checkbox_use_builtin_title_database->SetDescription(tr(TR_TITLE_DATABASE_DESCRIPTION));
{
Settings::Instance().SetCursorVisibility(Config::ShowCursor::Constantly); m_combobox_theme->SetTitle(tr("Theme"));
m_combobox_theme->SetDescription(tr(TR_THEME_DESCRIPTION));
m_checkbox_top_window->SetDescription(tr(TR_TOP_WINDOW_DESCRIPTION));
m_combobox_language->SetTitle(tr("Language"));
m_combobox_language->SetDescription(tr(TR_LANGUAGE_DESCRIPTION));
m_checkbox_focused_hotkeys->SetDescription(tr(TR_FOCUSED_HOTKEYS_DESCRIPTION));
m_checkbox_use_covers->SetDescription(tr(TR_USE_COVERS_DESCRIPTION));
m_checkbox_disable_screensaver->SetDescription(tr(TR_DISABLE_SCREENSAVER_DESCRIPTION));
m_checkbox_confirm_on_stop->SetDescription(tr(TR_CONFIRM_ON_STOP_DESCRIPTION));
m_checkbox_use_panic_handlers->SetDescription(tr(TR_USE_PANIC_HANDLERS_DESCRIPTION));
m_checkbox_enable_osd->SetDescription(tr(TR_ENABLE_OSD_DESCRIPTION));
m_checkbox_show_active_title->SetDescription(tr(TR_SHOW_ACTIVE_TITLE_DESCRIPTION));
m_checkbox_pause_on_focus_lost->SetDescription(tr(TR_PAUSE_ON_FOCUS_LOST_DESCRIPTION));
m_checkbox_lock_mouse->SetDescription(tr(TR_LOCK_MOUSE_DESCRIPTION));
m_radio_cursor_visible_movement->SetDescription(tr(TR_CURSOR_VISIBLE_MOVEMENT_DESCRIPTION));
m_radio_cursor_visible_never->SetDescription(tr(TR_CURSOR_VISIBLE_NEVER_DESCRIPTION));
m_radio_cursor_visible_always->SetDescription(tr(TR_CURSOR_VISIBLE_ALWAYS_DESCRIPTION));
m_combobox_userstyle->SetTitle(tr("Style"));
m_combobox_userstyle->SetDescription(tr(TR_USER_STYLE_DESCRIPTION));
} }

View File

@ -5,12 +5,13 @@
#include <QWidget> #include <QWidget>
class QCheckBox; class ConfigBool;
class QComboBox; class ConfigRadioInt;
class ConfigStringChoice;
class QLabel; class QLabel;
class QRadioButton;
class QVBoxLayout; class QVBoxLayout;
class ToolTipCheckBox; class ToolTipCheckBox;
class ToolTipComboBox;
class InterfacePane final : public QWidget class InterfacePane final : public QWidget
{ {
@ -22,34 +23,33 @@ private:
void CreateLayout(); void CreateLayout();
void CreateUI(); void CreateUI();
void CreateInGame(); void CreateInGame();
void AddDescriptions();
void ConnectLayout(); void ConnectLayout();
void LoadConfig(); void UpdateShowDebuggingCheckbox();
void OnSaveConfig(); void LoadUserStyle();
void OnCursorVisibleMovement(); void OnUserStyleChanged();
void OnCursorVisibleNever(); void OnLanguageChanged();
void OnCursorVisibleAlways();
QVBoxLayout* m_main_layout; QVBoxLayout* m_main_layout;
QComboBox* m_combobox_language; ConfigStringChoice* m_combobox_language;
QComboBox* m_combobox_theme; ConfigStringChoice* m_combobox_theme;
QComboBox* m_combobox_userstyle; ToolTipComboBox* m_combobox_userstyle;
QLabel* m_label_userstyle; QLabel* m_label_userstyle;
QCheckBox* m_checkbox_top_window; ConfigBool* m_checkbox_top_window;
QCheckBox* m_checkbox_use_builtin_title_database; ConfigBool* m_checkbox_use_builtin_title_database;
QCheckBox* m_checkbox_use_userstyle;
ToolTipCheckBox* m_checkbox_show_debugging_ui; ToolTipCheckBox* m_checkbox_show_debugging_ui;
QCheckBox* m_checkbox_focused_hotkeys; ConfigBool* m_checkbox_focused_hotkeys;
QCheckBox* m_checkbox_use_covers; ConfigBool* m_checkbox_use_covers;
QCheckBox* m_checkbox_disable_screensaver; ConfigBool* m_checkbox_disable_screensaver;
QCheckBox* m_checkbox_confirm_on_stop; ConfigBool* m_checkbox_confirm_on_stop;
QCheckBox* m_checkbox_use_panic_handlers; ConfigBool* m_checkbox_use_panic_handlers;
QCheckBox* m_checkbox_enable_osd; ConfigBool* m_checkbox_enable_osd;
QCheckBox* m_checkbox_show_active_title; ConfigBool* m_checkbox_show_active_title;
QCheckBox* m_checkbox_pause_on_focus_lost; ConfigBool* m_checkbox_pause_on_focus_lost;
QRadioButton* m_radio_cursor_visible_movement; ConfigRadioInt* m_radio_cursor_visible_movement;
QRadioButton* m_radio_cursor_visible_never; ConfigRadioInt* m_radio_cursor_visible_never;
QRadioButton* m_radio_cursor_visible_always; ConfigRadioInt* m_radio_cursor_visible_always;
QCheckBox* m_checkbox_lock_mouse; ConfigBool* m_checkbox_lock_mouse;
}; };