From 1c80e93070511ceb1eb6f8078c6a7697c12798eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 28 Jan 2026 11:00:04 +0100 Subject: [PATCH] Improve the appearance of unsupported ISO files --- UI/GameScreen.cpp | 12 +-- UI/MainScreen.cpp | 145 ++++++++++++++++++++++-------------- UI/UIAtlas.cpp | 4 + assets/ui_images/images.svg | 47 +++++++++++- 4 files changed, 144 insertions(+), 64 deletions(-) diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index 787e24e9b9..02fac91889 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -204,15 +204,15 @@ void GameScreen::CreateContentViews(UI::ViewGroup *parent) { const bool inGameDB = g_gameDB.GetGameInfos(info_->id_version, &dbInfos); if (knownFlags_ & GameInfoFlags::PARAM_SFO) { - // Show the game ID title below the icon. The top title will be from the DB. - std::string title = info_->GetTitle(); - - TextView *tvTitle = mainGameInfo->Add(new TextView(title, ALIGN_LEFT | FLAG_WRAP_TEXT, false, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); - tvTitle->SetShadow(true); - std::string regionID = ReplaceAll(info_->id_version, "_", " v"); if (!regionID.empty()) { regionID += ": "; + + // Show the game ID title below the icon. The top title will be from the DB. + std::string title = info_->GetTitle(); + + TextView *tvTitle = mainGameInfo->Add(new TextView(title, ALIGN_LEFT | FLAG_WRAP_TEXT, false, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); + tvTitle->SetShadow(true); } if (info_->region != GameRegion::UNKNOWN) { diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 79f60981a7..72cdafd0b5 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -114,6 +114,55 @@ static bool IsTempPath(const Path &str) { return false; } +static void DrawIconWithText(UIContext &dc, ImageID image, std::string_view text, const Bounds &bounds, bool gridStyle, const UI::Style &style) { + // This function is not used in the current code. + + float tw, th; + dc.MeasureText(dc.GetFontStyle(), gridStyle ? g_Config.fGameGridScale : 1.0, gridStyle ? g_Config.fGameGridScale : 1.0, text, &tw, &th, 0); + + bool compact = bounds.w < 180 * (gridStyle ? g_Config.fGameGridScale : 1.0); + if (compact) { + // No folder icon, except "up" + dc.PushScissor(bounds); + const FontStyle *fontStyle = GetTextStyle(dc, UI::TextSize::Small); + dc.SetFontStyle(*GetTextStyle(dc, UI::TextSize::Small)); + + int iconSize = image == ImageID("I_UP_DIRECTORY") ? (float)dc.Draw()->GetAtlas()->getImage(image)->h : bounds.h * 0.3f; + float textWidth = 0.0f; + float textHeight = 0; + dc.MeasureTextRect(*fontStyle, 1.0f, 1.0f, text, bounds.w - 10, &textWidth, &textHeight, ALIGN_HCENTER | FLAG_WRAP_TEXT); + + int totalHeight = iconSize + (int)textHeight; + + float y = bounds.h / 2.0f - totalHeight / 2.0f; + + if (image.isValid()) { + const AtlasImage *img = dc.Draw()->GetAtlas()->getImage(image); + if (img && img->h > 0) { + dc.Draw()->DrawImage(image, bounds.centerX(), bounds.y + y + 2, iconSize / (float)img->h, style.fgColor, ALIGN_TOP | ALIGN_HCENTER); + } + } + + if (image != ImageID("I_UP_DIRECTORY") && image != ImageID("I_PIN") && image != ImageID("I_UNPIN")) { + dc.DrawTextRect(text, bounds.Inset(5, y + iconSize + 4, 5, 2), style.fgColor, ALIGN_HCENTER | FLAG_WRAP_TEXT); + } + dc.SetFontStyle(dc.GetTheme().uiFont); + dc.PopScissor(); + } else { + bool scissor = false; + if (tw + 150 > bounds.w) { + dc.PushScissor(bounds); + scissor = true; + } + dc.Draw()->DrawImage(image, bounds.x + 72, bounds.centerY(), 0.88f * (gridStyle ? g_Config.fGameGridScale : 1.0), style.fgColor, ALIGN_CENTER); + dc.DrawText(text, bounds.x + 150, bounds.centerY(), style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT); + + if (scissor) { + dc.PopScissor(); + } + } +} + class GameButton : public UI::Clickable { public: GameButton(const Path &gamePath, bool gridStyle, UI::LayoutParams *layoutParams = nullptr) @@ -228,6 +277,38 @@ void GameButton::Draw(UIContext &dc) { u32 color = 0, shadowColor = 0; using namespace UI; + UI::Style style = dc.GetTheme().itemStyle; + if (down_) { + style = dc.GetTheme().itemDownStyle; + } + + // Some types we just draw a default icon for. + ImageID imageIcon = ImageID::invalid(); + switch (ginfo->fileType) { + case IdentifiedFileType::UNKNOWN_ELF: imageIcon = ImageID("I_DEBUGGER"); break; + case IdentifiedFileType::PPSSPP_GE_DUMP: imageIcon = ImageID("I_DISPLAY"); break; + case IdentifiedFileType::PSX_ISO: imageIcon = ImageID("I_PSX_ISO"); break; + case IdentifiedFileType::PSP_PS1_PBP: imageIcon = ImageID("I_PSX_ISO"); break; + case IdentifiedFileType::PS2_ISO: imageIcon = ImageID("I_PS2_ISO"); break; + case IdentifiedFileType::PS3_ISO: imageIcon = ImageID("I_PS3_ISO"); break; + case IdentifiedFileType::UNKNOWN_ISO: imageIcon = ImageID("I_UNKNOWN_ISO"); break; + case IdentifiedFileType::PPSSPP_SAVESTATE: + case IdentifiedFileType::ERROR_IDENTIFYING: + case IdentifiedFileType::UNKNOWN_BIN: imageIcon = ImageID("I_FILE"); break; + } + + if (imageIcon.isValid()) { + Style style = dc.GetTheme().itemStyle; + + if (HasFocus()) style = dc.GetTheme().itemFocusedStyle; + if (down_) style = dc.GetTheme().itemDownStyle; + if (!IsEnabled()) style = dc.GetTheme().itemDisabledStyle; + + dc.FillRect(style.background, bounds_); + DrawIconWithText(dc, imageIcon, ginfo->GetTitle(), bounds_, gridStyle_, style); + return; + } + if (ginfo->Ready(GameInfoFlags::ICON) && ginfo->icon.texture) { texture = ginfo->icon.texture; } @@ -237,10 +318,6 @@ void GameButton::Draw(UIContext &dc) { int w = gridStyle_ ? bounds_.w : 144; int h = bounds_.h; - UI::Style style = dc.GetTheme().itemStyle; - if (down_) - style = dc.GetTheme().itemDownStyle; - if (!gridStyle_ || !texture) { if (HasFocus()) style = down_ ? dc.GetTheme().itemDownStyle : dc.GetTheme().itemFocusedStyle; @@ -464,6 +541,14 @@ private: void DirButton::Draw(UIContext &dc) { using namespace UI; + + std::string_view text(GetText()); + ImageID image = ImageID(pinned_ ? "I_FOLDER_PINNED" : "I_FOLDER"); + if (text == "..") { + image = ImageID("I_UP_DIRECTORY"); + text = ""; + } + Style style = dc.GetTheme().itemStyle; if (HasFocus()) style = dc.GetTheme().itemFocusedStyle; @@ -471,55 +556,7 @@ void DirButton::Draw(UIContext &dc) { if (!IsEnabled()) style = dc.GetTheme().itemDisabledStyle; dc.FillRect(style.background, bounds_); - - std::string_view text(GetText()); - - ImageID image = ImageID(pinned_ ? "I_FOLDER_PINNED" : "I_FOLDER"); - if (text == "..") { - image = ImageID("I_UP_DIRECTORY"); - text = ""; - } - - float tw, th; - dc.MeasureText(dc.GetFontStyle(), gridStyle_ ? g_Config.fGameGridScale : 1.0, gridStyle_ ? g_Config.fGameGridScale : 1.0, text, &tw, &th, 0); - - bool compact = bounds_.w < 180 * (gridStyle_ ? g_Config.fGameGridScale : 1.0); - - if (compact) { - // No folder icon, except "up" - dc.PushScissor(bounds_); - const FontStyle *fontStyle = GetTextStyle(dc, UI::TextSize::Small); - dc.SetFontStyle(*GetTextStyle(dc, UI::TextSize::Small)); - - int iconSize = image == ImageID("I_UP_DIRECTORY") ? (float)dc.Draw()->GetAtlas()->getImage(image)->h : bounds_.h * 0.3f; - float textWidth = 0.0f; - float textHeight = 0; - dc.MeasureTextRect(*fontStyle, 1.0f, 1.0f, text, bounds_.w - 10, &textWidth, &textHeight, ALIGN_HCENTER | FLAG_WRAP_TEXT); - - int totalHeight = iconSize + (int)textHeight; - - float y = bounds_.h / 2.0f - totalHeight / 2.0f; - - dc.Draw()->DrawImage(image, bounds_.centerX(), bounds_.y + y + 2, iconSize / (float)dc.Draw()->GetAtlas()->getImage(image)->h, style.fgColor, ALIGN_TOP | ALIGN_HCENTER); - - if (image == ImageID("I_FOLDER") || image == ImageID("I_FOLDER_PINNED")) { - dc.DrawTextRect(text, bounds_.Inset(5, y + iconSize + 4, 5, 2), style.fgColor, ALIGN_HCENTER | FLAG_WRAP_TEXT); - } - dc.SetFontStyle(dc.GetTheme().uiFont); - dc.PopScissor(); - } else { - bool scissor = false; - if (tw + 150 > bounds_.w) { - dc.PushScissor(bounds_); - scissor = true; - } - dc.Draw()->DrawImage(image, bounds_.x + 72, bounds_.centerY(), 0.88f*(gridStyle_ ? g_Config.fGameGridScale : 1.0), style.fgColor, ALIGN_CENTER); - dc.DrawText(text, bounds_.x + 150, bounds_.centerY(), style.fgColor, ALIGN_VCENTER| FLAG_WRAP_TEXT); - - if (scissor) { - dc.PopScissor(); - } - } + DrawIconWithText(dc, image, text, bounds_, gridStyle_, style); } GameBrowser::GameBrowser(int token, const Path &path, BrowseFlags browseFlags, bool portrait, bool *gridStyle, ScreenManager *screenManager, std::string_view lastText, std::string_view lastLink, UI::LayoutParams *layoutParams) @@ -978,7 +1015,7 @@ void GameBrowser::Refresh() { if (!*gridStyle_) { caption = IsCurrentPathPinned() ? mm->T("UnpinPath", "Unpin") : mm->T("PinPath", "Pin"); } - UI::Button *pinButton = gameList_->Add(new UI::Button(caption, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::FILL_PARENT))); + UI::Button *pinButton = gameList_->Add(new Button(caption, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::FILL_PARENT))); pinButton->OnClick.Handle(this, &GameBrowser::PinToggleClick); pinButton->SetImageID(ImageID(IsCurrentPathPinned() ? "I_UNPIN" : "I_PIN")); } diff --git a/UI/UIAtlas.cpp b/UI/UIAtlas.cpp index ed1d02a2f4..e1b4358255 100644 --- a/UI/UIAtlas.cpp +++ b/UI/UIAtlas.cpp @@ -172,6 +172,10 @@ static const ImageMeta imageIDs[] = { {"I_MOVE", false}, {"I_RESIZE", false}, {"I_LINK_OUT_QUESTION", false}, + {"I_PSX_ISO", false}, + {"I_PS2_ISO", false}, + {"I_PS3_ISO", false}, + {"I_UNKNOWN_ISO", false}, }; static std::string PNGNameFromID(std::string_view id) { diff --git a/assets/ui_images/images.svg b/assets/ui_images/images.svg index 7237bc8168..8e2dab24fd 100644 --- a/assets/ui_images/images.svg +++ b/assets/ui_images/images.svg @@ -24,9 +24,9 @@ inkscape:pagecheckerboard="true" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" - inkscape:zoom="2.8284275" - inkscape:cx="267.81666" - inkscape:cy="394.74231" + inkscape:zoom="5.656855" + inkscape:cx="359.29859" + inkscape:cy="582.03719" inkscape:window-width="3840" inkscape:window-height="2071" inkscape:window-x="-9" @@ -2828,6 +2828,12 @@ + + + + + + PS3