Merge pull request #17728 from hrydgard/collapsible-achievement-lists

Make the achievement lists collapsible on the main achievements screen
This commit is contained in:
Henrik Rydgård 2023-07-16 18:41:51 +02:00 committed by GitHub
commit 89250bae5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 90 additions and 8 deletions

View File

@ -612,6 +612,45 @@ std::string ItemHeader::DescribeText() const {
return ApplySafeSubstitutions(u->T("%1 heading"), text_);
}
CollapsibleHeader::CollapsibleHeader(bool *toggle, const std::string &text, LayoutParams *layoutParams)
: CheckBox(toggle, text, "", layoutParams) {
layoutParams_->width = FILL_PARENT;
layoutParams_->height = 40;
}
void CollapsibleHeader::Draw(UIContext &dc) {
Style style = dc.theme->itemStyle;
if (HasFocus()) style = dc.theme->itemFocusedStyle;
if (down_) style = dc.theme->itemDownStyle;
if (!IsEnabled()) style = dc.theme->itemDisabledStyle;
DrawBG(dc, style);
float xoff = 37.0f;
dc.SetFontStyle(dc.theme->uiFontSmall);
dc.DrawText(text_.c_str(), bounds_.x + 4 + xoff, bounds_.centerY(), dc.theme->headerStyle.fgColor, ALIGN_LEFT | ALIGN_VCENTER);
dc.Draw()->DrawImageCenterTexel(dc.theme->whiteImage, bounds_.x, bounds_.y2() - 2, bounds_.x2(), bounds_.y2(), dc.theme->headerStyle.fgColor);
dc.Draw()->DrawImageRotated(ImageID("I_ARROW"), bounds_.x + 20.0f, bounds_.y + 20.0f, 1.0f, *toggle_ ? -M_PI / 2 : M_PI);
}
void CollapsibleHeader::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const {
Bounds bounds(0, 0, layoutParams_->width, layoutParams_->height);
if (bounds.w < 0) {
// If there's no size, let's grow as big as we want.
bounds.w = horiz.size == 0 ? MAX_ITEM_SIZE : horiz.size;
}
if (bounds.h < 0) {
bounds.h = vert.size == 0 ? MAX_ITEM_SIZE : vert.size;
}
ApplyBoundsBySpec(bounds, horiz, vert);
dc.MeasureTextRect(dc.theme->uiFontSmall, 1.0f, 1.0f, text_.c_str(), (int)text_.length(), bounds, &w, &h, ALIGN_LEFT | ALIGN_VCENTER);
}
void CollapsibleHeader::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
View::GetContentDimensions(dc, w, h);
}
void BorderView::Draw(UIContext &dc) {
Color color = 0xFFFFFFFF;
if (style_ == BorderStyle::HEADER_FG)

View File

@ -857,7 +857,8 @@ public:
//allow external agents to toggle the checkbox
virtual void Toggle();
virtual bool Toggled() const;
private:
protected:
float CalculateTextScale(const UIContext &dc, float availWidth) const;
bool *toggle_;
@ -866,6 +867,14 @@ private:
ImageID imageID_;
};
class CollapsibleHeader : public CheckBox {
public:
CollapsibleHeader(bool *toggle, const std::string &text, LayoutParams *layoutParams = nullptr);
void Draw(UIContext &dc) override;
void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override;
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
};
class BitCheckBox : public CheckBox {
public:
BitCheckBox(uint32_t *bitfield, uint32_t bit, const std::string &text, const std::string &smallText = "", LayoutParams *layoutParams = nullptr)

View File

@ -1180,4 +1180,19 @@ StickyChoice *ChoiceStrip::Choice(int index) {
return nullptr;
}
CollapsibleSection::CollapsibleSection(const std::string &title, LayoutParams *layoutParams) : LinearLayout(ORIENT_VERTICAL, layoutParams) {
SetSpacing(0.0f);
CollapsibleHeader *heading = new CollapsibleHeader(&open_, title);
views_.push_back(heading);
heading->OnClick.Add([=](UI::EventParams &) {
// Change the visibility of all children except the first one.
// Later maybe try something more ambitious.
for (size_t i = 1; i < views_.size(); i++) {
views_[i]->SetVisibility(open_ ? V_VISIBLE : V_GONE);
}
return UI::EVENT_DONE;
});
}
} // namespace UI

View File

@ -290,7 +290,6 @@ private:
bool topTabs_ = false;
};
class TabHolder : public LinearLayout {
public:
TabHolder(Orientation orientation, float stripSize, LayoutParams *layoutParams = 0);
@ -325,4 +324,12 @@ private:
std::vector<AnchorTranslateTween *> tabTweens_;
};
class CollapsibleSection : public LinearLayout {
public:
CollapsibleSection(const std::string &title, LayoutParams *layoutParams = nullptr);
private:
bool open_ = true;
};
} // namespace UI

View File

@ -56,6 +56,9 @@ bool IsActive();
// Returns true if unofficial achievements are enabled.
bool UnofficialEnabled();
// Returns true if encore-mode is active.
bool EncoreModeActive();
// Returns true if the emulator should hold off on executing game code, such as during game identification.
bool IsBlockingExecution();

View File

@ -11,6 +11,7 @@
#include "UI/RetroAchievementScreens.h"
#include "UI/BackgroundAudio.h"
#include "UI/OnScreenDisplay.h"
static inline const char *DeNull(const char *ptr) {
return ptr ? ptr : "";
@ -115,18 +116,26 @@ void RetroAchievementsListScreen::CreateAchievementsTab(UI::ViewGroup *achieveme
achievements->Add(new GameAchievementSummaryView());
achievements->Add(new ItemHeader(ac->T("Unlocked achievements")));
CollapsibleSection *unlocked = new CollapsibleSection(StringFromFormat("%s (%d)", ac->T("Unlocked achievements"), (int)unlockedAchievements.size()));
unlocked->SetSpacing(2.0f);
for (auto &achievement : unlockedAchievements) {
achievements->Add(new AchievementView(achievement));
unlocked->Add(new AchievementView(achievement));
}
achievements->Add(new ItemHeader(ac->T("Locked achievements")));
achievements->Add(unlocked);
CollapsibleSection *locked = new CollapsibleSection(StringFromFormat("%s (%d)", ac->T("Locked achievements"), (int)lockedAchievements.size()));
unlocked->SetSpacing(2.0f);
for (auto &achievement : lockedAchievements) {
achievements->Add(new AchievementView(achievement));
locked->Add(new AchievementView(achievement));
}
achievements->Add(new ItemHeader(ac->T("Other achievements")));
achievements->Add(locked);
CollapsibleSection *other = new CollapsibleSection(StringFromFormat("%s (%d)", ac->T("Other achievements"), (int)otherAchievements.size()));
unlocked->SetSpacing(2.0f);
for (auto &achievement : otherAchievements) {
achievements->Add(new AchievementView(achievement));
other->Add(new AchievementView(achievement));
}
achievements->Add(other);
}
void RetroAchievementsListScreen::CreateLeaderboardsTab(UI::ViewGroup *viewGroup) {