Skip to content

Commit

Permalink
Merge pull request #17728 from hrydgard/collapsible-achievement-lists
Browse files Browse the repository at this point in the history
Make the achievement lists collapsible on the main achievements screen
  • Loading branch information
hrydgard committed Jul 16, 2023
2 parents eaa131d + 7eb1bfe commit 89250ba
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 8 deletions.
39 changes: 39 additions & 0 deletions Common/UI/View.cpp
Expand Up @@ -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)
Expand Down
11 changes: 10 additions & 1 deletion Common/UI/View.h
Expand Up @@ -857,7 +857,8 @@ class CheckBox : public ClickableItem {
//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_;
Expand All @@ -866,6 +867,14 @@ class CheckBox : public ClickableItem {
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)
Expand Down
15 changes: 15 additions & 0 deletions Common/UI/ViewGroup.cpp
Expand Up @@ -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
9 changes: 8 additions & 1 deletion Common/UI/ViewGroup.h
Expand Up @@ -290,7 +290,6 @@ class ChoiceStrip : public LinearLayout {
bool topTabs_ = false;
};


class TabHolder : public LinearLayout {
public:
TabHolder(Orientation orientation, float stripSize, LayoutParams *layoutParams = 0);
Expand Down Expand Up @@ -325,4 +324,12 @@ class TabHolder : public LinearLayout {
std::vector<AnchorTranslateTween *> tabTweens_;
};

class CollapsibleSection : public LinearLayout {
public:
CollapsibleSection(const std::string &title, LayoutParams *layoutParams = nullptr);

private:
bool open_ = true;
};

} // namespace UI
3 changes: 3 additions & 0 deletions Core/RetroAchievements.h
Expand Up @@ -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();

Expand Down
21 changes: 15 additions & 6 deletions UI/RetroAchievementScreens.cpp
Expand Up @@ -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 : "";
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 89250ba

Please sign in to comment.