diff --git a/pcsx2-qt/GameList/GameListWidget.cpp b/pcsx2-qt/GameList/GameListWidget.cpp index 394366518f..d798be21c8 100644 --- a/pcsx2-qt/GameList/GameListWidget.cpp +++ b/pcsx2-qt/GameList/GameListWidget.cpp @@ -304,7 +304,7 @@ void GameListWidget::initialize() setCustomBackground(); } -static void resizeAndPadImage(QImage* image, int expected_width, int expected_height, bool fill_with_top_left) +static void resizeAndPadImage(QImage* image, int expected_width, int expected_height, bool fill_with_top_left, bool expand_to_fill) { const qreal dpr = image->devicePixelRatio(); const int dpr_expected_width = static_cast(static_cast(expected_width) * dpr); @@ -313,8 +313,8 @@ static void resizeAndPadImage(QImage* image, int expected_width, int expected_he return; // Resize - if ((static_cast(image->width()) / static_cast(image->height())) >= - (static_cast(dpr_expected_width) / static_cast(dpr_expected_height))) + if (((static_cast(image->width()) / static_cast(image->height())) >= + (static_cast(dpr_expected_width) / static_cast(dpr_expected_height))) != expand_to_fill) { *image = image->scaledToWidth(dpr_expected_width, Qt::SmoothTransformation); } @@ -331,9 +331,9 @@ static void resizeAndPadImage(QImage* image, int expected_width, int expected_he int yoffs = 0; const int image_width = image->width(); const int image_height = image->height(); - if (image_width < dpr_expected_width) + if ((image_width < dpr_expected_width) != expand_to_fill) xoffs = static_cast(static_cast((dpr_expected_width - image_width) / 2) / dpr); - if (image_height < dpr_expected_height) + if ((image_height < dpr_expected_height) != expand_to_fill) yoffs = static_cast(static_cast((dpr_expected_height - image_height) / 2) / dpr); QImage padded_image(dpr_expected_width, dpr_expected_height, QImage::Format_ARGB32); @@ -348,7 +348,7 @@ static void resizeAndPadImage(QImage* image, int expected_width, int expected_he const float opacity = Host::GetBaseFloatSettingValue("UI", "GameListBackgroundOpacity"); if (painter.begin(&padded_image)) { - painter.setOpacity((static_cast(opacity / 100.0f))); // Qt expect range from 0.0 to 1.0 + painter.setOpacity((static_cast(opacity / 100.0f))); // Qt expects the range to be from 0.0 to 1.0 painter.setCompositionMode(QPainter::CompositionMode_Source); painter.drawImage(xoffs, yoffs, *image); painter.end(); @@ -361,6 +361,7 @@ void GameListWidget::setCustomBackground(bool force_refresh) { std::string path = Host::GetBaseStringSettingValue("UI", "GameListBackgroundPath"); bool enabled = Host::GetBaseBoolSettingValue("UI", "GameListBackgroundEnabled"); + bool fill = Host::GetBaseBoolSettingValue("UI", "GameListBackgroundFill"); // Cleanup old animation if it still exists on gamelist if (m_background_movie != nullptr) @@ -400,7 +401,7 @@ void GameListWidget::setCustomBackground(bool force_refresh) } // Background is valid, connect the signals and start animation in gamelist - connect(m_background_movie, &QMovie::frameChanged, this, [this]() { processBackgroundFrames(); }); + connect(m_background_movie, &QMovie::frameChanged, this, [this, fill]() { processBackgroundFrames(fill); }); updateCustomBackgroundState(force_refresh); m_table_view->setAlternatingRowColors(false); @@ -417,14 +418,14 @@ void GameListWidget::updateCustomBackgroundState(bool force_start) } } -void GameListWidget::processBackgroundFrames() +void GameListWidget::processBackgroundFrames(bool fill_area) { QImage img = m_background_movie->currentImage(); img.setDevicePixelRatio(devicePixelRatioF()); const int widget_width = m_ui.stack->width(); const int widget_height = m_ui.stack->height(); - resizeAndPadImage(&img, widget_width, widget_height, false); + resizeAndPadImage(&img, widget_width, widget_height, false, fill_area); QPalette new_palette(m_ui.stack->palette()); new_palette.setBrush(QPalette::Base, img); diff --git a/pcsx2-qt/GameList/GameListWidget.h b/pcsx2-qt/GameList/GameListWidget.h index d4d7de93c0..0608362d22 100644 --- a/pcsx2-qt/GameList/GameListWidget.h +++ b/pcsx2-qt/GameList/GameListWidget.h @@ -51,7 +51,7 @@ public: void reloadThemeSpecificImages(); void setCustomBackground(bool force = false); void updateCustomBackgroundState(bool force_start = false); - void processBackgroundFrames(); + void processBackgroundFrames(bool fill_area); bool isShowingGameList() const; bool isShowingGameGrid() const; diff --git a/pcsx2-qt/SettingWidgetBinder.h b/pcsx2-qt/SettingWidgetBinder.h index 858b6ae211..1020a47f86 100644 --- a/pcsx2-qt/SettingWidgetBinder.h +++ b/pcsx2-qt/SettingWidgetBinder.h @@ -1263,7 +1263,7 @@ namespace SettingWidgetBinder static inline void BindWidgetToFileSetting(SettingsInterface* sif, QLineEdit* widget, QAbstractButton* browse_button, QAbstractButton* open_button, QAbstractButton* reset_button, std::string section, std::string key, std::string default_value, - const char* filter, bool allow_pergame = true, bool use_relative = true) + const char* filter, bool allow_pergame = false, bool use_relative = true) { using Accessor = SettingAccessor; diff --git a/pcsx2-qt/Settings/InterfaceSettingsWidget.cpp b/pcsx2-qt/Settings/InterfaceSettingsWidget.cpp index c7e154c5f2..abfa7e5cc3 100644 --- a/pcsx2-qt/Settings/InterfaceSettingsWidget.cpp +++ b/pcsx2-qt/Settings/InterfaceSettingsWidget.cpp @@ -110,9 +110,11 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsWindow* settings_dialog connect(m_ui.theme, QOverload::of(&QComboBox::currentIndexChanged), [this]() { emit themeChanged(); }); SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.backgroundOpacity, "UI", "GameListBackgroundOpacity", 100); + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.backgroundFill, "UI", "GameListBackgroundFill", false); connect(m_ui.backgroundBrowse, &QPushButton::clicked, [this]() { onSetGameListBackgroundTriggered(); }); connect(m_ui.backgroundReset, &QPushButton::clicked, [this]() { onClearGameListBackgroundTriggered(); }); connect(m_ui.backgroundOpacity, &QSpinBox::valueChanged, [this]() { emit backgroundChanged(); }); + connect(m_ui.backgroundFill, &QCheckBox::checkStateChanged, [this]() {emit backgroundChanged(); }); populateLanguages(); SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.language, "UI", "Language", QtHost::GetDefaultLanguage()); @@ -195,9 +197,18 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsWindow* settings_dialog m_ui.startFullscreenUI, tr("Start Big Picture Mode"), tr("Unchecked"), tr("Automatically starts Big Picture Mode instead of the regular Qt interface when PCSX2 launches.")); dialog()->registerWidgetHelp( - m_ui.backgroundBrowse, tr("Game List Background"), tr("Any"), + m_ui.backgroundBrowse, tr("Game List Background"), tr("None"), tr("Enable an animated / static background on the game list (where you launch your games).
" "This background is only visible in the library and will be hidden once a game is launched. It will also be paused when it's not in focus.")); + dialog()->registerWidgetHelp( + m_ui.backgroundReset, tr("Disable/Reset Game List Background"), tr("None"), + tr("Disable and reset the currently applied game list background.")); + dialog()->registerWidgetHelp( + m_ui.backgroundOpacity, tr("Game List Background Opacity"), tr("100%"), + tr("Sets the opacity of the custom background.")); + dialog()->registerWidgetHelp( + m_ui.backgroundFill, tr("Fill Image"), tr("Unchecked"), + tr("Expand the image to fill all available background area.")); onRenderToSeparateWindowChanged(); } @@ -219,6 +230,7 @@ void InterfaceSettingsWidget::onSetGameListBackgroundTriggered() { const QString path = QDir::toNativeSeparators( QFileDialog::getOpenFileName(this, tr("Select Background Image"), QString(), IMAGE_FILE_FILTER)); + if (path.isEmpty()) return; diff --git a/pcsx2-qt/Settings/InterfaceSettingsWidget.ui b/pcsx2-qt/Settings/InterfaceSettingsWidget.ui index 78b23d65fa..8333c3122a 100644 --- a/pcsx2-qt/Settings/InterfaceSettingsWidget.ui +++ b/pcsx2-qt/Settings/InterfaceSettingsWidget.ui @@ -145,6 +145,19 @@ Appearance + + + + + + + Language: + + + + + + @@ -152,6 +165,13 @@ + + + + Game List Background: + + + @@ -218,28 +238,15 @@ + + + + Fill Image + + + - - - - Game List Background: - - - - - - - - - - Language: - - - - - -