From 0180ec060b2917f24976a4e641d92d787cd8dc80 Mon Sep 17 00:00:00 2001 From: Stern Date: Sun, 14 Dec 2025 09:08:34 -0500 Subject: [PATCH] FSUI/Qt: Add Center/Tile background modes and remove redundant Qt null checks (#13564) Signed-off-by: SternXD Signed-off-by: SternXD --- common/Image.cpp | 2 +- pcsx2-qt/GameList/GameListWidget.cpp | 60 +++++--- pcsx2-qt/GameList/GameListWidget.h | 4 + pcsx2-qt/MainWindow.cpp | 6 + pcsx2-qt/MainWindow.h | 1 + pcsx2-qt/QtHost.cpp | 3 + pcsx2-qt/QtUtils.cpp | 44 +++--- pcsx2-qt/Settings/BIOSSettingsWidget.cpp | 2 + pcsx2-qt/Settings/InterfaceSettingsWidget.cpp | 2 +- pcsx2/ImGui/FullscreenUI.cpp | 130 +++++++++++++----- pcsx2/ImGui/ImGuiFullscreen.cpp | 8 +- 11 files changed, 181 insertions(+), 81 deletions(-) diff --git a/common/Image.cpp b/common/Image.cpp index f54af12011..3cc1fcb075 100644 --- a/common/Image.cpp +++ b/common/Image.cpp @@ -1148,7 +1148,7 @@ bool BMPBufferLoader(RGBA8Image* image, const void* buffer, size_t buffer_size) return false; } - if (width > 65536 || height > 65536) + if (width >= 65536 || height >= 65536) { Console.Error("BMP dimensions too large: %ux%u", width, height); return false; diff --git a/pcsx2-qt/GameList/GameListWidget.cpp b/pcsx2-qt/GameList/GameListWidget.cpp index f1a2ef5e4a..3d724bbe68 100644 --- a/pcsx2-qt/GameList/GameListWidget.cpp +++ b/pcsx2-qt/GameList/GameListWidget.cpp @@ -220,6 +220,8 @@ void GameListWidget::initialize() m_sort_model->setSourceModel(m_model); m_ui.setupUi(this); + m_ui.stack->installEventFilter(this); + m_ui.stack->setAutoFillBackground(false); for (u32 type = 0; type < static_cast(GameList::EntryType::Count); type++) { @@ -353,6 +355,7 @@ void GameListWidget::setCustomBackground() m_background_movie = nullptr; } + // Get the path to the custom background std::string path = Host::GetBaseStringSettingValue("UI", "GameListBackgroundPath"); if (!Path::IsAbsolute(path)) path = Path::Combine(EmuFolders::DataRoot, path); @@ -360,27 +363,26 @@ void GameListWidget::setCustomBackground() // Only try to create background if path are valid if (!path.empty() && FileSystem::FileExists(path.c_str())) { - QMovie* new_movie; QString img_path = QString::fromStdString(path); - if (img_path.endsWith(".png", Qt::CaseInsensitive)) - // Use apng plugin - new_movie = new QMovie(img_path, "apng", this); - else - new_movie = new QMovie(img_path, QByteArray(), this); - - if (new_movie->isValid()) - m_background_movie = new_movie; - else + const QByteArray format = (img_path.endsWith(".png", Qt::CaseInsensitive)) ? QByteArray("apng") : QByteArray(); + m_background_movie = new QMovie(img_path, format, this); + if (!m_background_movie->isValid()) { Console.Warning("Failed to load background movie from: %s", path.c_str()); - delete new_movie; + delete m_background_movie; + m_background_movie = nullptr; } } // If there is no valid background then reset fallback to default UI state if (!m_background_movie) { - m_ui.stack->setPalette(QApplication::palette()); + m_background_pixmap = QPixmap(); + m_ui.stack->setAutoFillBackground(true); + m_table_view->viewport()->setAutoFillBackground(true); + m_list_view->viewport()->setAutoFillBackground(true); + + m_ui.stack->update(); m_table_view->setAlternatingRowColors(true); return; } @@ -390,7 +392,7 @@ void GameListWidget::setCustomBackground() const std::string ar_value = Host::GetBaseStringSettingValue("UI", "GameListBackgroundMode", InterfaceSettingsWidget::BACKGROUND_SCALE_NAMES[static_cast(QtUtils::ScalingMode::Fit)]); for (u8 i = 0; i < static_cast(QtUtils::ScalingMode::MaxCount); i++) { - if (!(InterfaceSettingsWidget::BACKGROUND_SCALE_NAMES[i] == nullptr)) + if (InterfaceSettingsWidget::BACKGROUND_SCALE_NAMES[i] != nullptr) { if (ar_value == InterfaceSettingsWidget::BACKGROUND_SCALE_NAMES[i]) { @@ -405,8 +407,13 @@ void GameListWidget::setCustomBackground() // Selected Custom background is valid, connect the signals and start animation in gamelist connect(m_background_movie, &QMovie::frameChanged, this, &GameListWidget::processBackgroundFrames, Qt::UniqueConnection); + m_ui.stack->setAutoFillBackground(false); + + m_table_view->viewport()->setAutoFillBackground(false); + m_list_view->viewport()->setAutoFillBackground(false); updateCustomBackgroundState(true); m_table_view->setAlternatingRowColors(false); + processBackgroundFrames(); } void GameListWidget::updateCustomBackgroundState(const bool force_start) @@ -422,7 +429,7 @@ void GameListWidget::updateCustomBackgroundState(const bool force_start) void GameListWidget::processBackgroundFrames() { - if (m_background_movie && m_background_movie->isValid()) + if (m_background_movie && m_background_movie->isValid() && isVisible()) { const int widget_width = m_ui.stack->width(); const int widget_height = m_ui.stack->height(); @@ -435,9 +442,8 @@ void GameListWidget::processBackgroundFrames() QtUtils::resizeAndScalePixmap(&pm, widget_width, widget_height, dpr, m_background_scaling, m_background_opacity); - QPalette bg_palette(m_ui.stack->palette()); - bg_palette.setBrush(QPalette::Base, pm); - m_ui.stack->setPalette(bg_palette); + m_background_pixmap = std::move(pm); + m_ui.stack->update(); } } @@ -725,6 +731,7 @@ bool GameListWidget::event(QEvent* event) if (event->type() == QEvent::DevicePixelRatioChange) { m_model->setDevicePixelRatio(devicePixelRatioF()); + processBackgroundFrames(); QWidget::event(event); return true; } @@ -732,6 +739,25 @@ bool GameListWidget::event(QEvent* event) return QWidget::event(event); } +bool GameListWidget::eventFilter(QObject* watched, QEvent* event) +{ + if (watched == m_ui.stack && event->type() == QEvent::Paint) + { + if (!m_background_pixmap.isNull()) + { + QPainter painter(m_ui.stack); + const auto* paint_event = static_cast(event); + painter.save(); + painter.setClipRect(paint_event->rect()); + painter.drawTiledPixmap(m_ui.stack->rect(), m_background_pixmap); + painter.restore(); + return true; + } + } + + return QWidget::eventFilter(watched, event); +} + void GameListWidget::resizeTableViewColumnsToFit() { QtUtils::ResizeColumnsForTableView(m_table_view, { diff --git a/pcsx2-qt/GameList/GameListWidget.h b/pcsx2-qt/GameList/GameListWidget.h index 2e4d5ddf31..ce4cb4d244 100644 --- a/pcsx2-qt/GameList/GameListWidget.h +++ b/pcsx2-qt/GameList/GameListWidget.h @@ -10,7 +10,9 @@ #include "pcsx2/GameList.h" #include +#include #include +#include #include Q_DECLARE_METATYPE(const GameList::Entry*); @@ -101,6 +103,7 @@ protected: void hideEvent(QHideEvent* event) override; void resizeEvent(QResizeEvent* event) override; bool event(QEvent* event) override; + bool eventFilter(QObject* watched, QEvent* event) override; private: void loadTableHeaderState(); @@ -123,6 +126,7 @@ private: GameListRefreshThread* m_refresh_thread = nullptr; QMovie* m_background_movie = nullptr; + QPixmap m_background_pixmap; QtUtils::ScalingMode m_background_scaling = QtUtils::ScalingMode::Fit; float m_background_opacity = 100.0f; }; diff --git a/pcsx2-qt/MainWindow.cpp b/pcsx2-qt/MainWindow.cpp index 3ee4dd9988..13d55c3cd0 100644 --- a/pcsx2-qt/MainWindow.cpp +++ b/pcsx2-qt/MainWindow.cpp @@ -1193,6 +1193,12 @@ void MainWindow::cancelGameListRefresh() m_game_list_widget->cancelRefresh(); } +void MainWindow::updateGameListBackground() +{ + if (m_game_list_widget) + m_game_list_widget->setCustomBackground(); +} + void MainWindow::reportInfo(const QString& title, const QString& message) { QMessageBox::information(this, title, message); diff --git a/pcsx2-qt/MainWindow.h b/pcsx2-qt/MainWindow.h index 4da2fa9133..2f5bbff616 100644 --- a/pcsx2-qt/MainWindow.h +++ b/pcsx2-qt/MainWindow.h @@ -116,6 +116,7 @@ public Q_SLOTS: void checkForUpdates(bool display_message, bool force_check); void refreshGameList(bool invalidate_cache, bool popup_on_error); void cancelGameListRefresh(); + void updateGameListBackground(); void reportInfo(const QString& title, const QString& message); void reportError(const QString& title, const QString& message); bool confirmMessage(const QString& title, const QString& message); diff --git a/pcsx2-qt/QtHost.cpp b/pcsx2-qt/QtHost.cpp index e367756d15..902c400597 100644 --- a/pcsx2-qt/QtHost.cpp +++ b/pcsx2-qt/QtHost.cpp @@ -194,6 +194,9 @@ void EmuThread::stopFullscreenUI() { m_run_fullscreen_ui.store(false, std::memory_order_release); emit onFullscreenUIStateChange(false); + + // Resume and refresh background when FullscreenUI exits + QMetaObject::invokeMethod(g_main_window, "updateGameListBackground", Qt::QueuedConnection); } } diff --git a/pcsx2-qt/QtUtils.cpp b/pcsx2-qt/QtUtils.cpp index b0865fa52d..4f41681351 100644 --- a/pcsx2-qt/QtUtils.cpp +++ b/pcsx2-qt/QtUtils.cpp @@ -141,9 +141,16 @@ namespace QtUtils void resizeAndScalePixmap(QPixmap* pm, const int expected_width, const int expected_height, const qreal dpr, const ScalingMode scaling_mode, const float opacity) { - if (!pm || pm->isNull() || pm->width() <= 0 || pm->height() <= 0) + if (!pm || pm->width() <= 0 || pm->height() <= 0) return; + if (dpr <= 0.0) + { + Console.ErrorFmt("resizeAndScalePixmap: Invalid device pixel ratio ({}) - pixmap will be null", dpr); + *pm = QPixmap(); + return; + } + const int dpr_expected_width = qRound(expected_width * dpr); const int dpr_expected_height = qRound(expected_height * dpr); @@ -196,8 +203,7 @@ namespace QtUtils qRound(scaledSize.width()), qRound(scaledSize.height()), Qt::IgnoreAspectRatio, - Qt::SmoothTransformation - ); + Qt::SmoothTransformation); const QRectF scaledSrcRect(0, 0, pm->width(), pm->height()); @@ -211,16 +217,7 @@ namespace QtUtils } case ScalingMode::Stretch: { - *pm = pm->scaled( - dpr_expected_width, - dpr_expected_height, - Qt::IgnoreAspectRatio, - Qt::SmoothTransformation - ); - - const QRectF scaledSrcRect(0, 0, pm->width(), pm->height()); - - painter.drawPixmap(painterRect, *pm, scaledSrcRect); + painter.drawPixmap(painterRect, *pm, srcRect); break; } case ScalingMode::Center: @@ -229,7 +226,6 @@ namespace QtUtils const qreal pmHeight = pm->height() / dpr; QRectF destRect(0, 0, pmWidth, pmHeight); - destRect.moveCenter(painterRect.center()); painter.drawPixmap(destRect, *pm, srcRect); @@ -243,13 +239,19 @@ namespace QtUtils if (tileWidth <= 0 || tileHeight <= 0) break; - QPixmap tileSource = pm->scaled(tileWidth, tileHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation); - tileSource.setDevicePixelRatio(dpr); - - QBrush tileBrush(tileSource); - tileBrush.setTextureImage(tileSource.toImage()); - - painter.fillRect(painterRect, tileBrush); + if (pm->devicePixelRatio() == dpr) + { + QBrush tileBrush(*pm); + painter.fillRect(painterRect, tileBrush); + } + else + { + QPixmap tileSource = pm->scaled(tileWidth, tileHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation); + tileSource.setDevicePixelRatio(dpr); + QBrush tileBrush(tileSource); + tileBrush.setTextureImage(tileSource.toImage()); + painter.fillRect(painterRect, tileBrush); + } break; } default: diff --git a/pcsx2-qt/Settings/BIOSSettingsWidget.cpp b/pcsx2-qt/Settings/BIOSSettingsWidget.cpp index 71348a62e9..297070d808 100644 --- a/pcsx2-qt/Settings/BIOSSettingsWidget.cpp +++ b/pcsx2-qt/Settings/BIOSSettingsWidget.cpp @@ -39,6 +39,8 @@ BIOSSettingsWidget::BIOSSettingsWidget(SettingsWindow* settings_dialog, QWidget* connect(m_ui.refresh, &QPushButton::clicked, this, &BIOSSettingsWidget::refreshList); connect(m_ui.fileList, &QTreeWidget::currentItemChanged, this, &BIOSSettingsWidget::listItemChanged); connect(m_ui.fastBoot, &QCheckBox::checkStateChanged, this, &BIOSSettingsWidget::fastBootChanged); + + fastBootChanged(); } BIOSSettingsWidget::~BIOSSettingsWidget() = default; diff --git a/pcsx2-qt/Settings/InterfaceSettingsWidget.cpp b/pcsx2-qt/Settings/InterfaceSettingsWidget.cpp index 66406c0a2b..4d23a68ffc 100644 --- a/pcsx2-qt/Settings/InterfaceSettingsWidget.cpp +++ b/pcsx2-qt/Settings/InterfaceSettingsWidget.cpp @@ -275,7 +275,7 @@ void InterfaceSettingsWidget::onSetGameListBackgroundTriggered() if (path.isEmpty()) return; - std::string relative_path = Path::MakeRelative(QDir::toNativeSeparators(path).toStdString(), EmuFolders::DataRoot); + std::string relative_path = Path::MakeRelative(path.toStdString(), EmuFolders::DataRoot); Host::SetBaseStringSettingValue("UI", "GameListBackgroundPath", relative_path.c_str()); Host::CommitBaseSettingChanges(); diff --git a/pcsx2/ImGui/FullscreenUI.cpp b/pcsx2/ImGui/FullscreenUI.cpp index 8d2add5d54..74402094ff 100644 --- a/pcsx2/ImGui/FullscreenUI.cpp +++ b/pcsx2/ImGui/FullscreenUI.cpp @@ -1221,7 +1221,7 @@ void FullscreenUI::Render() // see if background setting changed static std::string s_last_background_path; - std::string current_path = Host::GetBaseStringSettingValue("UI", "GameListBackgroundPath"); + std::string current_path = Host::GetBaseStringSettingValue("UI", "FSUIBackgroundPath"); if (s_last_background_path != current_path) { s_last_background_path = current_path; @@ -1240,7 +1240,8 @@ void FullscreenUI::Render() s_current_main_window == MainWindowType::Exit || s_current_main_window == MainWindowType::GameList || s_current_main_window == MainWindowType::GameListSettings || - s_current_main_window == MainWindowType::Settings) && s_custom_background_enabled && s_custom_background_texture; + s_current_main_window == MainWindowType::Settings) && + !VMManager::HasValidVM() && s_custom_background_enabled && s_custom_background_texture; ImVec4 original_background_color; if (should_draw_background) @@ -1691,7 +1692,7 @@ bool FullscreenUI::ShouldDefaultToGameList() void FullscreenUI::LoadCustomBackground() { - std::string path = Host::GetBaseStringSettingValue("UI", "GameListBackgroundPath"); + std::string path = Host::GetBaseStringSettingValue("UI", "FSUIBackgroundPath"); if (path.empty()) { @@ -1759,19 +1760,25 @@ void FullscreenUI::DrawCustomBackground() const ImGuiIO& io = ImGui::GetIO(); const ImVec2 display_size = io.DisplaySize; - const float opacity = Host::GetBaseFloatSettingValue("UI", "GameListBackgroundOpacity", 100.0f) / 100.0f; - const std::string mode = Host::GetBaseStringSettingValue("UI", "GameListBackgroundMode", "fit"); + const u8 alpha = static_cast(Host::GetBaseFloatSettingValue("UI", "FSUIBackgroundOpacity", 100.0f) * 2.55f); + const std::string mode = Host::GetBaseStringSettingValue("UI", "FSUIBackgroundMode", "fit"); const float tex_width = static_cast(s_custom_background_texture->GetWidth()); const float tex_height = static_cast(s_custom_background_texture->GetHeight()); - ImVec2 img_min, img_max; + // Override the UIBackgroundColor that windows use + // We need to make windows transparent so our background image shows through + const ImVec4 transparent_bg = ImVec4(UIBackgroundColor.x, UIBackgroundColor.y, UIBackgroundColor.z, 0.0f); + ImGuiFullscreen::UIBackgroundColor = transparent_bg; + + ImDrawList* bg_draw_list = ImGui::GetBackgroundDrawList(); + const ImU32 col = IM_COL32(255, 255, 255, alpha); + const ImTextureID tex_id = reinterpret_cast(s_custom_background_texture->GetNativeHandle()); if (mode == "stretch") { // stretch to fill entire display (ignores aspect ratio) - img_min = ImVec2(0.0f, 0.0f); - img_max = display_size; + bg_draw_list->AddImage(tex_id, ImVec2(0.0f, 0.0f), display_size, ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), col); } else if (mode == "fill") { @@ -1796,8 +1803,64 @@ void FullscreenUI::DrawCustomBackground() const float offset_x = (display_size.x - scaled_width) * 0.5f; const float offset_y = (display_size.y - scaled_height) * 0.5f; - img_min = ImVec2(offset_x, offset_y); - img_max = ImVec2(offset_x + scaled_width, offset_y + scaled_height); + bg_draw_list->AddImage(tex_id, + ImVec2(offset_x, offset_y), + ImVec2(offset_x + scaled_width, offset_y + scaled_height), + ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), col); + } + else if (mode == "center") + { + // Center image at original size + const float offset_x = (display_size.x - tex_width) * 0.5f; + const float offset_y = (display_size.y - tex_height) * 0.5f; + + bg_draw_list->AddImage(tex_id, + ImVec2(offset_x, offset_y), + ImVec2(offset_x + tex_width, offset_y + tex_height), + ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), col); + } + else if (mode == "tile") + { + // Tile image across entire display + // If the image is extremely small, this approach can generate millions of quads + // and overflow the backend stream buffer (e.g. Vulkan assertion in VKStreamBuffer). + // Since we cannot switch ImGui's sampler to wrap (yet), clamp the maximum number of quads + constexpr int MAX_TILE_QUADS = 16384; + + float tile_width = tex_width; + float tile_height = tex_height; + int tiles_x = static_cast(std::ceil(display_size.x / tile_width)); + int tiles_y = static_cast(std::ceil(display_size.y / tile_height)); + + const int total_tiles = tiles_x * tiles_y; + if (total_tiles > MAX_TILE_QUADS) + { + const float scale = std::sqrt(static_cast(total_tiles) / static_cast(MAX_TILE_QUADS)); + tile_width *= scale; + tile_height *= scale; + tiles_x = static_cast(std::ceil(display_size.x / tile_width)); + tiles_y = static_cast(std::ceil(display_size.y / tile_height)); + } + + for (int y = 0; y < tiles_y; y++) + { + for (int x = 0; x < tiles_x; x++) + { + const float tile_x = static_cast(x) * tile_width; + const float tile_y = static_cast(y) * tile_height; + const float tile_max_x = std::min(tile_x + tile_width, display_size.x); + const float tile_max_y = std::min(tile_y + tile_height, display_size.y); + + // get uvs for partial tiles at edges + const float uv_max_x = (tile_max_x - tile_x) / tile_width; + const float uv_max_y = (tile_max_y - tile_y) / tile_height; + + bg_draw_list->AddImage(tex_id, + ImVec2(tile_x, tile_y), + ImVec2(tile_max_x, tile_max_y), + ImVec2(0.0f, 0.0f), ImVec2(uv_max_x, uv_max_y), col); + } + } } else // "fit" or default { @@ -1822,19 +1885,11 @@ void FullscreenUI::DrawCustomBackground() const float offset_x = (display_size.x - scaled_width) * 0.5f; const float offset_y = (display_size.y - scaled_height) * 0.5f; - img_min = ImVec2(offset_x, offset_y); - img_max = ImVec2(offset_x + scaled_width, offset_y + scaled_height); + bg_draw_list->AddImage(tex_id, + ImVec2(offset_x, offset_y), + ImVec2(offset_x + scaled_width, offset_y + scaled_height), + ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), col); } - - // Override the UIBackgroundColor that windows use - // We need to make windows transparent so our background image shows through - const ImVec4 transparent_bg = ImVec4(UIBackgroundColor.x, UIBackgroundColor.y, UIBackgroundColor.z, 0.0f); - ImGuiFullscreen::UIBackgroundColor = transparent_bg; - - ImDrawList* bg_draw_list = ImGui::GetBackgroundDrawList(); - const ImU32 col = IM_COL32(255, 255, 255, static_cast(opacity * 255.0f)); - bg_draw_list->AddImage(reinterpret_cast(s_custom_background_texture->GetNativeHandle()), - img_min, img_max, ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), col); } ////////////////////////////////////////////////////////////////////////// @@ -3630,7 +3685,7 @@ void FullscreenUI::DrawSettingsWindow() ImVec2(io.DisplaySize.x, LayoutScale(LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY) + (LayoutScale(LAYOUT_MENU_BUTTON_Y_PADDING) * 2.0f) + LayoutScale(2.0f)); - const bool using_custom_bg = s_custom_background_enabled && s_custom_background_texture; + const bool using_custom_bg = !VMManager::HasValidVM() && s_custom_background_enabled && s_custom_background_texture; const float header_bg_alpha = VMManager::HasValidVM() ? 0.90f : 1.0f; const float content_bg_alpha = using_custom_bg ? 0.0f : (VMManager::HasValidVM() ? 0.90f : 1.0f); SettingsInterface* bsi = GetEditingSettingsInterface(); @@ -4053,21 +4108,19 @@ void FullscreenUI::DrawInterfaceSettingsPage() MenuHeading(FSUI_CSTR("Background")); - std::string background_path = bsi->GetStringValue("UI", "GameListBackgroundPath", ""); - const bool background_enabled = bsi->GetBoolValue("UI", "GameListBackgroundEnabled", false); + std::string background_path = bsi->GetStringValue("UI", "FSUIBackgroundPath", ""); std::string background_display = FSUI_STR("None"); - if (!background_path.empty() && background_enabled) + if (!background_path.empty()) { background_display = Path::GetFileName(background_path); } if (MenuButtonWithValue(FSUI_ICONSTR(ICON_FA_IMAGE, "Background Image"), - FSUI_CSTR("Select a custom background image to use in Big Picture Mode menus."), + FSUI_CSTR("Select a custom background image to use in Big Picture Mode menus.\n\nSupported formats: PNG, JPG, JPEG, BMP."), background_display.c_str())) { - OpenFileSelector(FSUI_ICONSTR(ICON_FA_IMAGE, "Select Background Image"), false, - [](const std::string& path) { + OpenFileSelector(FSUI_ICONSTR(ICON_FA_IMAGE, "Select Background Image"), false, [](const std::string& path) { if (!path.empty()) { { @@ -4075,23 +4128,20 @@ void FullscreenUI::DrawInterfaceSettingsPage() SettingsInterface* bsi = GetEditingSettingsInterface(false); std::string relative_path = Path::MakeRelative(path, EmuFolders::DataRoot); - bsi->SetStringValue("UI", "GameListBackgroundPath", relative_path.c_str()); - bsi->SetBoolValue("UI", "GameListBackgroundEnabled", true); + bsi->SetStringValue("UI", "FSUIBackgroundPath", relative_path.c_str()); + bsi->SetBoolValue("UI", "FSUIBackgroundEnabled", true); SetSettingsChanged(bsi); } LoadCustomBackground(); } - CloseFileSelector(); - }, - GetImageFileFilters()); + CloseFileSelector(); }, GetImageFileFilters()); } if (MenuButton(FSUI_ICONSTR(ICON_FA_XMARK, "Clear Background Image"), FSUI_CSTR("Removes the custom background image."))) { - bsi->DeleteValue("UI", "GameListBackgroundPath"); - bsi->SetBoolValue("UI", "GameListBackgroundEnabled", false); + bsi->DeleteValue("UI", "FSUIBackgroundPath"); SetSettingsChanged(bsi); s_custom_background_texture.reset(); @@ -4101,21 +4151,25 @@ void FullscreenUI::DrawInterfaceSettingsPage() DrawIntRangeSetting(bsi, FSUI_ICONSTR(ICON_FA_DROPLET, "Background Opacity"), FSUI_CSTR("Sets the transparency of the custom background image."), - "UI", "GameListBackgroundOpacity", 100, 0, 100, "%d%%"); + "UI", "FSUIBackgroundOpacity", 100, 0, 100, "%d%%"); static constexpr const char* s_background_mode_names[] = { FSUI_NSTR("Fit"), FSUI_NSTR("Fill"), FSUI_NSTR("Stretch"), + FSUI_NSTR("Center"), + FSUI_NSTR("Tile"), }; static constexpr const char* s_background_mode_values[] = { "fit", "fill", "stretch", + "center", + "tile", }; DrawStringListSetting(bsi, FSUI_ICONSTR(ICON_FA_EXPAND, "Background Mode"), FSUI_CSTR("Select how to display the background image."), - "UI", "GameListBackgroundMode", "fit", s_background_mode_names, s_background_mode_values, std::size(s_background_mode_names), true); + "UI", "FSUIBackgroundMode", "fit", s_background_mode_names, s_background_mode_values, std::size(s_background_mode_names), true); MenuHeading(FSUI_CSTR("Behaviour")); DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_PF_SNOOZE, "Inhibit Screensaver"), diff --git a/pcsx2/ImGui/ImGuiFullscreen.cpp b/pcsx2/ImGui/ImGuiFullscreen.cpp index 9216e2a560..28fae3f2d4 100644 --- a/pcsx2/ImGui/ImGuiFullscreen.cpp +++ b/pcsx2/ImGui/ImGuiFullscreen.cpp @@ -2396,6 +2396,7 @@ void ImGuiFullscreen::DrawChoiceDialog() ImGui::PushStyleColor(ImGuiCol_Text, UIPrimaryTextColor); ImGui::PushStyleColor(ImGuiCol_TitleBg, UIPrimaryDarkColor); ImGui::PushStyleColor(ImGuiCol_TitleBgActive, UIPrimaryColor); + ImGui::PushStyleColor(ImGuiCol_PopupBg, UIPopupBackgroundColor); const float width = LayoutScale(600.0f); const float title_height = g_large_font.second + ImGui::GetStyle().FramePadding.y * 2.0f + ImGui::GetStyle().WindowPadding.y * 2.0f; @@ -2464,7 +2465,7 @@ void ImGuiFullscreen::DrawChoiceDialog() is_open = false; } - ImGui::PopStyleColor(3); + ImGui::PopStyleColor(4); ImGui::PopStyleVar(3); ImGui::PopFont(); @@ -2523,7 +2524,7 @@ void ImGuiFullscreen::DrawInputDialog() ImGui::PushStyleColor(ImGuiCol_Text, UIPrimaryTextColor); ImGui::PushStyleColor(ImGuiCol_TitleBg, UIPrimaryDarkColor); ImGui::PushStyleColor(ImGuiCol_TitleBgActive, UIPrimaryColor); - ImGui::PushStyleColor(ImGuiCol_PopupBg, UIBackgroundColor); + ImGui::PushStyleColor(ImGuiCol_PopupBg, UIPopupBackgroundColor); bool is_open = true; if (ImGui::BeginPopupModal(s_input_dialog_title.c_str(), &is_open, @@ -2715,6 +2716,7 @@ void ImGuiFullscreen::DrawMessageDialog() ImGui::PushStyleColor(ImGuiCol_Text, UIPrimaryTextColor); ImGui::PushStyleColor(ImGuiCol_TitleBg, UIPrimaryDarkColor); ImGui::PushStyleColor(ImGuiCol_TitleBgActive, UIPrimaryColor); + ImGui::PushStyleColor(ImGuiCol_PopupBg, UIPopupBackgroundColor); bool is_open = true; const u32 flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | @@ -2745,7 +2747,7 @@ void ImGuiFullscreen::DrawMessageDialog() ImGui::EndPopup(); } - ImGui::PopStyleColor(3); + ImGui::PopStyleColor(4); ImGui::PopStyleVar(4); ImGui::PopFont();