Add shortcuts and status bar widgets to toggle and set 3D factor (#6277)
This commit is contained in:
parent
f66d03dd48
commit
691cb43871
9 changed files with 135 additions and 37 deletions
2
dist/qt_themes/colorful/style.qrc
vendored
2
dist/qt_themes/colorful/style.qrc
vendored
|
@ -13,6 +13,6 @@
|
|||
<file alias="256x256/plus_folder.png">icons/256x256/plus_folder.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="colorful">
|
||||
<file>style.qss</file>
|
||||
<file alias="style.qss">../default/style.qss</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
4
dist/qt_themes/colorful/style.qss
vendored
4
dist/qt_themes/colorful/style.qss
vendored
|
@ -1,4 +0,0 @@
|
|||
/*
|
||||
This file is intentionally left blank.
|
||||
We do not want to apply any stylesheet for colorful, only icons.
|
||||
*/
|
17
dist/qt_themes/default/default.qrc
vendored
17
dist/qt_themes/default/default.qrc
vendored
|
@ -1,33 +1,22 @@
|
|||
<RCC>
|
||||
<qresource prefix="icons/default">
|
||||
<file alias="index.theme">icons/index.theme</file>
|
||||
|
||||
<file alias="16x16/checked.png">icons/16x16/checked.png</file>
|
||||
|
||||
<file alias="16x16/failed.png">icons/16x16/failed.png</file>
|
||||
|
||||
<file alias="16x16/connected.png">icons/16x16/connected.png</file>
|
||||
|
||||
<file alias="16x16/disconnected.png">icons/16x16/disconnected.png</file>
|
||||
|
||||
<file alias="16x16/connected_notification.png">icons/16x16/connected_notification.png</file>
|
||||
|
||||
<file alias="16x16/lock.png">icons/16x16/lock.png</file>
|
||||
|
||||
<file alias="48x48/bad_folder.png">icons/48x48/bad_folder.png</file>
|
||||
|
||||
<file alias="48x48/chip.png">icons/48x48/chip.png</file>
|
||||
|
||||
<file alias="48x48/folder.png">icons/48x48/folder.png</file>
|
||||
|
||||
<file alias="48x48/no_avatar.png">icons/48x48/no_avatar.png</file>
|
||||
|
||||
<file alias="48x48/plus.png">icons/48x48/plus.png</file>
|
||||
|
||||
<file alias="48x48/sd_card.png">icons/48x48/sd_card.png</file>
|
||||
|
||||
<file alias="256x256/citra.png">icons/256x256/citra.png</file>
|
||||
|
||||
<file alias="256x256/plus_folder.png">icons/256x256/plus_folder.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="default">
|
||||
<file>style.qss</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
14
dist/qt_themes/default/style.qss
vendored
Normal file
14
dist/qt_themes/default/style.qss
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
QPushButton#3DOptionStatusBarButton {
|
||||
color: #A5A5A5;
|
||||
font-weight: bold;
|
||||
border: 1px solid transparent;
|
||||
background-color: transparent;
|
||||
padding: 0px 3px 0px 3px;
|
||||
text-align: center;
|
||||
min-width: 60px;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
QPushButton#3DOptionStatusBarButton:hover {
|
||||
border: 1px solid #76797C;
|
||||
}
|
22
dist/qt_themes/qdarkstyle/style.qss
vendored
22
dist/qt_themes/qdarkstyle/style.qss
vendored
|
@ -522,13 +522,12 @@ QToolButton#qt_toolbar_ext_button {
|
|||
|
||||
QPushButton {
|
||||
color: #eff0f1;
|
||||
border-width: 1px;
|
||||
border-color: #54575B;
|
||||
border-style: solid;
|
||||
padding: 6px 4px;
|
||||
border: 1px solid #54575B;
|
||||
border-radius: 2px;
|
||||
padding: 5px 0px 5px 0px;
|
||||
outline: none;
|
||||
min-width: 100px;
|
||||
min-height: 13px;
|
||||
background-color: #232629;
|
||||
}
|
||||
|
||||
|
@ -1237,3 +1236,18 @@ QPlainTextEdit:disabled {
|
|||
TouchScreenPreview {
|
||||
qproperty-dotHighlightColor: #3daee9;
|
||||
}
|
||||
|
||||
QPushButton#3DOptionStatusBarButton {
|
||||
color: #A5A5A5;
|
||||
font-weight: bold;
|
||||
border: 1px solid transparent;
|
||||
background-color: transparent;
|
||||
padding: 0px 3px 0px 3px;
|
||||
text-align: center;
|
||||
min-width: 60px;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
QPushButton#3DOptionStatusBarButton:hover {
|
||||
border: 1px solid #76797C;
|
||||
}
|
||||
|
|
|
@ -55,14 +55,16 @@ const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> Config:
|
|||
// This must be in alphabetical order according to action name as it must have the same order as
|
||||
// UISetting::values.shortcuts, which is alphabetically ordered.
|
||||
// clang-format off
|
||||
const std::array<UISettings::Shortcut, 24> Config::default_hotkeys {{
|
||||
const std::array<UISettings::Shortcut, 27> Config::default_hotkeys {{
|
||||
{QStringLiteral("Advance Frame"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), Qt::WidgetWithChildrenShortcut}},
|
||||
{QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Decrease 3D Factor"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+-"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Decrease Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("-"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Exit Citra"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Q"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Exit Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("Esc"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("F11"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Increase 3D Factor"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl++"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Increase Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("+"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Load Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), Qt::WidgetWithChildrenShortcut}},
|
||||
{QStringLiteral("Load File"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+O"), Qt::WidgetWithChildrenShortcut}},
|
||||
|
@ -74,6 +76,7 @@ const std::array<UISettings::Shortcut, 24> Config::default_hotkeys {{
|
|||
{QStringLiteral("Save to Oldest Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+C"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Swap Screens"), QStringLiteral("Main Window"), {QStringLiteral("F9"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Toggle 3D"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+3"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Per-Game Speed"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Toggle Frame Advancing"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+A"), Qt::ApplicationShortcut}},
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
|
||||
static const std::array<int, Settings::NativeButton::NumButtons> default_buttons;
|
||||
static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs;
|
||||
static const std::array<UISettings::Shortcut, 24> default_hotkeys;
|
||||
static const std::array<UISettings::Shortcut, 27> default_hotkeys;
|
||||
|
||||
private:
|
||||
void Initialize(const std::string& config_name);
|
||||
|
|
|
@ -117,6 +117,7 @@ __declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;
|
|||
#endif
|
||||
|
||||
constexpr int default_mouse_timeout = 2500;
|
||||
constexpr int num_options_3d = 5;
|
||||
|
||||
/**
|
||||
* "Callouts" are one-time instructional messages shown to the user. In the config settings, there
|
||||
|
@ -202,6 +203,7 @@ GMainWindow::GMainWindow()
|
|||
|
||||
ConnectMenuEvents();
|
||||
ConnectWidgetEvents();
|
||||
Connect3DStateEvents();
|
||||
|
||||
LOG_INFO(Frontend, "Citra Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch,
|
||||
Common::g_scm_desc);
|
||||
|
@ -299,7 +301,6 @@ void GMainWindow::InitializeWidgets() {
|
|||
// Create status bar
|
||||
message_label = new QLabel();
|
||||
// Configured separately for left alignment
|
||||
message_label->setVisible(false);
|
||||
message_label->setFrameStyle(QFrame::NoFrame);
|
||||
message_label->setContentsMargins(4, 0, 4, 0);
|
||||
message_label->setAlignment(Qt::AlignLeft);
|
||||
|
@ -324,10 +325,26 @@ void GMainWindow::InitializeWidgets() {
|
|||
label->setVisible(false);
|
||||
label->setFrameStyle(QFrame::NoFrame);
|
||||
label->setContentsMargins(4, 0, 4, 0);
|
||||
statusBar()->addPermanentWidget(label, 0);
|
||||
statusBar()->addPermanentWidget(label);
|
||||
}
|
||||
statusBar()->addPermanentWidget(multiplayer_state->GetStatusText(), 0);
|
||||
statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon(), 0);
|
||||
|
||||
option_3d_button = new QPushButton();
|
||||
option_3d_button->setObjectName(QStringLiteral("3DOptionStatusBarButton"));
|
||||
option_3d_button->setFocusPolicy(Qt::NoFocus);
|
||||
option_3d_button->setToolTip(tr("Indicates the current 3D setting. Click to toggle."));
|
||||
|
||||
factor_3d_slider = new QSlider(Qt::Orientation::Horizontal, this);
|
||||
factor_3d_slider->setStyleSheet(QStringLiteral("QSlider { padding: 4px; }"));
|
||||
factor_3d_slider->setToolTip(tr("Current 3D factor while 3D is enabled."));
|
||||
factor_3d_slider->setRange(0, 100);
|
||||
|
||||
Update3DState();
|
||||
statusBar()->insertPermanentWidget(0, option_3d_button);
|
||||
statusBar()->insertPermanentWidget(1, factor_3d_slider);
|
||||
|
||||
statusBar()->addPermanentWidget(multiplayer_state->GetStatusText());
|
||||
statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon());
|
||||
|
||||
statusBar()->setVisible(true);
|
||||
|
||||
// Removes an ugly inner border from the status bar widgets under Linux
|
||||
|
@ -575,6 +592,35 @@ void GMainWindow::InitializeHotkeys() {
|
|||
});
|
||||
connect_shortcut(QStringLiteral("Mute Audio"),
|
||||
[] { Settings::values.audio_muted = !Settings::values.audio_muted; });
|
||||
|
||||
connect_shortcut(QStringLiteral("Toggle 3D"), &GMainWindow::Toggle3D);
|
||||
|
||||
// We use "static" here in order to avoid capturing by lambda due to a MSVC bug, which makes the
|
||||
// variable hold a garbage value after this function exits
|
||||
static constexpr u16 FACTOR_3D_STEP = 5;
|
||||
connect_shortcut(QStringLiteral("Decrease 3D Factor"), [this] {
|
||||
const auto factor_3d = Settings::values.factor_3d.GetValue();
|
||||
if (factor_3d > 0) {
|
||||
if (factor_3d % FACTOR_3D_STEP != 0) {
|
||||
Settings::values.factor_3d = factor_3d - (factor_3d % FACTOR_3D_STEP);
|
||||
} else {
|
||||
Settings::values.factor_3d = factor_3d - FACTOR_3D_STEP;
|
||||
}
|
||||
UpdateStatusBar();
|
||||
}
|
||||
});
|
||||
connect_shortcut(QStringLiteral("Increase 3D Factor"), [this] {
|
||||
const auto factor_3d = Settings::values.factor_3d.GetValue();
|
||||
if (factor_3d < 100) {
|
||||
if (factor_3d % FACTOR_3D_STEP != 0) {
|
||||
Settings::values.factor_3d =
|
||||
factor_3d + FACTOR_3D_STEP - (factor_3d % FACTOR_3D_STEP);
|
||||
} else {
|
||||
Settings::values.factor_3d = factor_3d + FACTOR_3D_STEP;
|
||||
}
|
||||
UpdateStatusBar();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void GMainWindow::ShowUpdaterWidgets() {
|
||||
|
@ -805,6 +851,12 @@ void GMainWindow::UpdateMenuState() {
|
|||
}
|
||||
}
|
||||
|
||||
void GMainWindow::Connect3DStateEvents() {
|
||||
connect(option_3d_button, &QPushButton::clicked, this, &GMainWindow::Toggle3D);
|
||||
connect(factor_3d_slider, qOverload<int>(&QSlider::valueChanged), this,
|
||||
[](int value) { Settings::values.factor_3d = value; });
|
||||
}
|
||||
|
||||
void GMainWindow::OnDisplayTitleBars(bool show) {
|
||||
QList<QDockWidget*> widgets = findChildren<QDockWidget*>();
|
||||
|
||||
|
@ -1219,7 +1271,6 @@ void GMainWindow::ShutdownGame() {
|
|||
|
||||
// Disable status bar updates
|
||||
status_bar_update_timer.stop();
|
||||
message_label->setVisible(false);
|
||||
message_label_used_for_movie = false;
|
||||
emu_speed_label->setVisible(false);
|
||||
game_fps_label->setVisible(false);
|
||||
|
@ -1900,6 +1951,7 @@ void GMainWindow::OnConfigure() {
|
|||
setMouseTracking(false);
|
||||
}
|
||||
UpdateSecondaryWindowVisibility();
|
||||
Update3DState();
|
||||
} else {
|
||||
Settings::values.input_profiles = old_input_profiles;
|
||||
Settings::values.touch_from_button_maps = old_touch_from_button_maps;
|
||||
|
@ -2160,22 +2212,18 @@ void GMainWindow::UpdateStatusBar() {
|
|||
const auto play_mode = Core::Movie::GetInstance().GetPlayMode();
|
||||
if (play_mode == Core::Movie::PlayMode::Recording) {
|
||||
message_label->setText(tr("Recording %1").arg(current));
|
||||
message_label->setVisible(true);
|
||||
message_label_used_for_movie = true;
|
||||
ui->action_Save_Movie->setEnabled(true);
|
||||
} else if (play_mode == Core::Movie::PlayMode::Playing) {
|
||||
message_label->setText(tr("Playing %1 / %2").arg(current, total));
|
||||
message_label->setVisible(true);
|
||||
message_label_used_for_movie = true;
|
||||
ui->action_Save_Movie->setEnabled(false);
|
||||
} else if (play_mode == Core::Movie::PlayMode::MovieFinished) {
|
||||
message_label->setText(tr("Movie Finished"));
|
||||
message_label->setVisible(true);
|
||||
message_label_used_for_movie = true;
|
||||
ui->action_Save_Movie->setEnabled(false);
|
||||
} else if (message_label_used_for_movie) { // Clear the label if movie was just closed
|
||||
message_label->setText(QString{});
|
||||
message_label->setVisible(false);
|
||||
message_label_used_for_movie = false;
|
||||
ui->action_Save_Movie->setEnabled(false);
|
||||
}
|
||||
|
@ -2197,6 +2245,18 @@ void GMainWindow::UpdateStatusBar() {
|
|||
emu_frametime_label->setVisible(true);
|
||||
}
|
||||
|
||||
void GMainWindow::Update3DState() {
|
||||
static const std::array options_3d = {tr("Off"), tr("Side by Side"), tr("Anaglyph"),
|
||||
tr("Interlaced"), tr("Reverse Interlaced")};
|
||||
|
||||
option_3d_button->setText(
|
||||
tr("3D: %1").arg(options_3d[static_cast<int>(Settings::values.render_3d.GetValue())]));
|
||||
|
||||
factor_3d_slider->setValue(Settings::values.factor_3d.GetValue());
|
||||
factor_3d_slider->setVisible(Settings::values.render_3d.GetValue() !=
|
||||
Settings::StereoRenderOption::Off);
|
||||
}
|
||||
|
||||
void GMainWindow::HideMouseCursor() {
|
||||
if (emu_thread == nullptr || !UISettings::values.hide_mouse.GetValue()) {
|
||||
mouse_hide_timer.stop();
|
||||
|
@ -2299,7 +2359,6 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
|
|||
if (emu_thread) {
|
||||
emu_thread->SetRunning(true);
|
||||
message_label->setText(status_message);
|
||||
message_label->setVisible(true);
|
||||
message_label_used_for_movie = false;
|
||||
}
|
||||
}
|
||||
|
@ -2309,6 +2368,12 @@ void GMainWindow::OnMenuAboutCitra() {
|
|||
about.exec();
|
||||
}
|
||||
|
||||
void GMainWindow::Toggle3D() {
|
||||
Settings::values.render_3d = static_cast<Settings::StereoRenderOption>(
|
||||
(static_cast<int>(Settings::values.render_3d.GetValue()) + 1) % num_options_3d);
|
||||
Update3DState();
|
||||
}
|
||||
|
||||
bool GMainWindow::ConfirmClose() {
|
||||
if (emu_thread == nullptr || !UISettings::values.confirm_before_closing)
|
||||
return true;
|
||||
|
@ -2418,8 +2483,18 @@ void GMainWindow::UpdateUITheme() {
|
|||
QStringList theme_paths(default_theme_paths);
|
||||
|
||||
if (is_default_theme || current_theme.isEmpty()) {
|
||||
qApp->setStyleSheet({});
|
||||
setStyleSheet({});
|
||||
const QString theme_uri(QStringLiteral(":default/style.qss"));
|
||||
QFile f(theme_uri);
|
||||
if (f.open(QFile::ReadOnly | QFile::Text)) {
|
||||
QTextStream ts(&f);
|
||||
qApp->setStyleSheet(ts.readAll());
|
||||
setStyleSheet(ts.readAll());
|
||||
} else {
|
||||
LOG_ERROR(Frontend,
|
||||
"Unable to open default stylesheet, falling back to empty stylesheet");
|
||||
qApp->setStyleSheet({});
|
||||
setStyleSheet({});
|
||||
}
|
||||
theme_paths.append(default_icons);
|
||||
QIcon::setThemeName(default_icons);
|
||||
} else {
|
||||
|
|
|
@ -40,6 +40,8 @@ template <typename>
|
|||
class QFutureWatcher;
|
||||
class QLabel;
|
||||
class QProgressBar;
|
||||
class QPushButton;
|
||||
class QSlider;
|
||||
class RegistersWidget;
|
||||
class Updater;
|
||||
class WaitTreeWidget;
|
||||
|
@ -118,6 +120,7 @@ private:
|
|||
void RestoreUIState();
|
||||
|
||||
void ConnectWidgetEvents();
|
||||
void Connect3DStateEvents();
|
||||
void ConnectMenuEvents();
|
||||
void UpdateMenuState();
|
||||
|
||||
|
@ -225,6 +228,7 @@ private slots:
|
|||
void OnStopVideoDumping();
|
||||
#endif
|
||||
void OnCoreError(Core::System::ResultStatus, std::string);
|
||||
void Toggle3D();
|
||||
/// Called whenever a user selects Help->About Citra
|
||||
void OnMenuAboutCitra();
|
||||
void OnUpdateFound(bool found, bool error);
|
||||
|
@ -236,6 +240,7 @@ private slots:
|
|||
private:
|
||||
Q_INVOKABLE void OnMoviePlaybackCompleted();
|
||||
void UpdateStatusBar();
|
||||
void Update3DState();
|
||||
void LoadTranslation();
|
||||
void UpdateWindowTitle();
|
||||
void UpdateUISettings();
|
||||
|
@ -259,6 +264,8 @@ private:
|
|||
QLabel* emu_speed_label = nullptr;
|
||||
QLabel* game_fps_label = nullptr;
|
||||
QLabel* emu_frametime_label = nullptr;
|
||||
QPushButton* option_3d_button = nullptr;
|
||||
QSlider* factor_3d_slider = nullptr;
|
||||
QTimer status_bar_update_timer;
|
||||
bool message_label_used_for_movie = false;
|
||||
|
||||
|
|
Loading…
Reference in a new issue