diff --git a/Common/UI/TabHolder.cpp b/Common/UI/TabHolder.cpp index c9a41d4c69..2f1eafb1a7 100644 --- a/Common/UI/TabHolder.cpp +++ b/Common/UI/TabHolder.cpp @@ -9,7 +9,7 @@ namespace UI { TabHolder::TabHolder(Orientation orientation, float stripSize, TabHolderFlags flags, View *bannerView, LayoutParams *layoutParams) - : LinearLayout(Opposite(orientation), layoutParams) { + : LinearLayout(Opposite(orientation), layoutParams), orientation_(orientation), flags_(flags) { SetSpacing(0.0f); if (orientation == ORIENT_HORIZONTAL) { // This orientation supports adding a back button. @@ -34,6 +34,8 @@ TabHolder::TabHolder(Orientation orientation, float stripSize, TabHolderFlags fl } } else { tabContainer_ = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(stripSize, FILL_PARENT)); + tabContainer_->Add(new Spacer(8.0f)); + tabContainer_->SetSpacing(0.0f); tabStrip_ = new ChoiceStrip(orientation, new LayoutParams(FILL_PARENT, FILL_PARENT)); tabStrip_->SetTopTabs(true); tabScroll_ = new ScrollView(orientation, new LinearLayoutParams(1.0f)); @@ -62,9 +64,15 @@ void TabHolder::AddBack(UIScreen *parent) { } } -void TabHolder::AddTabContents(std::string_view title, ViewGroup *tabContents) { +void TabHolder::AddTabContents(std::string_view title, ImageID imageId, ViewGroup *tabContents) { tabs_.push_back(tabContents); - tabStrip_->AddChoice(title); + if (orientation_ == ORIENT_HORIZONTAL && (flags_ & TabHolderFlags::HorizontalOnlyIcons) && imageId.isValid()) { + tabStrip_->AddChoice(imageId); + } else if (orientation_ == ORIENT_VERTICAL && (flags_ & TabHolderFlags::VerticalShowIcons) && imageId.isValid()) { + tabStrip_->AddChoice(title, imageId); + } else { + tabStrip_->AddChoice(title); + } contents_->Add(tabContents); if (tabs_.size() > 1) tabContents->SetVisibility(V_GONE); @@ -76,9 +84,15 @@ void TabHolder::AddTabContents(std::string_view title, ViewGroup *tabContents) { createFuncs_.push_back(nullptr); } -void TabHolder::AddTabDeferred(std::string_view title, std::function createCb) { +void TabHolder::AddTabDeferred(std::string_view title, ImageID imageId, std::function createCb) { tabs_.push_back(nullptr); // marker - tabStrip_->AddChoice(title); + if (orientation_ == ORIENT_HORIZONTAL && (flags_ & TabHolderFlags::HorizontalOnlyIcons) && imageId.isValid()) { + tabStrip_->AddChoice(imageId); + } else if (orientation_ == ORIENT_VERTICAL && (flags_ & TabHolderFlags::VerticalShowIcons) && imageId.isValid()) { + tabStrip_->AddChoice(title, imageId); + } else { + tabStrip_->AddChoice(title); + } tabTweens_.push_back(nullptr); createFuncs_.push_back(createCb); @@ -223,8 +237,8 @@ ChoiceStrip::ChoiceStrip(Orientation orientation, LayoutParams *layoutParams) SetSpacing(0.0f); } -void ChoiceStrip::AddChoice(std::string_view title) { - StickyChoice *c = new StickyChoice(title, "", +void ChoiceStrip::AddChoice(std::string_view title, ImageID imageId) { + StickyChoice *c = new StickyChoice(title, imageId, orientation_ == ORIENT_HORIZONTAL ? nullptr : new LinearLayoutParams(FILL_PARENT, ITEM_HEIGHT)); diff --git a/Common/UI/TabHolder.h b/Common/UI/TabHolder.h index beb883d234..99bd84b32c 100644 --- a/Common/UI/TabHolder.h +++ b/Common/UI/TabHolder.h @@ -14,6 +14,8 @@ class ScrollView; enum class TabHolderFlags { Default = 0, BackButton = 1, + HorizontalOnlyIcons = 2, + VerticalShowIcons = 4, }; ENUM_CLASS_BITOPS(TabHolderFlags); @@ -22,11 +24,11 @@ public: TabHolder(Orientation orientation, float stripSize, TabHolderFlags flags, View *bannerView, LayoutParams *layoutParams); template - T *AddTab(std::string_view title, T *tabContents) { - AddTabContents(title, tabContents); + T *AddTab(std::string_view title, ImageID imageId, T *tabContents) { + AddTabContents(title, imageId, tabContents); return tabContents; } - void AddTabDeferred(std::string_view title, std::function createCb); + void AddTabDeferred(std::string_view title, ImageID imageId, std::function createCb); void EnableTab(int tab, bool enabled); void AddBack(UIScreen *parent); @@ -48,7 +50,7 @@ public: } private: - void AddTabContents(std::string_view title, ViewGroup *tabContents); + void AddTabContents(std::string_view title, ImageID imageId, ViewGroup *tabContents); void OnTabClick(EventParams &e); bool EnsureTab(int index); // return true if it actually created a tab. @@ -57,7 +59,9 @@ private: ChoiceStrip *tabStrip_ = nullptr; ScrollView *tabScroll_ = nullptr; ViewGroup *contents_ = nullptr; + Orientation orientation_ = ORIENT_HORIZONTAL; + TabHolderFlags flags_ = TabHolderFlags::Default; int currentTab_ = 0; std::vector tabs_; std::vector tabTweens_; @@ -68,7 +72,7 @@ class ChoiceStrip : public LinearLayout { public: ChoiceStrip(Orientation orientation, LayoutParams *layoutParams = 0); - void AddChoice(std::string_view title); + void AddChoice(std::string_view title, ImageID imageId = ImageID::invalid()); void AddChoice(ImageID buttonImage); int GetSelection() const { return selected_; } diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index 30ffc0da73..1c8c63c8bc 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -468,11 +468,6 @@ void Choice::ClickInternal() { void Choice::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const { float totalW = 0.0f; float totalH = 0.0f; - if (image_.isValid()) { - dc.Draw()->GetAtlas()->measureImage(image_, &w, &h); - totalW = w * imgScale_ + 6; - totalH = h * imgScale_; - } if (!text_.empty()) { const int paddingX = 12; float availWidth = horiz.size - paddingX * 2 - textPadding_.horiz() - totalW; @@ -488,6 +483,16 @@ void Choice::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, dc.MeasureTextRect(dc.GetTheme().uiFont, scale, scale, text_, availBounds, &textW, &textH, FLAG_WRAP_TEXT); totalH = std::max(totalH, textH); totalW += textW; + if (image_.isValid()) { + totalW += 12; + totalW += totalH; + } + } else { + if (image_.isValid()) { + dc.Draw()->GetAtlas()->measureImage(image_, &w, &h); + totalW = w * imgScale_ + 6; + totalH = h * imgScale_; + } } w = totalW + (text_.empty() ? 16 : 24); @@ -508,17 +513,20 @@ void Choice::Draw(UIContext &dc) { } else if (!text_.empty() && !hideTitle_) { dc.SetFontStyle(dc.GetTheme().uiFont); - int paddingX = 12; - float availWidth = bounds_.w - paddingX * 2 - textPadding_.horiz(); + int paddingLeft = 12; + int paddingRight = 12; + float availWidth = bounds_.w - (paddingLeft + paddingRight + textPadding_.horiz()); if (image_.isValid()) { + paddingLeft = 0; const AtlasImage *image = dc.Draw()->GetAtlas()->getImage(image_); if (image) { _dbg_assert_(image); - paddingX += image->w + 6; - availWidth -= image->w + 6; // TODO: Use scale rotation and flip here as well (DrawImageRotated is always ALIGN_CENTER for now) - dc.Draw()->DrawImage(image_, bounds_.x + 6, bounds_.centerY(), 1.0f, style.fgColor, ALIGN_LEFT | ALIGN_VCENTER); + dc.Draw()->DrawImage(image_, bounds_.x + bounds_.h * 0.5f + paddingLeft, bounds_.centerY(), 1.0f, style.fgColor, ALIGN_CENTER); + + paddingLeft += bounds_.h; + availWidth -= bounds_.h; } } @@ -528,12 +536,12 @@ void Choice::Draw(UIContext &dc) { if (rightIconImage_.isValid()) { uint32_t col = rightIconKeepColor_ ? 0xffffffff : style.fgColor; // Don't apply theme to gold icon if (shine_) { - Bounds b = Bounds::FromCenter(bounds_.x2() - 32 - paddingX, bounds_.centerY(), bounds_.h * 0.4f); + Bounds b = Bounds::FromCenter(bounds_.x2() - 32 - paddingRight, bounds_.centerY(), bounds_.h * 0.4f); DrawIconShine(dc, b.Inset(5.0f, 5.0f), 0.65f, false); } - dc.Draw()->DrawImageRotated(rightIconImage_, bounds_.x2() - 32 - paddingX, bounds_.centerY(), rightIconScale_, rightIconRot_, col, rightIconFlipH_); + dc.Draw()->DrawImageRotated(rightIconImage_, bounds_.x2() - 32 - paddingRight, bounds_.centerY(), rightIconScale_, rightIconRot_, col, rightIconFlipH_); } - Bounds textBounds(bounds_.x + paddingX + textPadding_.left, bounds_.y, availWidth, bounds_.h); + Bounds textBounds(bounds_.x + paddingLeft + textPadding_.left, bounds_.y, availWidth, bounds_.h); dc.DrawTextRectSqueeze(text_, textBounds, style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT | drawTextFlags_); } dc.SetFontScale(1.0f, 1.0f); @@ -629,7 +637,7 @@ void CollapsibleHeader::Draw(UIContext &dc) { float xoff = 37.0f; dc.SetFontStyle(dc.GetTheme().uiFontSmall); - dc.DrawText(text_, bounds_.x + 4 + xoff, bounds_.centerY(), style.fgColor, ALIGN_LEFT | ALIGN_VCENTER); + dc.DrawText(text_, bounds_.x + 6 + xoff, bounds_.centerY(), style.fgColor, ALIGN_LEFT | ALIGN_VCENTER); dc.Draw()->DrawImageCenterTexel(dc.GetTheme().whiteImage, bounds_.x, bounds_.y2() - 2, bounds_.x2(), bounds_.y2(), style.fgColor); if (hasSubItems_) { dc.Draw()->DrawImageRotated(ImageID("I_ARROW"), bounds_.x + 20.0f, bounds_.y + 20.0f, 1.0f, *toggle_ ? -M_PI / 2 : M_PI, style.fgColor); diff --git a/Common/UI/View.h b/Common/UI/View.h index db524d6421..5cc1b51ab1 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -30,8 +30,6 @@ struct KeyInput; struct TouchInput; struct AxisInput; -struct ImageID; - class DrawBuffer; class Texture; class UIContext; @@ -778,10 +776,12 @@ private: // Different key handling. class StickyChoice : public Choice { public: - StickyChoice(std::string_view text, std::string_view smallText = "", LayoutParams *layoutParams = 0) + StickyChoice(std::string_view text, std::string_view smallText = "", LayoutParams *layoutParams = nullptr) : Choice(text, smallText, false, layoutParams) {} - StickyChoice(ImageID buttonImage, LayoutParams *layoutParams = 0) + StickyChoice(ImageID buttonImage, LayoutParams *layoutParams = nullptr) : Choice(buttonImage, layoutParams) {} + StickyChoice(std::string_view text, ImageID image, LayoutParams *layoutParams = nullptr) + : Choice(text, image, layoutParams) {} bool Key(const KeyInput &key) override; bool Touch(const TouchInput &touch) override; @@ -1033,8 +1033,8 @@ public: Event OnClick; private: - bool down_; - bool dragging_; + bool down_ = false; + bool dragging_ = false; }; class TextEdit : public View { diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index f50c1d27d5..31aa24b4ac 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -752,6 +752,7 @@ void hleLagSync(u64 userdata, int cyclesLate) { double now = before; while (now < goal && goal < now + 0.01) { // Tight loop on win32 - intentionally, as timing is otherwise not precise enough. + // TODO: Use the precise waits if available #ifndef _WIN32 const double left = goal - now; if (left > 0.0f && left < 1.0f) { // Sanity check diff --git a/Core/System.cpp b/Core/System.cpp index b98ef349e8..749d6bd75a 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -934,6 +934,8 @@ void DumpFileIfEnabled(const u8 *dataPtr, const u32 length, std::string_view nam delete[] path; } }, path); + } else { + free(path); } return; } diff --git a/UI/CustomButtonMappingScreen.cpp b/UI/CustomButtonMappingScreen.cpp index 40e4e87e32..e80ffd1318 100644 --- a/UI/CustomButtonMappingScreen.cpp +++ b/UI/CustomButtonMappingScreen.cpp @@ -146,7 +146,7 @@ void CustomButtonMappingScreen::CreateViews() { root__->Add(leftColumn); ScrollView *rightScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT, 1.0f)); leftColumn->Add(new Spacer(new LinearLayoutParams(1.0f))); - leftColumn->Add(new Choice(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); + leftColumn->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK")))->OnClick.Handle(this, &UIScreen::OnBack); root__->Add(rightScroll); LinearLayout *vertLayout = new LinearLayout(ORIENT_VERTICAL); diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 5a47e977d5..b6644f7113 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -557,7 +557,7 @@ void FrameDumpTestScreen::CreateViews() { LinearLayout *dumps = new LinearLayoutList(ORIENT_VERTICAL); dumps->SetSpacing(0); dumpsScroll->Add(dumps); - tabHolder->AddTab("Dumps", dumpsScroll); + tabHolder->AddTab("Dumps", ImageID::invalid(), dumpsScroll); dumps->Add(new ItemHeader("GE Frame Dumps")); diff --git a/UI/GPUDriverTestScreen.cpp b/UI/GPUDriverTestScreen.cpp index b9993af4ea..cdc9cf5529 100644 --- a/UI/GPUDriverTestScreen.cpp +++ b/UI/GPUDriverTestScreen.cpp @@ -303,10 +303,10 @@ void GPUDriverTestScreen::CreateViews() { tabHolder_ = new TabHolder(ORIENT_HORIZONTAL, 30.0f, TabHolderFlags::Default, nullptr, new AnchorLayoutParams(FILL_PARENT, FILL_PARENT, false)); anchor->Add(tabHolder_); - tabHolder_->AddTab("Discard", new LinearLayout(ORIENT_VERTICAL)); - tabHolder_->AddTab("Shader", new LinearLayout(ORIENT_VERTICAL)); + tabHolder_->AddTab("Discard", ImageID::invalid(), new LinearLayout(ORIENT_VERTICAL)); + tabHolder_->AddTab("Shader", ImageID::invalid(), new LinearLayout(ORIENT_VERTICAL)); - Choice *back = new Choice(di->T("Back"), "", false, new AnchorLayoutParams(190, WRAP_CONTENT, 10, NONE, NONE, 10)); + Choice *back = new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new AnchorLayoutParams(190, WRAP_CONTENT, 10, NONE, NONE, 10)); back->OnClick.Handle(this, &UIScreen::OnBack); anchor->Add(back); } diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 49f66e84cc..4a476064af 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -117,7 +117,7 @@ void SetMemStickDirDarwin(int requesterToken) { #endif GameSettingsScreen::GameSettingsScreen(const Path &gamePath, std::string gameID, bool editThenRestore) - : UITabbedBaseDialogScreen(gamePath), gameID_(gameID), editThenRestore_(editThenRestore) { + : UITabbedBaseDialogScreen(gamePath, TabDialogFlags::HorizontalOnlyIcons | TabDialogFlags::VerticalShowIcons), gameID_(gameID), editThenRestore_(editThenRestore) { prevInflightFrames_ = g_Config.iInflightFrames; analogSpeedMapped_ = KeyMap::InputMappingsFromPspButton(VIRTKEY_SPEED_ANALOG, nullptr, true); } @@ -221,35 +221,34 @@ void GameSettingsScreen::CreateTabs() { using namespace UI; auto ms = GetI18NCategory(I18NCat::MAINSETTINGS); - AddTab("GameSettingsGraphics", ms->T("Graphics"), [this](UI::LinearLayout *parent) { + AddTab("GameSettingsGraphics", ms->T("Graphics"), ImageID("I_DISPLAY"), [this](UI::LinearLayout *parent) { CreateGraphicsSettings(parent); }); - AddTab("GameSettingsControls", ms->T("Controls"), [this](UI::LinearLayout *parent) { + AddTab("GameSettingsControls", ms->T("Controls"), ImageID("I_CONTROLLER"), [this](UI::LinearLayout *parent) { CreateControlsSettings(parent); }); - AddTab("GameSettingsAudio", ms->T("Audio"), [this](UI::LinearLayout *parent) { + AddTab("GameSettingsAudio", ms->T("Audio"), ImageID("I_SPEAKER_MAX"), [this](UI::LinearLayout *parent) { CreateAudioSettings(parent); }); - AddTab("GameSettingsNetworking", ms->T("Networking"), [this](UI::LinearLayout *parent) { + AddTab("GameSettingsNetworking", ms->T("Networking"), ImageID("I_WIFI"), [this](UI::LinearLayout *parent) { CreateNetworkingSettings(parent); }); - AddTab("GameSettingsTools", ms->T("Tools"), [this](UI::LinearLayout *parent) { + AddTab("GameSettingsTools", ms->T("Tools"), ImageID("I_DEVMENU"), [this](UI::LinearLayout *parent) { CreateToolsSettings(parent); }); - AddTab("GameSettingsSystem", ms->T("System"), [this](UI::LinearLayout *parent) { + AddTab("GameSettingsSystem", ms->T("System"), ImageID("I_GEAR"), [this](UI::LinearLayout *parent) { parent->SetSpacing(0); CreateSystemSettings(parent); }); - int deviceType = System_GetPropertyInt(SYSPROP_DEVICE_TYPE); if ((deviceType == DEVICE_TYPE_VR) || g_Config.bForceVR) { - AddTab("GameSettingsVR", ms->T("VR"), [this](UI::LinearLayout *parent) { + AddTab("GameSettingsVR", ms->T("VR"), ImageID::invalid(), [this](UI::LinearLayout *parent) { CreateVRSettings(parent); }); } diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 52d7c7e616..5a9c19d092 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -1099,7 +1099,7 @@ void MainScreen::CreateRecentTab() { scrollRecentGames->Add(tabRecentGames); gameBrowsers_.push_back(tabRecentGames); - tabHolder_->AddTab(mm->T("Recent"), scrollRecentGames); + tabHolder_->AddTab(mm->T("Recent"), ImageID::invalid(), scrollRecentGames); tabRecentGames->OnChoice.Handle(this, &MainScreen::OnGameSelectedInstant); tabRecentGames->OnHoldChoice.Handle(this, &MainScreen::OnGameSelected); tabRecentGames->OnHighlight.Handle(this, &MainScreen::OnGameHighlight); @@ -1119,7 +1119,7 @@ GameBrowser *MainScreen::CreateBrowserTab(const Path &path, std::string_view tit scrollView->Add(gameBrowser); gameBrowsers_.push_back(gameBrowser); - tabHolder_->AddTab(mm->T(title), scrollView); + tabHolder_->AddTab(mm->T(title), ImageID::invalid(), scrollView); if (scrollPos) { scrollView->RememberPosition(scrollPos); } @@ -1617,7 +1617,7 @@ void UmdReplaceScreen::CreateViews() { Path("!RECENT"), BrowseFlags::NONE, &g_Config.bGridView1, screenManager(), "", "", new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); scrollRecentGames->Add(tabRecentGames); - leftColumn->AddTab(mm->T("Recent"), scrollRecentGames); + leftColumn->AddTab(mm->T("Recent"), ImageID::invalid(), scrollRecentGames); tabRecentGames->OnChoice.Handle(this, &UmdReplaceScreen::OnGameSelected); tabRecentGames->OnHoldChoice.Handle(this, &UmdReplaceScreen::OnGameSelected); } @@ -1630,7 +1630,7 @@ void UmdReplaceScreen::CreateViews() { scrollAllGames->Add(tabAllGames); - leftColumn->AddTab(mm->T("Games"), scrollAllGames); + leftColumn->AddTab(mm->T("Games"), ImageID::invalid(), scrollAllGames); tabAllGames->OnChoice.Handle(this, &UmdReplaceScreen::OnGameSelected); diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index c74db93103..d910929fcb 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -154,7 +154,7 @@ void UIBaseScreen::sendMessage(UIMessage message, const char *value) { void UIBaseDialogScreen::AddStandardBack(UI::ViewGroup *parent) { using namespace UI; auto di = GetI18NCategory(I18NCat::DIALOG); - parent->Add(new Choice(di->T("Back"), "", false, new AnchorLayoutParams(190, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &UIScreen::OnBack); + parent->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new AnchorLayoutParams(190, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &UIScreen::OnBack); } PromptScreen::PromptScreen(const Path &gamePath, std::string_view message, std::string_view yesButtonText, std::string_view noButtonText, std::function callback) diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index 654fe6b24d..45590a96ca 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -613,7 +613,7 @@ void RemoteISOBrowseScreen::CreateViews() { scrollRecentGames->Add(tabRemoteGames); gameBrowsers_.push_back(tabRemoteGames); - leftColumn->AddTab(ri->T("Remote Server"), scrollRecentGames); + leftColumn->AddTab(ri->T("Remote Server"), ImageID::invalid(), scrollRecentGames); tabRemoteGames->OnChoice.Handle(this, &MainScreen::OnGameSelectedInstant); tabRemoteGames->OnHoldChoice.Handle(this, &MainScreen::OnGameSelected); tabRemoteGames->OnHighlight.Handle(this, &MainScreen::OnGameHighlight); @@ -623,7 +623,7 @@ void RemoteISOBrowseScreen::CreateViews() { rightColumnItems->SetSpacing(0.0f); rightColumn->Add(rightColumnItems); - rightColumnItems->Add(new Choice(di->T("Back"), "", false, new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &UIScreen::OnBack); + rightColumnItems->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &UIScreen::OnBack); if (portrait) { root_ = new LinearLayout(ORIENT_VERTICAL); diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index 13039a0663..8a3ff439fd 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -325,7 +325,7 @@ void ReportScreen::CreateViews() { UpdateOverallDescription(); rightColumnItems->Add(new Spacer(25.0)); - rightColumnItems->Add(new Choice(di->T("Back"), "", false, new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &UIScreen::OnBack); + rightColumnItems->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &UIScreen::OnBack); root_ = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0f)); root_->Add(leftColumn); @@ -432,7 +432,7 @@ void ReportFinishScreen::CreateViews() { rightColumnItems->Add(new Choice(rp->T("View Feedback")))->OnClick.Handle(this, &ReportFinishScreen::HandleViewFeedback); rightColumnItems->Add(new Spacer(25.0)); - rightColumnItems->Add(new Choice(di->T("Back"), "", false, new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &UIScreen::OnBack); + rightColumnItems->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &UIScreen::OnBack); root_ = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0f)); root_->Add(leftColumn); diff --git a/UI/RetroAchievementScreens.cpp b/UI/RetroAchievementScreens.cpp index 154b43a580..a579c85273 100644 --- a/UI/RetroAchievementScreens.cpp +++ b/UI/RetroAchievementScreens.cpp @@ -64,18 +64,18 @@ AudioFileChooser::AudioFileChooser(RequesterToken token, std::string *value, std void RetroAchievementsListScreen::CreateTabs() { auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS); - AddTab("Achievements", ac->T("Achievements"), [this](UI::LinearLayout *parent) { + AddTab("Achievements", ac->T("Achievements"), ImageID::invalid(), [this](UI::LinearLayout *parent) { parent->SetSpacing(5.0f); CreateAchievementsTab(parent); }); - AddTab("Leaderboards", ac->T("Leaderboards"), [this](UI::LinearLayout *parent) { + AddTab("Leaderboards", ac->T("Leaderboards"), ImageID::invalid(), [this](UI::LinearLayout *parent) { parent->SetSpacing(5.0f); CreateLeaderboardsTab(parent); }); #ifdef _DEBUG - AddTab("AchievementsStatistics", ac->T("Statistics"), [this](UI::LinearLayout *parent) { + AddTab("AchievementsStatistics", ac->T("Statistics"), ImageID::invalid(), [this](UI::LinearLayout *parent) { parent->SetSpacing(5.0f); CreateStatisticsTab(parent); }); diff --git a/UI/TabbedDialogScreen.cpp b/UI/TabbedDialogScreen.cpp index 5a30dee559..6b35730003 100644 --- a/UI/TabbedDialogScreen.cpp +++ b/UI/TabbedDialogScreen.cpp @@ -12,10 +12,10 @@ #include "UI/MiscViews.h" #include "UI/TabbedDialogScreen.h" -void UITabbedBaseDialogScreen::AddTab(const char *tag, std::string_view title, std::function createCallback, TabFlags flags) { +void UITabbedBaseDialogScreen::AddTab(const char *tag, std::string_view title, ImageID imageId, std::function createCallback, TabFlags flags) { using namespace UI; - tabHolder_->AddTabDeferred(title, [createCallback = std::move(createCallback), tag, flags]() -> UI::ViewGroup * { + tabHolder_->AddTabDeferred(title, imageId, [createCallback = std::move(createCallback), tag, flags]() -> UI::ViewGroup * { using namespace UI; ViewGroup *scroll = nullptr; if (!(flags & TabFlags::NonScrollable)) { @@ -53,12 +53,21 @@ void UITabbedBaseDialogScreen::CreateViews() { if (portrait) { auto di = GetI18NCategory(I18NCat::DIALOG); LinearLayout *verticalLayout = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT)); - tabHolder_ = new TabHolder(ORIENT_HORIZONTAL, 200, TabHolderFlags::BackButton, filterNotice_, new LinearLayoutParams(1.0f)); + + TabHolderFlags tabHolderFlags = TabHolderFlags::BackButton; + if (flags_ & TabDialogFlags::HorizontalOnlyIcons) { + tabHolderFlags |= TabHolderFlags::HorizontalOnlyIcons; + } + tabHolder_ = new TabHolder(ORIENT_HORIZONTAL, 200, tabHolderFlags, filterNotice_, new LinearLayoutParams(1.0f)); verticalLayout->Add(tabHolder_); CreateExtraButtons(verticalLayout, 0); root_->Add(verticalLayout); } else { - tabHolder_ = new TabHolder(ORIENT_VERTICAL, 200, TabHolderFlags::Default, filterNotice_, new AnchorLayoutParams(10, 0, 10, 0, false)); + TabHolderFlags tabHolderFlags = TabHolderFlags::Default; + if (flags_ & TabDialogFlags::VerticalShowIcons) { + tabHolderFlags |= TabHolderFlags::VerticalShowIcons; + } + tabHolder_ = new TabHolder(ORIENT_VERTICAL, 300, tabHolderFlags, filterNotice_, new AnchorLayoutParams(10, 0, 10, 0, false)); CreateExtraButtons(tabHolder_->Container(), 10); tabHolder_->AddBack(this); root_->Add(tabHolder_); @@ -90,7 +99,7 @@ void UITabbedBaseDialogScreen::CreateViews() { if ((g_display.dp_xres < g_display.dp_yres || g_display.dp_yres >= 500) && (deviceType != DEVICE_TYPE_VR) && ShowSearchControls()) { // Search auto ms = GetI18NCategory(I18NCat::MAINSETTINGS); - AddTab("GameSettingsSearch", ms->T("Search"), [this](UI::LinearLayout *searchSettings) { + AddTab("GameSettingsSearch", ms->T("Search"), ImageID("I_SEARCH"), [this](UI::LinearLayout *searchSettings) { auto se = GetI18NCategory(I18NCat::SEARCH); searchSettings->Add(new ItemHeader(se->T("Find settings"))); diff --git a/UI/TabbedDialogScreen.h b/UI/TabbedDialogScreen.h index 1193354c13..42e53921c0 100644 --- a/UI/TabbedDialogScreen.h +++ b/UI/TabbedDialogScreen.h @@ -4,6 +4,7 @@ #include #include "Common/UI/UIScreen.h" +#include "Common/Render/TextureAtlas.h" #include "Common/System/System.h" #include "Core/ConfigValues.h" #include "UI/BaseScreens.h" @@ -14,6 +15,13 @@ namespace UI { class TabHolder; } +enum class TabDialogFlags { + Default = 0, + HorizontalOnlyIcons = 1, + VerticalShowIcons = 2, +}; +ENUM_CLASS_BITOPS(TabDialogFlags); + enum class TabFlags { Default = 0, NonScrollable = 1, @@ -22,11 +30,14 @@ ENUM_CLASS_BITOPS(TabFlags); class UITabbedBaseDialogScreen : public UIBaseDialogScreen { public: - UITabbedBaseDialogScreen(const Path &gamePath) : UIBaseDialogScreen(gamePath) { + UITabbedBaseDialogScreen(const Path &gamePath, TabDialogFlags flags = TabDialogFlags::Default) : UIBaseDialogScreen(gamePath), flags_(flags) { ignoreBottomInset_ = true; } - void AddTab(const char *tag, std::string_view title, std::function createCallback, TabFlags flags = TabFlags::Default); + void AddTab(const char *tag, std::string_view title, ImageID imageId, std::function createCallback, TabFlags flags = TabFlags::Default); + void AddTab(const char *tag, std::string_view title, std::function createCallback, TabFlags flags = TabFlags::Default) { + AddTab(tag, title, ImageID::invalid(), createCallback, flags); + } void CreateViews() override; protected: @@ -57,4 +68,6 @@ private: // If we recreate the views while this is active we show it again std::string oldSettingInfo_; std::string searchFilter_; + + TabDialogFlags flags_ = TabDialogFlags::Default; }; diff --git a/UI/TouchControlVisibilityScreen.cpp b/UI/TouchControlVisibilityScreen.cpp index f9c7355364..95aa90895d 100644 --- a/UI/TouchControlVisibilityScreen.cpp +++ b/UI/TouchControlVisibilityScreen.cpp @@ -149,12 +149,12 @@ void RightAnalogMappingScreen::CreateViews() { auto mc = GetI18NCategory(I18NCat::MAPPABLECONTROLS); root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT)); - Choice *back = new Choice(di->T("Back"), "", false, new AnchorLayoutParams(leftColumnWidth - 10, WRAP_CONTENT, 10, NONE, NONE, 10)); + Choice *back = new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new AnchorLayoutParams(leftColumnWidth - 10, WRAP_CONTENT, 10, NONE, NONE, 10)); root_->Add(back)->OnClick.Handle(this, &UIScreen::OnBack); TabHolder *tabHolder = new TabHolder(ORIENT_VERTICAL, leftColumnWidth, TabHolderFlags::Default, nullptr, new AnchorLayoutParams(10, 0, 10, 0, false)); root_->Add(tabHolder); ScrollView *rightPanel = new ScrollView(ORIENT_VERTICAL); - tabHolder->AddTab(co->T("Binds"), rightPanel); + tabHolder->AddTab(co->T("Binds"), ImageID::invalid(), rightPanel); LinearLayout *vert = rightPanel->Add(new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT))); vert->SetSpacing(0); diff --git a/UI/UIAtlas.cpp b/UI/UIAtlas.cpp index 1d53c8b9fa..394fed4e8c 100644 --- a/UI/UIAtlas.cpp +++ b/UI/UIAtlas.cpp @@ -135,7 +135,7 @@ static const ImageMeta imageIDs[] = { {"I_FILLED_CIRCLE_3", false}, {"I_FILLED_CIRCLE_4", false}, {"I_FILLED_CIRCLE_5", false}, - {"I_SETTINGS_DISPLAY", false}, + {"I_DISPLAY", false}, {"I_NAVIGATE_BACK", false}, {"I_NAVIGATE_FORWARD", false}, {"I_FOLDER_UPLOAD", false}, @@ -150,6 +150,9 @@ static const ImageMeta imageIDs[] = { {"I_LOGO_PLAY_STORE", false}, {"I_LOGO_APP_STORE", false}, {"I_SEARCH", false}, + {"I_DEVMENU", false}, + {"I_CONTROLLER", false}, + {"I_DEBUGGER", false}, }; static std::string PNGNameFromID(std::string_view id) { diff --git a/assets/ui_images/images.svg b/assets/ui_images/images.svg index a5dddc85b1..f778fc3f75 100644 --- a/assets/ui_images/images.svg +++ b/assets/ui_images/images.svg @@ -24,15 +24,15 @@ inkscape:pagecheckerboard="true" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" - inkscape:zoom="2.0000001" - inkscape:cx="520.74999" - inkscape:cy="253.74999" + inkscape:zoom="4.0000002" + inkscape:cx="95.374995" + inkscape:cy="277.37499" inkscape:window-width="3379" inkscape:window-height="1941" inkscape:window-x="-9" inkscape:window-y="0" inkscape:window-maximized="0" - inkscape:current-layer="layer1" + inkscape:current-layer="I_FOLDER_PINNED" showgrid="false" /> + + + + + + .st0{stroke:#FFFFFF;stroke-miterlimit:10;} .st1{fill:#FFFFFF;} +