[desktop] Add icon-only mode to grid and improve design (#3485)
- Move Game Icon Size to the main toolbar. It's cleaner that way - Add a "Show Game Name" toggle that does as it says. Disabling it basically creates an "icons-only" mode. Useful for controller-only nav with big icons (TODO: maybe make a 192 size?) - Fixed a crash with controller nav. Oops - Rounded corners of the game icon in grid mode - Fixed the scroll bar creating extra clamping range on the grid icons - Item can be deselected if user clicks on the blank space outside of the view As a bonus fixed a crash on mod manager Future TODOs for design: - [ ] Row 1 type. Not sure what to do here tbh. - [ ] Move around game list settings in configure_ui to make it clear that nothing there affects the grid view. - [ ] 192x192 size? 256 feels too big on my 1440p screen whereas 128 feels too small. - Set text space as a function of fontMetrics. Signed-off-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3485 Reviewed-by: DraVee <dravee@eden-emu.dev> Reviewed-by: Maufeat <sahyno1996@gmail.com>
This commit is contained in:
parent
e10f55d9db
commit
ca9f2d43be
|
|
@ -18,7 +18,7 @@ std::vector<std::filesystem::path> GetModFolder(const std::string& root) {
|
||||||
|
|
||||||
auto callback = [&paths](const std::filesystem::directory_entry& entry) -> bool {
|
auto callback = [&paths](const std::filesystem::directory_entry& entry) -> bool {
|
||||||
const auto name = entry.path().filename().string();
|
const auto name = entry.path().filename().string();
|
||||||
static constexpr const std::array<std::string, 5> valid_names = {"exefs",
|
static const std::array<std::string, 5> valid_names = {"exefs",
|
||||||
"romfs"
|
"romfs"
|
||||||
"romfs_ext",
|
"romfs_ext",
|
||||||
"cheats", "romfslite"};
|
"cheats", "romfslite"};
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,7 @@ struct Values {
|
||||||
Setting<u8> row_1_text_id{linkage, 3, "row_1_text_id", Category::UiGameList};
|
Setting<u8> row_1_text_id{linkage, 3, "row_1_text_id", Category::UiGameList};
|
||||||
Setting<u8> row_2_text_id{linkage, 2, "row_2_text_id", Category::UiGameList};
|
Setting<u8> row_2_text_id{linkage, 2, "row_2_text_id", Category::UiGameList};
|
||||||
Setting<Settings::GameListMode> game_list_mode{linkage, Settings::GameListMode::TreeView, "game_list_mode", Category::UiGameList};
|
Setting<Settings::GameListMode> game_list_mode{linkage, Settings::GameListMode::TreeView, "game_list_mode", Category::UiGameList};
|
||||||
|
Setting<bool> show_game_name{linkage, true, "show_game_name", Category::UiGameList};
|
||||||
|
|
||||||
std::atomic_bool is_game_list_reload_pending{false};
|
std::atomic_bool is_game_list_reload_pending{false};
|
||||||
Setting<bool> cache_game_list{linkage, true, "cache_game_list", Category::UiGameList};
|
Setting<bool> cache_game_list{linkage, true, "cache_game_list", Category::UiGameList};
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,8 @@ QStringList GetModFolders(const QString& root, const QString& fallbackName) {
|
||||||
QString name = QtCommon::Frontend::GetTextInput(
|
QString name = QtCommon::Frontend::GetTextInput(
|
||||||
tr("Mod Name"), tr("What should this mod be called?"), default_name);
|
tr("Mod Name"), tr("What should this mod be called?"), default_name);
|
||||||
|
|
||||||
|
if (name.isEmpty()) return {};
|
||||||
|
|
||||||
// if std_path is empty, frontend_common could not determine mod type and/or name.
|
// if std_path is empty, frontend_common could not determine mod type and/or name.
|
||||||
// so we have to prompt the user and set up the structure ourselves
|
// so we have to prompt the user and set up the structure ourselves
|
||||||
if (paths.empty()) {
|
if (paths.empty()) {
|
||||||
|
|
|
||||||
|
|
@ -161,14 +161,14 @@ void ConfigurePerGameAddons::InstallMods(const QStringList& mods) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigurePerGameAddons::InstallModPath(const QString& path) {
|
void ConfigurePerGameAddons::InstallModPath(const QString& path, const QString &fallbackName) {
|
||||||
const auto mods = QtCommon::Mod::GetModFolders(path, {});
|
const auto mods = QtCommon::Mod::GetModFolders(path, fallbackName);
|
||||||
|
|
||||||
if (mods.size() > 1) {
|
if (mods.size() > 1) {
|
||||||
ModSelectDialog* dialog = new ModSelectDialog(mods, this);
|
ModSelectDialog* dialog = new ModSelectDialog(mods, this);
|
||||||
connect(dialog, &ModSelectDialog::modsSelected, this, &ConfigurePerGameAddons::InstallMods);
|
connect(dialog, &ModSelectDialog::modsSelected, this, &ConfigurePerGameAddons::InstallMods);
|
||||||
dialog->show();
|
dialog->show();
|
||||||
} else {
|
} else if (!mods.empty()) {
|
||||||
InstallMods(mods);
|
InstallMods(mods);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -194,7 +194,7 @@ void ConfigurePerGameAddons::InstallModZip() {
|
||||||
|
|
||||||
const QString extracted = QtCommon::Mod::ExtractMod(path);
|
const QString extracted = QtCommon::Mod::ExtractMod(path);
|
||||||
if (!extracted.isEmpty())
|
if (!extracted.isEmpty())
|
||||||
InstallModPath(extracted);
|
InstallModPath(extracted, QFileInfo(path).baseName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigurePerGameAddons::changeEvent(QEvent* event) {
|
void ConfigurePerGameAddons::changeEvent(QEvent* event) {
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ public:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void InstallMods(const QStringList &mods);
|
void InstallMods(const QStringList &mods);
|
||||||
void InstallModPath(const QString& path);
|
void InstallModPath(const QString& path, const QString& fallbackName = {});
|
||||||
|
|
||||||
void InstallModFolder();
|
void InstallModFolder();
|
||||||
void InstallModZip();
|
void InstallModZip();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "yuzu/configuration/configure_ui.h"
|
#include "yuzu/configuration/configure_ui.h"
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
|
@ -21,7 +20,6 @@
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
#include "common/logging/log.h"
|
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/settings_enums.h"
|
#include "common/settings_enums.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
|
@ -32,13 +30,6 @@
|
||||||
#include "qt_common/config/uisettings.h"
|
#include "qt_common/config/uisettings.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr std::array default_game_icon_sizes{
|
|
||||||
std::make_pair(0, QT_TRANSLATE_NOOP("ConfigureUI", "None")),
|
|
||||||
std::make_pair(32, QT_TRANSLATE_NOOP("ConfigureUI", "Small (32x32)")),
|
|
||||||
std::make_pair(64, QT_TRANSLATE_NOOP("ConfigureUI", "Standard (64x64)")),
|
|
||||||
std::make_pair(128, QT_TRANSLATE_NOOP("ConfigureUI", "Large (128x128)")),
|
|
||||||
std::make_pair(256, QT_TRANSLATE_NOOP("ConfigureUI", "Full Size (256x256)")),
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr std::array default_folder_icon_sizes{
|
constexpr std::array default_folder_icon_sizes{
|
||||||
std::make_pair(0, QT_TRANSLATE_NOOP("ConfigureUI", "None")),
|
std::make_pair(0, QT_TRANSLATE_NOOP("ConfigureUI", "None")),
|
||||||
|
|
@ -57,10 +48,6 @@ constexpr std::array row_text_names{
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
QString GetTranslatedGameIconSize(size_t index) {
|
|
||||||
return QCoreApplication::translate("ConfigureUI", default_game_icon_sizes[index].second);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString GetTranslatedFolderIconSize(size_t index) {
|
QString GetTranslatedFolderIconSize(size_t index) {
|
||||||
return QCoreApplication::translate("ConfigureUI", default_folder_icon_sizes[index].second);
|
return QCoreApplication::translate("ConfigureUI", default_folder_icon_sizes[index].second);
|
||||||
}
|
}
|
||||||
|
|
@ -127,8 +114,6 @@ ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent)
|
||||||
connect(ui->show_types, &QCheckBox::STATE_CHANGED, this, &ConfigureUi::RequestGameListUpdate);
|
connect(ui->show_types, &QCheckBox::STATE_CHANGED, this, &ConfigureUi::RequestGameListUpdate);
|
||||||
connect(ui->show_play_time, &QCheckBox::STATE_CHANGED, this,
|
connect(ui->show_play_time, &QCheckBox::STATE_CHANGED, this,
|
||||||
&ConfigureUi::RequestGameListUpdate);
|
&ConfigureUi::RequestGameListUpdate);
|
||||||
connect(ui->game_icon_size_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
|
||||||
&ConfigureUi::RequestGameListUpdate);
|
|
||||||
connect(ui->folder_icon_size_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
connect(ui->folder_icon_size_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||||
this, &ConfigureUi::RequestGameListUpdate);
|
this, &ConfigureUi::RequestGameListUpdate);
|
||||||
connect(ui->row_1_text_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
connect(ui->row_1_text_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||||
|
|
@ -172,7 +157,6 @@ void ConfigureUi::ApplyConfiguration() {
|
||||||
UISettings::values.show_size = ui->show_size->isChecked();
|
UISettings::values.show_size = ui->show_size->isChecked();
|
||||||
UISettings::values.show_types = ui->show_types->isChecked();
|
UISettings::values.show_types = ui->show_types->isChecked();
|
||||||
UISettings::values.show_play_time = ui->show_play_time->isChecked();
|
UISettings::values.show_play_time = ui->show_play_time->isChecked();
|
||||||
UISettings::values.game_icon_size = ui->game_icon_size_combobox->currentData().toUInt();
|
|
||||||
UISettings::values.folder_icon_size = ui->folder_icon_size_combobox->currentData().toUInt();
|
UISettings::values.folder_icon_size = ui->folder_icon_size_combobox->currentData().toUInt();
|
||||||
UISettings::values.row_1_text_id = ui->row_1_text_combobox->currentData().toUInt();
|
UISettings::values.row_1_text_id = ui->row_1_text_combobox->currentData().toUInt();
|
||||||
UISettings::values.row_2_text_id = ui->row_2_text_combobox->currentData().toUInt();
|
UISettings::values.row_2_text_id = ui->row_2_text_combobox->currentData().toUInt();
|
||||||
|
|
@ -202,8 +186,6 @@ void ConfigureUi::SetConfiguration() {
|
||||||
ui->show_size->setChecked(UISettings::values.show_size.GetValue());
|
ui->show_size->setChecked(UISettings::values.show_size.GetValue());
|
||||||
ui->show_types->setChecked(UISettings::values.show_types.GetValue());
|
ui->show_types->setChecked(UISettings::values.show_types.GetValue());
|
||||||
ui->show_play_time->setChecked(UISettings::values.show_play_time.GetValue());
|
ui->show_play_time->setChecked(UISettings::values.show_play_time.GetValue());
|
||||||
ui->game_icon_size_combobox->setCurrentIndex(
|
|
||||||
ui->game_icon_size_combobox->findData(UISettings::values.game_icon_size.GetValue()));
|
|
||||||
ui->folder_icon_size_combobox->setCurrentIndex(
|
ui->folder_icon_size_combobox->setCurrentIndex(
|
||||||
ui->folder_icon_size_combobox->findData(UISettings::values.folder_icon_size.GetValue()));
|
ui->folder_icon_size_combobox->findData(UISettings::values.folder_icon_size.GetValue()));
|
||||||
|
|
||||||
|
|
@ -231,11 +213,6 @@ void ConfigureUi::changeEvent(QEvent* event) {
|
||||||
void ConfigureUi::RetranslateUI() {
|
void ConfigureUi::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
|
|
||||||
for (int i = 0; i < ui->game_icon_size_combobox->count(); i++) {
|
|
||||||
ui->game_icon_size_combobox->setItemText(i,
|
|
||||||
GetTranslatedGameIconSize(static_cast<size_t>(i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < ui->folder_icon_size_combobox->count(); i++) {
|
for (int i = 0; i < ui->folder_icon_size_combobox->count(); i++) {
|
||||||
ui->folder_icon_size_combobox->setItemText(
|
ui->folder_icon_size_combobox->setItemText(
|
||||||
i, GetTranslatedFolderIconSize(static_cast<size_t>(i)));
|
i, GetTranslatedFolderIconSize(static_cast<size_t>(i)));
|
||||||
|
|
@ -270,10 +247,6 @@ void ConfigureUi::InitializeLanguageComboBox() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureUi::InitializeIconSizeComboBox() {
|
void ConfigureUi::InitializeIconSizeComboBox() {
|
||||||
for (size_t i = 0; i < default_game_icon_sizes.size(); i++) {
|
|
||||||
const auto size = default_game_icon_sizes[i].first;
|
|
||||||
ui->game_icon_size_combobox->addItem(GetTranslatedGameIconSize(i), size);
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < default_folder_icon_sizes.size(); i++) {
|
for (size_t i = 0; i < default_folder_icon_sizes.size(); i++) {
|
||||||
const auto size = default_folder_icon_sizes[i].first;
|
const auto size = default_folder_icon_sizes[i].first;
|
||||||
ui->folder_icon_size_combobox->addItem(GetTranslatedFolderIconSize(i), size);
|
ui->folder_icon_size_combobox->addItem(GetTranslatedFolderIconSize(i), size);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>363</width>
|
<width>363</width>
|
||||||
<height>603</height>
|
<height>613</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
|
@ -111,20 +111,6 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="game_icon_size_qhbox_layout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="game_icon_size_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Game Icon Size:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="game_icon_size_combobox"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="folder_icon_size_qhbox_layout_2">
|
<layout class="QHBoxLayout" name="folder_icon_size_qhbox_layout_2">
|
||||||
<item>
|
<item>
|
||||||
|
|
@ -221,7 +207,7 @@
|
||||||
<string>TextLabel</string>
|
<string>TextLabel</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -251,7 +237,7 @@
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QPainterPath>
|
||||||
#include "game_card.h"
|
#include "game_card.h"
|
||||||
#include "qt_common/config/uisettings.h"
|
#include "qt_common/config/uisettings.h"
|
||||||
|
|
||||||
|
|
@ -18,7 +19,7 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option,
|
||||||
painter->setRenderHint(QPainter::Antialiasing);
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
// padding
|
// padding
|
||||||
QRect cardRect = option.rect.adjusted(4, 4, -4, -4);
|
QRect cardRect = option.rect.adjusted(4 + m_padding / 2, 4, -4 - m_padding / 2, -4);
|
||||||
|
|
||||||
// colors
|
// colors
|
||||||
QPalette palette = option.palette;
|
QPalette palette = option.palette;
|
||||||
|
|
@ -32,7 +33,7 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option,
|
||||||
borderColor = palette.highlight().color().lighter(150);
|
borderColor = palette.highlight().color().lighter(150);
|
||||||
textColor = palette.highlightedText().color();
|
textColor = palette.highlightedText().color();
|
||||||
} else if (option.state & QStyle::State_MouseOver) {
|
} else if (option.state & QStyle::State_MouseOver) {
|
||||||
backgroundColor = backgroundColor.lighter(110);
|
backgroundColor = backgroundColor.lighter(120);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bg
|
// bg
|
||||||
|
|
@ -40,7 +41,7 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option,
|
||||||
painter->setPen(QPen(borderColor, 1));
|
painter->setPen(QPen(borderColor, 1));
|
||||||
painter->drawRoundedRect(cardRect, 10, 10);
|
painter->drawRoundedRect(cardRect, 10, 10);
|
||||||
|
|
||||||
static constexpr const int padding = 10;
|
static constexpr const int padding = 8;
|
||||||
|
|
||||||
// icon
|
// icon
|
||||||
int _iconsize = UISettings::values.game_icon_size.GetValue();
|
int _iconsize = UISettings::values.game_icon_size.GetValue();
|
||||||
|
|
@ -58,7 +59,18 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option,
|
||||||
iconRect = QRect(x, y, scaledSize.width(), scaledSize.height());
|
iconRect = QRect(x, y, scaledSize.width(), scaledSize.height());
|
||||||
|
|
||||||
painter->setRenderHint(QPainter::SmoothPixmapTransform, true);
|
painter->setRenderHint(QPainter::SmoothPixmapTransform, true);
|
||||||
|
|
||||||
|
// Put this in a separate thing on the painter stack to prevent clipping the text.
|
||||||
|
painter->save();
|
||||||
|
|
||||||
|
// round image edges
|
||||||
|
QPainterPath path;
|
||||||
|
path.addRoundedRect(iconRect, 10, 10);
|
||||||
|
painter->setClipPath(path);
|
||||||
|
|
||||||
painter->drawPixmap(iconRect, iconPixmap);
|
painter->drawPixmap(iconRect, iconPixmap);
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
} else {
|
} else {
|
||||||
// if there is no icon just draw a blank rect
|
// if there is no icon just draw a blank rect
|
||||||
iconRect = QRect(cardRect.left() + padding,
|
iconRect = QRect(cardRect.left() + padding,
|
||||||
|
|
@ -66,6 +78,7 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option,
|
||||||
_iconsize, _iconsize);
|
_iconsize, _iconsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (UISettings::values.show_game_name.GetValue()) {
|
||||||
// if "none" is selected, pretend there's a
|
// if "none" is selected, pretend there's a
|
||||||
_iconsize = _iconsize ? _iconsize : 96;
|
_iconsize = _iconsize ? _iconsize : 96;
|
||||||
|
|
||||||
|
|
@ -91,6 +104,7 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option,
|
||||||
painter->setFont(font);
|
painter->setFont(font);
|
||||||
|
|
||||||
painter->drawText(textRect, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, title);
|
painter->drawText(textRect, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, title);
|
||||||
|
}
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
@ -99,6 +113,7 @@ QSize GameCard::sizeHint(const QStyleOptionViewItem& option, const QModelIndex&
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameCard::setSize(const QSize& newSize) {
|
void GameCard::setSize(const QSize& newSize, const int padding) {
|
||||||
m_size = newSize;
|
m_size = newSize;
|
||||||
|
m_padding = padding;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,9 @@ public:
|
||||||
|
|
||||||
QSize sizeHint(const QStyleOptionViewItem &option,
|
QSize sizeHint(const QStyleOptionViewItem &option,
|
||||||
const QModelIndex &index) const override;
|
const QModelIndex &index) const override;
|
||||||
void setSize(const QSize& newSize);
|
void setSize(const QSize& newSize, const int padding);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSize m_size;
|
QSize m_size;
|
||||||
|
int m_padding;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include <QAbstractItemView>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
|
@ -13,13 +14,12 @@
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QScroller>
|
#include <QScroller>
|
||||||
|
#include <QScrollerProperties>
|
||||||
#include <QThreadPool>
|
#include <QThreadPool>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
#include <QVariantAnimation>
|
#include <QVariantAnimation>
|
||||||
#include <fmt/ranges.h>
|
#include <fmt/ranges.h>
|
||||||
#include <QAbstractItemView>
|
#include <qnamespace.h>
|
||||||
#include <QScroller>
|
|
||||||
#include <QScrollerProperties>
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include "core/file_sys/registered_cache.h"
|
#include "core/file_sys/registered_cache.h"
|
||||||
#include "game/game_card.h"
|
#include "game/game_card.h"
|
||||||
#include "qt_common/config/uisettings.h"
|
#include "qt_common/config/uisettings.h"
|
||||||
|
#include "qt_common/qt_common.h"
|
||||||
#include "qt_common/util/game.h"
|
#include "qt_common/util/game.h"
|
||||||
#include "yuzu/compatibility_list.h"
|
#include "yuzu/compatibility_list.h"
|
||||||
#include "yuzu/game/game_list.h"
|
#include "yuzu/game/game_list.h"
|
||||||
|
|
@ -35,7 +36,6 @@
|
||||||
#include "yuzu/game/game_list_worker.h"
|
#include "yuzu/game/game_list_worker.h"
|
||||||
#include "yuzu/main_window.h"
|
#include "yuzu/main_window.h"
|
||||||
#include "yuzu/util/controller_navigation.h"
|
#include "yuzu/util/controller_navigation.h"
|
||||||
#include "qt_common/qt_common.h"
|
|
||||||
|
|
||||||
GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist_, QObject* parent)
|
GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist_, QObject* parent)
|
||||||
: QObject(parent), gamelist{gamelist_} {}
|
: QObject(parent), gamelist{gamelist_} {}
|
||||||
|
|
@ -393,16 +393,21 @@ GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvid
|
||||||
tree_view->setStyleSheet(QStringLiteral("QTreeView{ border: none; }"));
|
tree_view->setStyleSheet(QStringLiteral("QTreeView{ border: none; }"));
|
||||||
|
|
||||||
// list view setup
|
// list view setup
|
||||||
list_view->setViewMode(QListView::IconMode);
|
list_view->setViewMode(QListView::ListMode);
|
||||||
list_view->setResizeMode(QListView::Adjust);
|
list_view->setResizeMode(QListView::Fixed);
|
||||||
list_view->setUniformItemSizes(false);
|
list_view->setUniformItemSizes(true);
|
||||||
list_view->setSelectionMode(QAbstractItemView::SingleSelection);
|
list_view->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
list_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
list_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||||
list_view->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
list_view->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||||
|
|
||||||
|
// Forcefully disable scroll bar, prevents thing where game list items
|
||||||
|
// will start clamping prematurely.
|
||||||
|
list_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
|
||||||
list_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
list_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
list_view->setContextMenuPolicy(Qt::CustomContextMenu);
|
list_view->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
list_view->setGridSize(QSize(140, 160));
|
list_view->setGridSize(QSize(140, 160));
|
||||||
m_gameCard->setSize(list_view->gridSize());
|
m_gameCard->setSize(list_view->gridSize(), 0);
|
||||||
|
|
||||||
list_view->setSpacing(10);
|
list_view->setSpacing(10);
|
||||||
list_view->setWordWrap(true);
|
list_view->setWordWrap(true);
|
||||||
|
|
@ -438,8 +443,8 @@ GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvid
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier);
|
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier);
|
||||||
QCoreApplication::postEvent(tree_view, event);
|
|
||||||
QCoreApplication::postEvent(list_view, event);
|
QCoreApplication::postEvent(m_currentView, event);
|
||||||
});
|
});
|
||||||
|
|
||||||
// We must register all custom types with the Qt Automoc system so that we are able to use
|
// We must register all custom types with the Qt Automoc system so that we are able to use
|
||||||
|
|
@ -488,11 +493,7 @@ void GameList::ResetViewMode() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_isTreeMode != newTreeMode) {
|
|
||||||
m_isTreeMode = newTreeMode;
|
|
||||||
|
|
||||||
auto view = m_currentView->viewport();
|
auto view = m_currentView->viewport();
|
||||||
|
|
||||||
view->installEventFilter(this);
|
view->installEventFilter(this);
|
||||||
|
|
||||||
// touch gestures
|
// touch gestures
|
||||||
|
|
@ -510,6 +511,9 @@ void GameList::ResetViewMode() {
|
||||||
QScrollerProperties::OvershootAlwaysOff);
|
QScrollerProperties::OvershootAlwaysOff);
|
||||||
scroller->setScrollerProperties(props);
|
scroller->setScrollerProperties(props);
|
||||||
|
|
||||||
|
if (m_isTreeMode != newTreeMode) {
|
||||||
|
m_isTreeMode = newTreeMode;
|
||||||
|
|
||||||
RefreshGameDirectory();
|
RefreshGameDirectory();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1007,30 +1011,55 @@ void GameList::UpdateIconSize() {
|
||||||
// Update sizes and stuff for the list view
|
// Update sizes and stuff for the list view
|
||||||
const u32 icon_size = UISettings::values.game_icon_size.GetValue();
|
const u32 icon_size = UISettings::values.game_icon_size.GetValue();
|
||||||
|
|
||||||
// the scaling on the card is kinda abysmal.
|
|
||||||
// TODO(crueter): refactor
|
|
||||||
int heightMargin = 0;
|
int heightMargin = 0;
|
||||||
int widthMargin = 80;
|
int widthMargin = 80;
|
||||||
|
|
||||||
|
if (UISettings::values.show_game_name) {
|
||||||
|
// the scaling on the card is kinda abysmal.
|
||||||
|
// TODO(crueter): refactor
|
||||||
switch (icon_size) {
|
switch (icon_size) {
|
||||||
case 128:
|
case 128:
|
||||||
heightMargin = 70;
|
heightMargin = 65;
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
widthMargin = 120;
|
widthMargin = 120;
|
||||||
heightMargin = 120;
|
heightMargin = 120;
|
||||||
break;
|
break;
|
||||||
case 64:
|
case 64:
|
||||||
heightMargin = 80;
|
heightMargin = 77;
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
case 256:
|
case 256:
|
||||||
heightMargin = 81;
|
heightMargin = 81;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
widthMargin = 24;
|
||||||
|
heightMargin = 24;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(crueter): Auto size
|
// "auto" resize //
|
||||||
list_view->setGridSize(QSize(icon_size + widthMargin, icon_size + heightMargin));
|
const int view_width = list_view->viewport()->width();
|
||||||
m_gameCard->setSize(list_view->gridSize());
|
|
||||||
|
// Tiny space padding to prevent the list view from forcing its own resize operation.
|
||||||
|
const double spacing = 0.01;
|
||||||
|
const int min_item_width = icon_size + widthMargin;
|
||||||
|
|
||||||
|
// And now stretch it a bit to fill out remaining space.
|
||||||
|
// Not perfect but works well enough for now
|
||||||
|
int columns = std::max(1, view_width / min_item_width);
|
||||||
|
int stretched_width = (view_width - (spacing * (columns - 1))) / columns;
|
||||||
|
|
||||||
|
// only updates things if grid size is changed
|
||||||
|
QSize grid_size(stretched_width, icon_size + heightMargin);
|
||||||
|
if (list_view->gridSize() != grid_size) {
|
||||||
|
list_view->setUpdatesEnabled(false);
|
||||||
|
|
||||||
|
list_view->setGridSize(grid_size);
|
||||||
|
m_gameCard->setSize(grid_size, stretched_width - min_item_width);
|
||||||
|
|
||||||
|
list_view->setUpdatesEnabled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameList::PopulateAsync(QVector<UISettings::GameDir>& game_dirs) {
|
void GameList::PopulateAsync(QVector<UISettings::GameDir>& game_dirs) {
|
||||||
|
|
@ -1043,6 +1072,7 @@ void GameList::PopulateAsync(QVector<UISettings::GameDir>& game_dirs) {
|
||||||
tree_view->setColumnHidden(COLUMN_SIZE, !UISettings::values.show_size);
|
tree_view->setColumnHidden(COLUMN_SIZE, !UISettings::values.show_size);
|
||||||
tree_view->setColumnHidden(COLUMN_PLAY_TIME, !UISettings::values.show_play_time);
|
tree_view->setColumnHidden(COLUMN_PLAY_TIME, !UISettings::values.show_play_time);
|
||||||
|
|
||||||
|
if (!m_isTreeMode)
|
||||||
UpdateIconSize();
|
UpdateIconSize();
|
||||||
|
|
||||||
// Cancel any existing worker.
|
// Cancel any existing worker.
|
||||||
|
|
@ -1266,6 +1296,23 @@ bool GameList::eventFilter(QObject* obj, QEvent* event) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (obj == m_currentView->viewport() && event->type() == QEvent::MouseButtonPress) {
|
||||||
|
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||||
|
|
||||||
|
// if the user clicks outside of the list, deselect the current item.
|
||||||
|
QModelIndex index = m_currentView->indexAt(mouseEvent->pos());
|
||||||
|
if (!index.isValid()) {
|
||||||
|
m_currentView->selectionModel()->clearSelection();
|
||||||
|
m_currentView->setCurrentIndex(QModelIndex());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj == list_view->viewport() && event->type() == QEvent::Resize) {
|
||||||
|
UpdateIconSize();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return QWidget::eventFilter(obj, event);
|
return QWidget::eventFilter(obj, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,11 @@
|
||||||
<addaction name="action_Tree_View"/>
|
<addaction name="action_Tree_View"/>
|
||||||
<addaction name="action_Grid_View"/>
|
<addaction name="action_Grid_View"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuGame_Icon_Size">
|
||||||
|
<property name="title">
|
||||||
|
<string>Game &Icon Size</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
<action name="action_Reset_Window_Size_720">
|
<action name="action_Reset_Window_Size_720">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Reset Window Size to &720p</string>
|
<string>Reset Window Size to &720p</string>
|
||||||
|
|
@ -145,6 +150,8 @@
|
||||||
<addaction name="menu_Reset_Window_Size"/>
|
<addaction name="menu_Reset_Window_Size"/>
|
||||||
<addaction name="menu_View_Debugging"/>
|
<addaction name="menu_View_Debugging"/>
|
||||||
<addaction name="menu_Game_List_Mode"/>
|
<addaction name="menu_Game_List_Mode"/>
|
||||||
|
<addaction name="menuGame_Icon_Size"/>
|
||||||
|
<addaction name="action_Show_Game_Name"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menu_Multiplayer">
|
<widget class="QMenu" name="menu_Multiplayer">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
|
|
@ -586,6 +593,24 @@
|
||||||
<string>&Grid View</string>
|
<string>&Grid View</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionGame_Icon_Size">
|
||||||
|
<property name="text">
|
||||||
|
<string>Game Icon Size</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNone">
|
||||||
|
<property name="text">
|
||||||
|
<string>None</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="action_Show_Game_Name">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Show Game &Name</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="yuzu.qrc"/>
|
<include location="yuzu.qrc"/>
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@
|
||||||
#include <QStatusBar>
|
#include <QStatusBar>
|
||||||
#include <QtConcurrentRun>
|
#include <QtConcurrentRun>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
|
#include <QActionGroup>
|
||||||
|
|
||||||
// Qt Common //
|
// Qt Common //
|
||||||
#include "qt_common/config/uisettings.h"
|
#include "qt_common/config/uisettings.h"
|
||||||
|
|
@ -377,6 +378,22 @@ static QString PrettyProductName() {
|
||||||
return QSysInfo::prettyProductName();
|
return QSysInfo::prettyProductName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr std::array<std::pair<u32, const char *>, 5> default_game_icon_sizes{
|
||||||
|
std::make_pair(0, QT_TRANSLATE_NOOP("MainWindow", "None")),
|
||||||
|
std::make_pair(32, QT_TRANSLATE_NOOP("MainWindow", "Small (32x32)")),
|
||||||
|
std::make_pair(64, QT_TRANSLATE_NOOP("MainWindow", "Standard (64x64)")),
|
||||||
|
std::make_pair(128, QT_TRANSLATE_NOOP("MainWindow", "Large (128x128)")),
|
||||||
|
std::make_pair(256, QT_TRANSLATE_NOOP("MainWindow", "Full Size (256x256)")),
|
||||||
|
};
|
||||||
|
|
||||||
|
QString GetTranslatedGameIconSize(size_t index) {
|
||||||
|
return QCoreApplication::translate("MainWindow", default_game_icon_sizes[index].second);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
// TODO(crueter): carboxyl does this, is it needed in qml?
|
// TODO(crueter): carboxyl does this, is it needed in qml?
|
||||||
inline static bool isDarkMode() {
|
inline static bool isDarkMode() {
|
||||||
|
|
@ -1607,6 +1624,33 @@ void MainWindow::ConnectMenuEvents() {
|
||||||
connect_menu(ui->action_Grid_View, &MainWindow::SetGridView);
|
connect_menu(ui->action_Grid_View, &MainWindow::SetGridView);
|
||||||
connect_menu(ui->action_Tree_View, &MainWindow::SetTreeView);
|
connect_menu(ui->action_Tree_View, &MainWindow::SetTreeView);
|
||||||
|
|
||||||
|
game_size_actions = new QActionGroup(this);
|
||||||
|
game_size_actions->setExclusive(true);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < default_game_icon_sizes.size(); i++) {
|
||||||
|
const auto current_size = UISettings::values.game_icon_size.GetValue();
|
||||||
|
const auto size = default_game_icon_sizes[i].first;
|
||||||
|
QAction *action = ui->menuGame_Icon_Size->addAction(GetTranslatedGameIconSize(i));
|
||||||
|
action->setCheckable(true);
|
||||||
|
|
||||||
|
if (current_size == size) action->setChecked(true);
|
||||||
|
|
||||||
|
game_size_actions->addAction(action);
|
||||||
|
|
||||||
|
connect(action, &QAction::triggered, this, [this, size](bool checked) {
|
||||||
|
if (checked) {
|
||||||
|
UISettings::values.game_icon_size.SetValue(size);
|
||||||
|
CheckIconSize();
|
||||||
|
game_list->RefreshGameDirectory();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckIconSize();
|
||||||
|
|
||||||
|
ui->action_Show_Game_Name->setChecked(UISettings::values.show_game_name.GetValue());
|
||||||
|
connect(ui->action_Show_Game_Name, &QAction::triggered, this, &MainWindow::ToggleShowGameName);
|
||||||
|
|
||||||
// Multiplayer
|
// Multiplayer
|
||||||
connect(ui->action_View_Lobby, &QAction::triggered, multiplayer_state,
|
connect(ui->action_View_Lobby, &QAction::triggered, multiplayer_state,
|
||||||
&MultiplayerState::OnViewLobby);
|
&MultiplayerState::OnViewLobby);
|
||||||
|
|
@ -3385,6 +3429,9 @@ void MainWindow::SetGameListMode(Settings::GameListMode mode) {
|
||||||
ui->action_Tree_View->setChecked(mode == Settings::GameListMode::TreeView);
|
ui->action_Tree_View->setChecked(mode == Settings::GameListMode::TreeView);
|
||||||
|
|
||||||
UISettings::values.game_list_mode = mode;
|
UISettings::values.game_list_mode = mode;
|
||||||
|
ui->action_Show_Game_Name->setEnabled(mode == Settings::GameListMode::GridView);
|
||||||
|
|
||||||
|
CheckIconSize();
|
||||||
game_list->ResetViewMode();
|
game_list->ResetViewMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3396,6 +3443,43 @@ void MainWindow::SetTreeView() {
|
||||||
SetGameListMode(Settings::GameListMode::TreeView);
|
SetGameListMode(Settings::GameListMode::TreeView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::CheckIconSize() {
|
||||||
|
// When in grid view mode, with text off
|
||||||
|
// there is no point in having icons turned off..
|
||||||
|
auto actions = game_size_actions->actions();
|
||||||
|
if (UISettings::values.game_list_mode.GetValue() == Settings::GameListMode::GridView &&
|
||||||
|
!UISettings::values.show_game_name.GetValue()) {
|
||||||
|
u32 newSize = UISettings::values.game_icon_size.GetValue();
|
||||||
|
if (newSize == 0) {
|
||||||
|
newSize = 64;
|
||||||
|
UISettings::values.game_icon_size.SetValue(newSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then disable the "none" action and update that menu.
|
||||||
|
for (size_t i = 0; i < default_game_icon_sizes.size(); i++) {
|
||||||
|
const auto current_size = newSize;
|
||||||
|
const auto size = default_game_icon_sizes[i].first;
|
||||||
|
if (current_size == size) actions.at(i)->setChecked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update this if you add anything before None.
|
||||||
|
actions.at(0)->setEnabled(false);
|
||||||
|
} else {
|
||||||
|
actions.at(0)->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::ToggleShowGameName() {
|
||||||
|
auto &setting = UISettings::values.show_game_name;
|
||||||
|
const bool newValue = !setting.GetValue();
|
||||||
|
ui->action_Show_Game_Name->setChecked(newValue);
|
||||||
|
setting.SetValue(newValue);
|
||||||
|
|
||||||
|
CheckIconSize();
|
||||||
|
|
||||||
|
game_list->RefreshGameDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::OnConfigure() {
|
void MainWindow::OnConfigure() {
|
||||||
const auto old_theme = UISettings::values.theme;
|
const auto old_theme = UISettings::values.theme;
|
||||||
const bool old_discord_presence = UISettings::values.enable_discord_presence.GetValue();
|
const bool old_discord_presence = UISettings::values.enable_discord_presence.GetValue();
|
||||||
|
|
@ -3916,7 +4000,6 @@ void MainWindow::OnDataDialog() {
|
||||||
|
|
||||||
// refresh stuff in case it was cleared
|
// refresh stuff in case it was cleared
|
||||||
OnGameListRefresh();
|
OnGameListRefresh();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::OnToggleFilterBar() {
|
void MainWindow::OnToggleFilterBar() {
|
||||||
|
|
@ -3939,7 +4022,6 @@ void MainWindow::OnGameListRefresh() {
|
||||||
SetFirmwareVersion();
|
SetFirmwareVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::LaunchFirmwareApplet(u64 raw_program_id, std::optional<Service::NFP::CabinetMode> cabinet_mode) {
|
void MainWindow::LaunchFirmwareApplet(u64 raw_program_id, std::optional<Service::NFP::CabinetMode> cabinet_mode) {
|
||||||
auto const program_id = Service::AM::AppletProgramId(raw_program_id);
|
auto const program_id = Service::AM::AppletProgramId(raw_program_id);
|
||||||
auto result = FirmwareManager::VerifyFirmware(*QtCommon::system.get());
|
auto result = FirmwareManager::VerifyFirmware(*QtCommon::system.get());
|
||||||
|
|
@ -4658,6 +4740,11 @@ void MainWindow::OnLanguageChanged(const QString& locale) {
|
||||||
qApp->removeTranslator(&translator);
|
qApp->removeTranslator(&translator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QAction *> actions = game_size_actions->actions();
|
||||||
|
for (size_t i = 0; i < default_game_icon_sizes.size(); i++) {
|
||||||
|
actions.at(i)->setText(GetTranslatedGameIconSize(i));
|
||||||
|
}
|
||||||
|
|
||||||
UISettings::values.language = locale.toStdString();
|
UISettings::values.language = locale.toStdString();
|
||||||
LoadTranslation();
|
LoadTranslation();
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
|
#include <qaction.h>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/settings_enums.h"
|
#include "common/settings_enums.h"
|
||||||
|
|
@ -407,6 +408,9 @@ private slots:
|
||||||
void SetGridView();
|
void SetGridView();
|
||||||
void SetTreeView();
|
void SetTreeView();
|
||||||
|
|
||||||
|
void CheckIconSize();
|
||||||
|
void ToggleShowGameName();
|
||||||
|
|
||||||
void LaunchFirmwareApplet(u64 program_id, std::optional<Service::NFP::CabinetMode> mode);
|
void LaunchFirmwareApplet(u64 program_id, std::optional<Service::NFP::CabinetMode> mode);
|
||||||
void OnCreateHomeMenuDesktopShortcut();
|
void OnCreateHomeMenuDesktopShortcut();
|
||||||
void OnCreateHomeMenuApplicationMenuShortcut();
|
void OnCreateHomeMenuApplicationMenuShortcut();
|
||||||
|
|
@ -532,6 +536,8 @@ private:
|
||||||
|
|
||||||
QString startup_icon_theme;
|
QString startup_icon_theme;
|
||||||
|
|
||||||
|
QActionGroup *game_size_actions;
|
||||||
|
|
||||||
// Debugger panes
|
// Debugger panes
|
||||||
ControllerDialog* controller_dialog = nullptr;
|
ControllerDialog* controller_dialog = nullptr;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue