mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-18 17:34:52 +00:00
Change Background Image for games (#2334)
* Added opacity change instead of blur for background image * Fixed integer overflow when refreshing grid list * Added slider to control background image opacity * Added show background image button * Added UI code for checkbox and English and Spanish translations for new UI elements * Removed background image caching * Background image update on apply/save * Only recompute image if opacity or game changes * Fixed segfault when trying to change opacity after table refresh * Placed background image settings under GUI in settings file
This commit is contained in:
parent
363604c6f0
commit
b6ad512e34
13 changed files with 279 additions and 56 deletions
|
@ -95,6 +95,8 @@ std::vector<std::string> m_pkg_viewer;
|
||||||
std::vector<std::string> m_elf_viewer;
|
std::vector<std::string> m_elf_viewer;
|
||||||
std::vector<std::string> m_recent_files;
|
std::vector<std::string> m_recent_files;
|
||||||
std::string emulator_language = "en";
|
std::string emulator_language = "en";
|
||||||
|
static int backgroundImageOpacity = 50;
|
||||||
|
static bool showBackgroundImage = true;
|
||||||
|
|
||||||
// Language
|
// Language
|
||||||
u32 m_language = 1; // english
|
u32 m_language = 1; // english
|
||||||
|
@ -611,6 +613,22 @@ u32 GetLanguage() {
|
||||||
return m_language;
|
return m_language;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getBackgroundImageOpacity() {
|
||||||
|
return backgroundImageOpacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBackgroundImageOpacity(int opacity) {
|
||||||
|
backgroundImageOpacity = std::clamp(opacity, 0, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getShowBackgroundImage() {
|
||||||
|
return showBackgroundImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setShowBackgroundImage(bool show) {
|
||||||
|
showBackgroundImage = show;
|
||||||
|
}
|
||||||
|
|
||||||
void load(const std::filesystem::path& path) {
|
void load(const std::filesystem::path& path) {
|
||||||
// If the configuration file does not exist, create it and return
|
// If the configuration file does not exist, create it and return
|
||||||
std::error_code error;
|
std::error_code error;
|
||||||
|
@ -731,6 +749,8 @@ void load(const std::filesystem::path& path) {
|
||||||
m_recent_files = toml::find_or<std::vector<std::string>>(gui, "recentFiles", {});
|
m_recent_files = toml::find_or<std::vector<std::string>>(gui, "recentFiles", {});
|
||||||
m_table_mode = toml::find_or<int>(gui, "gameTableMode", 0);
|
m_table_mode = toml::find_or<int>(gui, "gameTableMode", 0);
|
||||||
emulator_language = toml::find_or<std::string>(gui, "emulatorLanguage", "en");
|
emulator_language = toml::find_or<std::string>(gui, "emulatorLanguage", "en");
|
||||||
|
backgroundImageOpacity = toml::find_or<int>(gui, "backgroundImageOpacity", 50);
|
||||||
|
showBackgroundImage = toml::find_or<bool>(gui, "showBackgroundImage", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.contains("Settings")) {
|
if (data.contains("Settings")) {
|
||||||
|
@ -821,6 +841,8 @@ void save(const std::filesystem::path& path) {
|
||||||
data["GUI"]["addonInstallDir"] =
|
data["GUI"]["addonInstallDir"] =
|
||||||
std::string{fmt::UTF(settings_addon_install_dir.u8string()).data};
|
std::string{fmt::UTF(settings_addon_install_dir.u8string()).data};
|
||||||
data["GUI"]["emulatorLanguage"] = emulator_language;
|
data["GUI"]["emulatorLanguage"] = emulator_language;
|
||||||
|
data["GUI"]["backgroundImageOpacity"] = backgroundImageOpacity;
|
||||||
|
data["GUI"]["showBackgroundImage"] = showBackgroundImage;
|
||||||
data["Settings"]["consoleLanguage"] = m_language;
|
data["Settings"]["consoleLanguage"] = m_language;
|
||||||
|
|
||||||
std::ofstream file(path, std::ios::binary);
|
std::ofstream file(path, std::ios::binary);
|
||||||
|
@ -914,6 +936,8 @@ void setDefaultValues() {
|
||||||
separateupdatefolder = false;
|
separateupdatefolder = false;
|
||||||
compatibilityData = false;
|
compatibilityData = false;
|
||||||
checkCompatibilityOnStartup = false;
|
checkCompatibilityOnStartup = false;
|
||||||
|
backgroundImageOpacity = 50;
|
||||||
|
showBackgroundImage = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr std::string_view GetDefaultKeyboardConfig() {
|
constexpr std::string_view GetDefaultKeyboardConfig() {
|
||||||
|
|
|
@ -30,6 +30,8 @@ bool getEnableDiscordRPC();
|
||||||
bool getSeparateUpdateEnabled();
|
bool getSeparateUpdateEnabled();
|
||||||
bool getCompatibilityEnabled();
|
bool getCompatibilityEnabled();
|
||||||
bool getCheckCompatibilityOnStartup();
|
bool getCheckCompatibilityOnStartup();
|
||||||
|
int getBackgroundImageOpacity();
|
||||||
|
bool getShowBackgroundImage();
|
||||||
|
|
||||||
std::string getLogFilter();
|
std::string getLogFilter();
|
||||||
std::string getLogType();
|
std::string getLogType();
|
||||||
|
@ -88,6 +90,8 @@ void setGameInstallDirs(const std::vector<std::filesystem::path>& settings_insta
|
||||||
void setSaveDataPath(const std::filesystem::path& path);
|
void setSaveDataPath(const std::filesystem::path& path);
|
||||||
void setCompatibilityEnabled(bool use);
|
void setCompatibilityEnabled(bool use);
|
||||||
void setCheckCompatibilityOnStartup(bool use);
|
void setCheckCompatibilityOnStartup(bool use);
|
||||||
|
void setBackgroundImageOpacity(int opacity);
|
||||||
|
void setShowBackgroundImage(bool show);
|
||||||
|
|
||||||
void setCursorState(s16 cursorState);
|
void setCursorState(s16 cursorState);
|
||||||
void setCursorHideTimeout(int newcursorHideTimeout);
|
void setCursorHideTimeout(int newcursorHideTimeout);
|
||||||
|
|
|
@ -38,17 +38,34 @@ GameGridFrame::GameGridFrame(std::shared_ptr<GameInfoClass> game_info_get,
|
||||||
|
|
||||||
void GameGridFrame::onCurrentCellChanged(int currentRow, int currentColumn, int previousRow,
|
void GameGridFrame::onCurrentCellChanged(int currentRow, int currentColumn, int previousRow,
|
||||||
int previousColumn) {
|
int previousColumn) {
|
||||||
crtRow = currentRow;
|
// Early exit for invalid indices
|
||||||
crtColumn = currentColumn;
|
if (currentRow < 0 || currentColumn < 0) {
|
||||||
columnCnt = this->columnCount();
|
|
||||||
|
|
||||||
auto itemID = (crtRow * columnCnt) + currentColumn;
|
|
||||||
if (itemID > m_game_info->m_games.count() - 1) {
|
|
||||||
cellClicked = false;
|
cellClicked = false;
|
||||||
validCellSelected = false;
|
validCellSelected = false;
|
||||||
BackgroundMusicPlayer::getInstance().stopMusic();
|
BackgroundMusicPlayer::getInstance().stopMusic();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crtRow = currentRow;
|
||||||
|
crtColumn = currentColumn;
|
||||||
|
columnCnt = this->columnCount();
|
||||||
|
|
||||||
|
// Prevent integer overflow
|
||||||
|
if (columnCnt <= 0 || crtRow > (std::numeric_limits<int>::max() / columnCnt)) {
|
||||||
|
cellClicked = false;
|
||||||
|
validCellSelected = false;
|
||||||
|
BackgroundMusicPlayer::getInstance().stopMusic();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto itemID = (crtRow * columnCnt) + currentColumn;
|
||||||
|
if (itemID < 0 || itemID > m_game_info->m_games.count() - 1) {
|
||||||
|
cellClicked = false;
|
||||||
|
validCellSelected = false;
|
||||||
|
BackgroundMusicPlayer::getInstance().stopMusic();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cellClicked = true;
|
cellClicked = true;
|
||||||
validCellSelected = true;
|
validCellSelected = true;
|
||||||
SetGridBackgroundImage(crtRow, crtColumn);
|
SetGridBackgroundImage(crtRow, crtColumn);
|
||||||
|
@ -65,6 +82,8 @@ void GameGridFrame::PlayBackgroundMusic(QString path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameGridFrame::PopulateGameGrid(QVector<GameInfo> m_games_search, bool fromSearch) {
|
void GameGridFrame::PopulateGameGrid(QVector<GameInfo> m_games_search, bool fromSearch) {
|
||||||
|
this->crtRow = -1;
|
||||||
|
this->crtColumn = -1;
|
||||||
QVector<GameInfo> m_games_;
|
QVector<GameInfo> m_games_;
|
||||||
this->clearContents();
|
this->clearContents();
|
||||||
if (fromSearch)
|
if (fromSearch)
|
||||||
|
@ -136,44 +155,49 @@ void GameGridFrame::PopulateGameGrid(QVector<GameInfo> m_games_search, bool from
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameGridFrame::SetGridBackgroundImage(int row, int column) {
|
void GameGridFrame::SetGridBackgroundImage(int row, int column) {
|
||||||
|
|
||||||
int itemID = (row * this->columnCount()) + column;
|
int itemID = (row * this->columnCount()) + column;
|
||||||
QWidget* item = this->cellWidget(row, column);
|
QWidget* item = this->cellWidget(row, column);
|
||||||
if (item) {
|
if (!item) {
|
||||||
QString pic1Path;
|
// handle case where no item was clicked
|
||||||
Common::FS::PathToQString(pic1Path, (*m_games_shared)[itemID].pic_path);
|
return;
|
||||||
const auto blurredPic1Path = Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) /
|
|
||||||
(*m_games_shared)[itemID].serial / "pic1.png";
|
|
||||||
QString blurredPic1PathQt;
|
|
||||||
Common::FS::PathToQString(blurredPic1PathQt, blurredPic1Path);
|
|
||||||
|
|
||||||
backgroundImage = QImage(blurredPic1PathQt);
|
|
||||||
if (backgroundImage.isNull()) {
|
|
||||||
QImage image(pic1Path);
|
|
||||||
backgroundImage = m_game_list_utils.BlurImage(image, image.rect(), 16);
|
|
||||||
|
|
||||||
std::filesystem::path img_path =
|
|
||||||
Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) /
|
|
||||||
(*m_games_shared)[itemID].serial;
|
|
||||||
std::filesystem::create_directories(img_path);
|
|
||||||
if (!backgroundImage.save(blurredPic1PathQt, "PNG")) {
|
|
||||||
// qDebug() << "Error: Unable to save image.";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If background images are hidden, clear the background image
|
||||||
|
if (!Config::getShowBackgroundImage()) {
|
||||||
|
backgroundImage = QImage();
|
||||||
|
m_last_opacity = -1; // Reset opacity tracking when disabled
|
||||||
|
m_current_game_path.clear(); // Reset current game path
|
||||||
RefreshGridBackgroundImage();
|
RefreshGridBackgroundImage();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto& game = (*m_games_shared)[itemID];
|
||||||
|
const int opacity = Config::getBackgroundImageOpacity();
|
||||||
|
|
||||||
|
// Recompute if opacity changed or we switched to a different game
|
||||||
|
if (opacity != m_last_opacity || game.pic_path != m_current_game_path) {
|
||||||
|
QImage original_image(QString::fromStdString(game.pic_path.string()));
|
||||||
|
if (!original_image.isNull()) {
|
||||||
|
backgroundImage = m_game_list_utils.ChangeImageOpacity(
|
||||||
|
original_image, original_image.rect(), opacity / 100.0f);
|
||||||
|
m_last_opacity = opacity;
|
||||||
|
m_current_game_path = game.pic_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshGridBackgroundImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameGridFrame::RefreshGridBackgroundImage() {
|
void GameGridFrame::RefreshGridBackgroundImage() {
|
||||||
if (!backgroundImage.isNull()) {
|
|
||||||
QPalette palette;
|
QPalette palette;
|
||||||
|
if (!backgroundImage.isNull() && Config::getShowBackgroundImage()) {
|
||||||
palette.setBrush(QPalette::Base,
|
palette.setBrush(QPalette::Base,
|
||||||
QBrush(backgroundImage.scaled(size(), Qt::IgnoreAspectRatio)));
|
QBrush(backgroundImage.scaled(size(), Qt::IgnoreAspectRatio)));
|
||||||
|
}
|
||||||
QColor transparentColor = QColor(135, 206, 235, 40);
|
QColor transparentColor = QColor(135, 206, 235, 40);
|
||||||
palette.setColor(QPalette::Highlight, transparentColor);
|
palette.setColor(QPalette::Highlight, transparentColor);
|
||||||
this->setPalette(palette);
|
this->setPalette(palette);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool GameGridFrame::IsValidCellSelected() {
|
bool GameGridFrame::IsValidCellSelected() {
|
||||||
return validCellSelected;
|
return validCellSelected;
|
||||||
|
|
|
@ -33,6 +33,8 @@ private:
|
||||||
std::shared_ptr<CompatibilityInfoClass> m_compat_info;
|
std::shared_ptr<CompatibilityInfoClass> m_compat_info;
|
||||||
std::shared_ptr<QVector<GameInfo>> m_games_shared;
|
std::shared_ptr<QVector<GameInfo>> m_games_shared;
|
||||||
bool validCellSelected = false;
|
bool validCellSelected = false;
|
||||||
|
int m_last_opacity = -1; // Track last opacity to avoid unnecessary recomputation
|
||||||
|
std::filesystem::path m_current_game_path; // Track current game path to detect changes
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GameGridFrame(std::shared_ptr<GameInfoClass> game_info_get,
|
explicit GameGridFrame(std::shared_ptr<GameInfoClass> game_info_get,
|
||||||
|
|
|
@ -89,6 +89,7 @@ void GameListFrame::onCurrentCellChanged(int currentRow, int currentColumn, int
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
m_current_item = item; // Store current item
|
||||||
SetListBackgroundImage(item);
|
SetListBackgroundImage(item);
|
||||||
PlayBackgroundMusic(item);
|
PlayBackgroundMusic(item);
|
||||||
}
|
}
|
||||||
|
@ -104,6 +105,7 @@ void GameListFrame::PlayBackgroundMusic(QTableWidgetItem* item) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameListFrame::PopulateGameList(bool isInitialPopulation) {
|
void GameListFrame::PopulateGameList(bool isInitialPopulation) {
|
||||||
|
this->m_current_item = nullptr;
|
||||||
// Do not show status column if it is not enabled
|
// Do not show status column if it is not enabled
|
||||||
this->setColumnHidden(2, !Config::getCompatibilityEnabled());
|
this->setColumnHidden(2, !Config::getCompatibilityEnabled());
|
||||||
this->setColumnHidden(6, !Config::GetLoadGameSizeEnabled());
|
this->setColumnHidden(6, !Config::GetLoadGameSizeEnabled());
|
||||||
|
@ -167,39 +169,42 @@ void GameListFrame::SetListBackgroundImage(QTableWidgetItem* item) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString pic1Path;
|
// If background images are hidden, clear the background image
|
||||||
Common::FS::PathToQString(pic1Path, m_game_info->m_games[item->row()].pic_path);
|
if (!Config::getShowBackgroundImage()) {
|
||||||
const auto blurredPic1Path = Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) /
|
backgroundImage = QImage();
|
||||||
m_game_info->m_games[item->row()].serial / "pic1.png";
|
m_last_opacity = -1; // Reset opacity tracking when disabled
|
||||||
QString blurredPic1PathQt;
|
m_current_game_path.clear(); // Reset current game path
|
||||||
Common::FS::PathToQString(blurredPic1PathQt, blurredPic1Path);
|
RefreshListBackgroundImage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
backgroundImage = QImage(blurredPic1PathQt);
|
const auto& game = m_game_info->m_games[item->row()];
|
||||||
if (backgroundImage.isNull()) {
|
const int opacity = Config::getBackgroundImageOpacity();
|
||||||
QImage image(pic1Path);
|
|
||||||
backgroundImage = m_game_list_utils.BlurImage(image, image.rect(), 16);
|
|
||||||
|
|
||||||
std::filesystem::path img_path =
|
// Recompute if opacity changed or we switched to a different game
|
||||||
Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) /
|
if (opacity != m_last_opacity || game.pic_path != m_current_game_path) {
|
||||||
m_game_info->m_games[item->row()].serial;
|
QImage original_image(QString::fromStdString(game.pic_path.string()));
|
||||||
std::filesystem::create_directories(img_path);
|
if (!original_image.isNull()) {
|
||||||
if (!backgroundImage.save(blurredPic1PathQt, "PNG")) {
|
backgroundImage = m_game_list_utils.ChangeImageOpacity(
|
||||||
// qDebug() << "Error: Unable to save image.";
|
original_image, original_image.rect(), opacity / 100.0f);
|
||||||
|
m_last_opacity = opacity;
|
||||||
|
m_current_game_path = game.pic_path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RefreshListBackgroundImage();
|
RefreshListBackgroundImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameListFrame::RefreshListBackgroundImage() {
|
void GameListFrame::RefreshListBackgroundImage() {
|
||||||
if (!backgroundImage.isNull()) {
|
|
||||||
QPalette palette;
|
QPalette palette;
|
||||||
|
if (!backgroundImage.isNull() && Config::getShowBackgroundImage()) {
|
||||||
palette.setBrush(QPalette::Base,
|
palette.setBrush(QPalette::Base,
|
||||||
QBrush(backgroundImage.scaled(size(), Qt::IgnoreAspectRatio)));
|
QBrush(backgroundImage.scaled(size(), Qt::IgnoreAspectRatio)));
|
||||||
|
}
|
||||||
QColor transparentColor = QColor(135, 206, 235, 40);
|
QColor transparentColor = QColor(135, 206, 235, 40);
|
||||||
palette.setColor(QPalette::Highlight, transparentColor);
|
palette.setColor(QPalette::Highlight, transparentColor);
|
||||||
this->setPalette(palette);
|
this->setPalette(palette);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void GameListFrame::SortNameAscending(int columnIndex) {
|
void GameListFrame::SortNameAscending(int columnIndex) {
|
||||||
std::sort(m_game_info->m_games.begin(), m_game_info->m_games.end(),
|
std::sort(m_game_info->m_games.begin(), m_game_info->m_games.end(),
|
||||||
|
@ -392,3 +397,7 @@ QString GameListFrame::GetPlayTime(const std::string& serial) {
|
||||||
file.close();
|
file.close();
|
||||||
return playTime;
|
return playTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QTableWidgetItem* GameListFrame::GetCurrentItem() {
|
||||||
|
return m_current_item;
|
||||||
|
}
|
|
@ -44,11 +44,14 @@ private:
|
||||||
QList<QAction*> m_columnActs;
|
QList<QAction*> m_columnActs;
|
||||||
GameInfoClass* game_inf_get = nullptr;
|
GameInfoClass* game_inf_get = nullptr;
|
||||||
bool ListSortedAsc = true;
|
bool ListSortedAsc = true;
|
||||||
|
QTableWidgetItem* m_current_item = nullptr;
|
||||||
|
int m_last_opacity = -1; // Track last opacity to avoid unnecessary recomputation
|
||||||
|
std::filesystem::path m_current_game_path; // Track current game path to detect changes
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void PopulateGameList(bool isInitialPopulation = true);
|
void PopulateGameList(bool isInitialPopulation = true);
|
||||||
void ResizeIcons(int iconSize);
|
void ResizeIcons(int iconSize);
|
||||||
|
QTableWidgetItem* GetCurrentItem();
|
||||||
QImage backgroundImage;
|
QImage backgroundImage;
|
||||||
GameListUtils m_game_list_utils;
|
GameListUtils m_game_list_utils;
|
||||||
GuiContextMenus m_gui_context_menus;
|
GuiContextMenus m_gui_context_menus;
|
||||||
|
|
|
@ -201,4 +201,30 @@ public:
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Opacity is a float between 0 and 1
|
||||||
|
static QImage ChangeImageOpacity(const QImage& image, const QRect& rect, float opacity) {
|
||||||
|
// Convert to ARGB32 format to ensure alpha channel support
|
||||||
|
QImage result = image.convertToFormat(QImage::Format_ARGB32);
|
||||||
|
|
||||||
|
// Ensure opacity is between 0 and 1
|
||||||
|
opacity = std::clamp(opacity, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
// Convert opacity to integer alpha value (0-255)
|
||||||
|
int alpha = static_cast<int>(opacity * 255);
|
||||||
|
|
||||||
|
// Process only the specified rectangle area
|
||||||
|
for (int y = rect.top(); y <= rect.bottom(); ++y) {
|
||||||
|
QRgb* line = reinterpret_cast<QRgb*>(result.scanLine(y));
|
||||||
|
for (int x = rect.left(); x <= rect.right(); ++x) {
|
||||||
|
// Get current pixel
|
||||||
|
QRgb pixel = line[x];
|
||||||
|
// Keep RGB values, but modify alpha while preserving relative transparency
|
||||||
|
int newAlpha = (qAlpha(pixel) * alpha) / 255;
|
||||||
|
line[x] = qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), newAlpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -297,6 +297,23 @@ void MainWindow::CreateConnects() {
|
||||||
connect(settingsDialog, &SettingsDialog::CompatibilityChanged, this,
|
connect(settingsDialog, &SettingsDialog::CompatibilityChanged, this,
|
||||||
&MainWindow::RefreshGameTable);
|
&MainWindow::RefreshGameTable);
|
||||||
|
|
||||||
|
connect(settingsDialog, &SettingsDialog::BackgroundOpacityChanged, this,
|
||||||
|
[this](int opacity) {
|
||||||
|
Config::setBackgroundImageOpacity(opacity);
|
||||||
|
if (m_game_list_frame) {
|
||||||
|
QTableWidgetItem* current = m_game_list_frame->GetCurrentItem();
|
||||||
|
if (current) {
|
||||||
|
m_game_list_frame->SetListBackgroundImage(current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_game_grid_frame) {
|
||||||
|
if (m_game_grid_frame->IsValidCellSelected()) {
|
||||||
|
m_game_grid_frame->SetGridBackgroundImage(m_game_grid_frame->crtRow,
|
||||||
|
m_game_grid_frame->crtColumn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
settingsDialog->exec();
|
settingsDialog->exec();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,9 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
|
||||||
{
|
{
|
||||||
connect(ui->chooseHomeTabComboBox, &QComboBox::currentTextChanged, this,
|
connect(ui->chooseHomeTabComboBox, &QComboBox::currentTextChanged, this,
|
||||||
[](const QString& hometab) { Config::setChooseHomeTab(hometab.toStdString()); });
|
[](const QString& hometab) { Config::setChooseHomeTab(hometab.toStdString()); });
|
||||||
|
|
||||||
|
connect(ui->showBackgroundImageCheckBox, &QCheckBox::stateChanged, this,
|
||||||
|
[](int state) { Config::setShowBackgroundImage(state == Qt::Checked); });
|
||||||
}
|
}
|
||||||
// Input TAB
|
// Input TAB
|
||||||
{
|
{
|
||||||
|
@ -251,6 +254,7 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
|
||||||
#ifdef ENABLE_UPDATER
|
#ifdef ENABLE_UPDATER
|
||||||
ui->updaterGroupBox->installEventFilter(this);
|
ui->updaterGroupBox->installEventFilter(this);
|
||||||
#endif
|
#endif
|
||||||
|
ui->GUIBackgroundImageGroupBox->installEventFilter(this);
|
||||||
ui->GUIMusicGroupBox->installEventFilter(this);
|
ui->GUIMusicGroupBox->installEventFilter(this);
|
||||||
ui->disableTrophycheckBox->installEventFilter(this);
|
ui->disableTrophycheckBox->installEventFilter(this);
|
||||||
ui->enableCompatibilityCheckBox->installEventFilter(this);
|
ui->enableCompatibilityCheckBox->installEventFilter(this);
|
||||||
|
@ -410,6 +414,8 @@ void SettingsDialog::LoadValuesFromConfig() {
|
||||||
|
|
||||||
ui->removeFolderButton->setEnabled(!ui->gameFoldersListWidget->selectedItems().isEmpty());
|
ui->removeFolderButton->setEnabled(!ui->gameFoldersListWidget->selectedItems().isEmpty());
|
||||||
ResetInstallFolders();
|
ResetInstallFolders();
|
||||||
|
ui->backgroundImageOpacitySlider->setValue(Config::getBackgroundImageOpacity());
|
||||||
|
ui->showBackgroundImageCheckBox->setChecked(Config::getShowBackgroundImage());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::InitializeEmulatorLanguages() {
|
void SettingsDialog::InitializeEmulatorLanguages() {
|
||||||
|
@ -504,6 +510,8 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
|
||||||
} else if (elementName == "updaterGroupBox") {
|
} else if (elementName == "updaterGroupBox") {
|
||||||
text = tr("updaterGroupBox");
|
text = tr("updaterGroupBox");
|
||||||
#endif
|
#endif
|
||||||
|
} else if (elementName == "GUIBackgroundImageGroupBox") {
|
||||||
|
text = tr("GUIBackgroundImageGroupBox");
|
||||||
} else if (elementName == "GUIMusicGroupBox") {
|
} else if (elementName == "GUIMusicGroupBox") {
|
||||||
text = tr("GUIMusicGroupBox");
|
text = tr("GUIMusicGroupBox");
|
||||||
} else if (elementName == "disableTrophycheckBox") {
|
} else if (elementName == "disableTrophycheckBox") {
|
||||||
|
@ -638,6 +646,9 @@ void SettingsDialog::UpdateSettings() {
|
||||||
Config::setChooseHomeTab(ui->chooseHomeTabComboBox->currentText().toStdString());
|
Config::setChooseHomeTab(ui->chooseHomeTabComboBox->currentText().toStdString());
|
||||||
Config::setCompatibilityEnabled(ui->enableCompatibilityCheckBox->isChecked());
|
Config::setCompatibilityEnabled(ui->enableCompatibilityCheckBox->isChecked());
|
||||||
Config::setCheckCompatibilityOnStartup(ui->checkCompatibilityOnStartupCheckBox->isChecked());
|
Config::setCheckCompatibilityOnStartup(ui->checkCompatibilityOnStartupCheckBox->isChecked());
|
||||||
|
Config::setBackgroundImageOpacity(ui->backgroundImageOpacitySlider->value());
|
||||||
|
emit BackgroundOpacityChanged(ui->backgroundImageOpacitySlider->value());
|
||||||
|
Config::setShowBackgroundImage(ui->showBackgroundImageCheckBox->isChecked());
|
||||||
|
|
||||||
#ifdef ENABLE_DISCORD_RPC
|
#ifdef ENABLE_DISCORD_RPC
|
||||||
auto* rpc = Common::Singleton<DiscordRPCHandler::RPC>::Instance();
|
auto* rpc = Common::Singleton<DiscordRPCHandler::RPC>::Instance();
|
||||||
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
signals:
|
signals:
|
||||||
void LanguageChanged(const std::string& locale);
|
void LanguageChanged(const std::string& locale);
|
||||||
void CompatibilityChanged();
|
void CompatibilityChanged();
|
||||||
|
void BackgroundOpacityChanged(int opacity);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadValuesFromConfig();
|
void LoadValuesFromConfig();
|
||||||
|
|
|
@ -583,6 +583,76 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="GUIBackgroundImageGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Background Image</string>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="backgroundImageVLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="showBackgroundImageCheckBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Show Background Image</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="opacityLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="backgroundImageOpacityLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Opacity</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSlider" name="backgroundImageOpacitySlider">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="GUIMusicGroupBox">
|
<widget class="QGroupBox" name="GUIMusicGroupBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
|
|
@ -757,6 +757,18 @@
|
||||||
<source>Disable Trophy Pop-ups</source>
|
<source>Disable Trophy Pop-ups</source>
|
||||||
<translation>Disable Trophy Pop-ups</translation>
|
<translation>Disable Trophy Pop-ups</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Background Image</source>
|
||||||
|
<translation>Background Image</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Show Background Image</source>
|
||||||
|
<translation>Show Background Image</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Opacity</source>
|
||||||
|
<translation>Opacity</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Play title music</source>
|
<source>Play title music</source>
|
||||||
<translation>Play title music</translation>
|
<translation>Play title music</translation>
|
||||||
|
@ -853,6 +865,10 @@
|
||||||
<source>updaterGroupBox</source>
|
<source>updaterGroupBox</source>
|
||||||
<translation>Update:\nRelease: Official versions released every month that may be very outdated, but are more reliable and tested.\nNightly: Development versions that have all the latest features and fixes, but may contain bugs and are less stable.</translation>
|
<translation>Update:\nRelease: Official versions released every month that may be very outdated, but are more reliable and tested.\nNightly: Development versions that have all the latest features and fixes, but may contain bugs and are less stable.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>GUIBackgroundImageGroupBox</source>
|
||||||
|
<translation>Background Image:\nControl the opacity of the game background image.</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>GUIMusicGroupBox</source>
|
<source>GUIMusicGroupBox</source>
|
||||||
<translation>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</translation>
|
<translation>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</translation>
|
||||||
|
|
|
@ -748,6 +748,18 @@
|
||||||
<source>Disable Trophy Pop-ups</source>
|
<source>Disable Trophy Pop-ups</source>
|
||||||
<translation>Disable Trophy Pop-ups</translation>
|
<translation>Disable Trophy Pop-ups</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Background Image</source>
|
||||||
|
<translation>Imagen de fondo</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Show Background Image</source>
|
||||||
|
<translation>Mostrar Imagen de Fondo</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Opacity</source>
|
||||||
|
<translation>Opacidad</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Play title music</source>
|
<source>Play title music</source>
|
||||||
<translation>Reproducir la música de apertura</translation>
|
<translation>Reproducir la música de apertura</translation>
|
||||||
|
@ -844,6 +856,10 @@
|
||||||
<source>updaterGroupBox</source>
|
<source>updaterGroupBox</source>
|
||||||
<translation>Actualización:\nRelease: Versiones oficiales lanzadas cada mes que pueden estar muy desactualizadas, pero son más confiables y están probadas.\nNightly: Versiones de desarrollo que tienen todas las últimas funciones y correcciones, pero pueden contener errores y son menos estables.</translation>
|
<translation>Actualización:\nRelease: Versiones oficiales lanzadas cada mes que pueden estar muy desactualizadas, pero son más confiables y están probadas.\nNightly: Versiones de desarrollo que tienen todas las últimas funciones y correcciones, pero pueden contener errores y son menos estables.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>GUIBackgroundImageGroupBox</source>
|
||||||
|
<translation>Imagen de fondo:\nControle la opacidad de la imagen de fondo del juego.</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>GUIMusicGroupBox</source>
|
<source>GUIMusicGroupBox</source>
|
||||||
<translation>Reproducir Música del Título:\nSi un juego lo admite, habilita la reproducción de música especial al seleccionar el juego en la interfaz gráfica.</translation>
|
<translation>Reproducir Música del Título:\nSi un juego lo admite, habilita la reproducción de música especial al seleccionar el juego en la interfaz gráfica.</translation>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue