mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-20 03:24:49 +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_recent_files;
|
||||
std::string emulator_language = "en";
|
||||
static int backgroundImageOpacity = 50;
|
||||
static bool showBackgroundImage = true;
|
||||
|
||||
// Language
|
||||
u32 m_language = 1; // english
|
||||
|
@ -611,6 +613,22 @@ u32 GetLanguage() {
|
|||
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) {
|
||||
// If the configuration file does not exist, create it and return
|
||||
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_table_mode = toml::find_or<int>(gui, "gameTableMode", 0);
|
||||
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")) {
|
||||
|
@ -821,6 +841,8 @@ void save(const std::filesystem::path& path) {
|
|||
data["GUI"]["addonInstallDir"] =
|
||||
std::string{fmt::UTF(settings_addon_install_dir.u8string()).data};
|
||||
data["GUI"]["emulatorLanguage"] = emulator_language;
|
||||
data["GUI"]["backgroundImageOpacity"] = backgroundImageOpacity;
|
||||
data["GUI"]["showBackgroundImage"] = showBackgroundImage;
|
||||
data["Settings"]["consoleLanguage"] = m_language;
|
||||
|
||||
std::ofstream file(path, std::ios::binary);
|
||||
|
@ -914,6 +936,8 @@ void setDefaultValues() {
|
|||
separateupdatefolder = false;
|
||||
compatibilityData = false;
|
||||
checkCompatibilityOnStartup = false;
|
||||
backgroundImageOpacity = 50;
|
||||
showBackgroundImage = true;
|
||||
}
|
||||
|
||||
constexpr std::string_view GetDefaultKeyboardConfig() {
|
||||
|
|
|
@ -30,6 +30,8 @@ bool getEnableDiscordRPC();
|
|||
bool getSeparateUpdateEnabled();
|
||||
bool getCompatibilityEnabled();
|
||||
bool getCheckCompatibilityOnStartup();
|
||||
int getBackgroundImageOpacity();
|
||||
bool getShowBackgroundImage();
|
||||
|
||||
std::string getLogFilter();
|
||||
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 setCompatibilityEnabled(bool use);
|
||||
void setCheckCompatibilityOnStartup(bool use);
|
||||
void setBackgroundImageOpacity(int opacity);
|
||||
void setShowBackgroundImage(bool show);
|
||||
|
||||
void setCursorState(s16 cursorState);
|
||||
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,
|
||||
int previousColumn) {
|
||||
crtRow = currentRow;
|
||||
crtColumn = currentColumn;
|
||||
columnCnt = this->columnCount();
|
||||
|
||||
auto itemID = (crtRow * columnCnt) + currentColumn;
|
||||
if (itemID > m_game_info->m_games.count() - 1) {
|
||||
// Early exit for invalid indices
|
||||
if (currentRow < 0 || currentColumn < 0) {
|
||||
cellClicked = false;
|
||||
validCellSelected = false;
|
||||
BackgroundMusicPlayer::getInstance().stopMusic();
|
||||
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;
|
||||
validCellSelected = true;
|
||||
SetGridBackgroundImage(crtRow, crtColumn);
|
||||
|
@ -65,6 +82,8 @@ void GameGridFrame::PlayBackgroundMusic(QString path) {
|
|||
}
|
||||
|
||||
void GameGridFrame::PopulateGameGrid(QVector<GameInfo> m_games_search, bool fromSearch) {
|
||||
this->crtRow = -1;
|
||||
this->crtColumn = -1;
|
||||
QVector<GameInfo> m_games_;
|
||||
this->clearContents();
|
||||
if (fromSearch)
|
||||
|
@ -136,43 +155,48 @@ void GameGridFrame::PopulateGameGrid(QVector<GameInfo> m_games_search, bool from
|
|||
}
|
||||
|
||||
void GameGridFrame::SetGridBackgroundImage(int row, int column) {
|
||||
|
||||
int itemID = (row * this->columnCount()) + column;
|
||||
QWidget* item = this->cellWidget(row, column);
|
||||
if (item) {
|
||||
QString pic1Path;
|
||||
Common::FS::PathToQString(pic1Path, (*m_games_shared)[itemID].pic_path);
|
||||
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.";
|
||||
}
|
||||
}
|
||||
RefreshGridBackgroundImage();
|
||||
if (!item) {
|
||||
// handle case where no item was clicked
|
||||
return;
|
||||
}
|
||||
|
||||
// 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();
|
||||
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() {
|
||||
if (!backgroundImage.isNull()) {
|
||||
QPalette palette;
|
||||
QPalette palette;
|
||||
if (!backgroundImage.isNull() && Config::getShowBackgroundImage()) {
|
||||
palette.setBrush(QPalette::Base,
|
||||
QBrush(backgroundImage.scaled(size(), Qt::IgnoreAspectRatio)));
|
||||
QColor transparentColor = QColor(135, 206, 235, 40);
|
||||
palette.setColor(QPalette::Highlight, transparentColor);
|
||||
this->setPalette(palette);
|
||||
}
|
||||
QColor transparentColor = QColor(135, 206, 235, 40);
|
||||
palette.setColor(QPalette::Highlight, transparentColor);
|
||||
this->setPalette(palette);
|
||||
}
|
||||
|
||||
bool GameGridFrame::IsValidCellSelected() {
|
||||
|
|
|
@ -33,6 +33,8 @@ private:
|
|||
std::shared_ptr<CompatibilityInfoClass> m_compat_info;
|
||||
std::shared_ptr<QVector<GameInfo>> m_games_shared;
|
||||
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:
|
||||
explicit GameGridFrame(std::shared_ptr<GameInfoClass> game_info_get,
|
||||
|
|
|
@ -89,6 +89,7 @@ void GameListFrame::onCurrentCellChanged(int currentRow, int currentColumn, int
|
|||
if (!item) {
|
||||
return;
|
||||
}
|
||||
m_current_item = item; // Store current item
|
||||
SetListBackgroundImage(item);
|
||||
PlayBackgroundMusic(item);
|
||||
}
|
||||
|
@ -104,6 +105,7 @@ void GameListFrame::PlayBackgroundMusic(QTableWidgetItem* item) {
|
|||
}
|
||||
|
||||
void GameListFrame::PopulateGameList(bool isInitialPopulation) {
|
||||
this->m_current_item = nullptr;
|
||||
// Do not show status column if it is not enabled
|
||||
this->setColumnHidden(2, !Config::getCompatibilityEnabled());
|
||||
this->setColumnHidden(6, !Config::GetLoadGameSizeEnabled());
|
||||
|
@ -167,38 +169,41 @@ void GameListFrame::SetListBackgroundImage(QTableWidgetItem* item) {
|
|||
return;
|
||||
}
|
||||
|
||||
QString pic1Path;
|
||||
Common::FS::PathToQString(pic1Path, m_game_info->m_games[item->row()].pic_path);
|
||||
const auto blurredPic1Path = Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) /
|
||||
m_game_info->m_games[item->row()].serial / "pic1.png";
|
||||
QString blurredPic1PathQt;
|
||||
Common::FS::PathToQString(blurredPic1PathQt, blurredPic1Path);
|
||||
// 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
|
||||
RefreshListBackgroundImage();
|
||||
return;
|
||||
}
|
||||
|
||||
backgroundImage = QImage(blurredPic1PathQt);
|
||||
if (backgroundImage.isNull()) {
|
||||
QImage image(pic1Path);
|
||||
backgroundImage = m_game_list_utils.BlurImage(image, image.rect(), 16);
|
||||
const auto& game = m_game_info->m_games[item->row()];
|
||||
const int opacity = Config::getBackgroundImageOpacity();
|
||||
|
||||
std::filesystem::path img_path =
|
||||
Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) /
|
||||
m_game_info->m_games[item->row()].serial;
|
||||
std::filesystem::create_directories(img_path);
|
||||
if (!backgroundImage.save(blurredPic1PathQt, "PNG")) {
|
||||
// qDebug() << "Error: Unable to save image.";
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
RefreshListBackgroundImage();
|
||||
}
|
||||
|
||||
void GameListFrame::RefreshListBackgroundImage() {
|
||||
if (!backgroundImage.isNull()) {
|
||||
QPalette palette;
|
||||
QPalette palette;
|
||||
if (!backgroundImage.isNull() && Config::getShowBackgroundImage()) {
|
||||
palette.setBrush(QPalette::Base,
|
||||
QBrush(backgroundImage.scaled(size(), Qt::IgnoreAspectRatio)));
|
||||
QColor transparentColor = QColor(135, 206, 235, 40);
|
||||
palette.setColor(QPalette::Highlight, transparentColor);
|
||||
this->setPalette(palette);
|
||||
}
|
||||
QColor transparentColor = QColor(135, 206, 235, 40);
|
||||
palette.setColor(QPalette::Highlight, transparentColor);
|
||||
this->setPalette(palette);
|
||||
}
|
||||
|
||||
void GameListFrame::SortNameAscending(int columnIndex) {
|
||||
|
@ -392,3 +397,7 @@ QString GameListFrame::GetPlayTime(const std::string& serial) {
|
|||
file.close();
|
||||
return playTime;
|
||||
}
|
||||
|
||||
QTableWidgetItem* GameListFrame::GetCurrentItem() {
|
||||
return m_current_item;
|
||||
}
|
|
@ -44,11 +44,14 @@ private:
|
|||
QList<QAction*> m_columnActs;
|
||||
GameInfoClass* game_inf_get = nullptr;
|
||||
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:
|
||||
void PopulateGameList(bool isInitialPopulation = true);
|
||||
void ResizeIcons(int iconSize);
|
||||
|
||||
QTableWidgetItem* GetCurrentItem();
|
||||
QImage backgroundImage;
|
||||
GameListUtils m_game_list_utils;
|
||||
GuiContextMenus m_gui_context_menus;
|
||||
|
|
|
@ -201,4 +201,30 @@ public:
|
|||
|
||||
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,
|
||||
&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();
|
||||
});
|
||||
|
||||
|
|
|
@ -173,6 +173,9 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
|
|||
{
|
||||
connect(ui->chooseHomeTabComboBox, &QComboBox::currentTextChanged, this,
|
||||
[](const QString& hometab) { Config::setChooseHomeTab(hometab.toStdString()); });
|
||||
|
||||
connect(ui->showBackgroundImageCheckBox, &QCheckBox::stateChanged, this,
|
||||
[](int state) { Config::setShowBackgroundImage(state == Qt::Checked); });
|
||||
}
|
||||
// Input TAB
|
||||
{
|
||||
|
@ -251,6 +254,7 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
|
|||
#ifdef ENABLE_UPDATER
|
||||
ui->updaterGroupBox->installEventFilter(this);
|
||||
#endif
|
||||
ui->GUIBackgroundImageGroupBox->installEventFilter(this);
|
||||
ui->GUIMusicGroupBox->installEventFilter(this);
|
||||
ui->disableTrophycheckBox->installEventFilter(this);
|
||||
ui->enableCompatibilityCheckBox->installEventFilter(this);
|
||||
|
@ -410,6 +414,8 @@ void SettingsDialog::LoadValuesFromConfig() {
|
|||
|
||||
ui->removeFolderButton->setEnabled(!ui->gameFoldersListWidget->selectedItems().isEmpty());
|
||||
ResetInstallFolders();
|
||||
ui->backgroundImageOpacitySlider->setValue(Config::getBackgroundImageOpacity());
|
||||
ui->showBackgroundImageCheckBox->setChecked(Config::getShowBackgroundImage());
|
||||
}
|
||||
|
||||
void SettingsDialog::InitializeEmulatorLanguages() {
|
||||
|
@ -504,6 +510,8 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
|
|||
} else if (elementName == "updaterGroupBox") {
|
||||
text = tr("updaterGroupBox");
|
||||
#endif
|
||||
} else if (elementName == "GUIBackgroundImageGroupBox") {
|
||||
text = tr("GUIBackgroundImageGroupBox");
|
||||
} else if (elementName == "GUIMusicGroupBox") {
|
||||
text = tr("GUIMusicGroupBox");
|
||||
} else if (elementName == "disableTrophycheckBox") {
|
||||
|
@ -638,6 +646,9 @@ void SettingsDialog::UpdateSettings() {
|
|||
Config::setChooseHomeTab(ui->chooseHomeTabComboBox->currentText().toStdString());
|
||||
Config::setCompatibilityEnabled(ui->enableCompatibilityCheckBox->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
|
||||
auto* rpc = Common::Singleton<DiscordRPCHandler::RPC>::Instance();
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
signals:
|
||||
void LanguageChanged(const std::string& locale);
|
||||
void CompatibilityChanged();
|
||||
void BackgroundOpacityChanged(int opacity);
|
||||
|
||||
private:
|
||||
void LoadValuesFromConfig();
|
||||
|
|
|
@ -583,6 +583,76 @@
|
|||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
<widget class="QGroupBox" name="GUIMusicGroupBox">
|
||||
<property name="sizePolicy">
|
||||
|
|
|
@ -757,6 +757,18 @@
|
|||
<source>Disable Trophy Pop-ups</source>
|
||||
<translation>Disable Trophy Pop-ups</translation>
|
||||
</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>
|
||||
<source>Play title music</source>
|
||||
<translation>Play title music</translation>
|
||||
|
@ -853,6 +865,10 @@
|
|||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<source>GUIBackgroundImageGroupBox</source>
|
||||
<translation>Background Image:\nControl the opacity of the game background image.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>GUIMusicGroupBox</source>
|
||||
<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>
|
||||
<translation>Disable Trophy Pop-ups</translation>
|
||||
</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>
|
||||
<source>Play title music</source>
|
||||
<translation>Reproducir la música de apertura</translation>
|
||||
|
@ -844,6 +856,10 @@
|
|||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<source>GUIBackgroundImageGroupBox</source>
|
||||
<translation>Imagen de fondo:\nControle la opacidad de la imagen de fondo del juego.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
|
|
Loading…
Add table
Reference in a new issue