From a7eb6bcffaaebec94b16c9fe0bdf74e6a83b1c59 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 10 Dec 2017 00:44:44 -0800 Subject: [PATCH] Store: Highlight active item, reselect on resize. --- UI/Store.cpp | 52 +++++++++++++++++++++++++++++++++++----------------- UI/Store.h | 8 ++++++-- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/UI/Store.cpp b/UI/Store.cpp index 9aefc1f6d7..201db63276 100644 --- a/UI/Store.cpp +++ b/UI/Store.cpp @@ -166,17 +166,15 @@ void HttpImageFileView::Draw(UIContext &dc) { // This is the entry in a list. Does not have install buttons and so on. -class ProductItemView : public UI::Choice { +class ProductItemView : public UI::StickyChoice { public: ProductItemView(const StoreEntry &entry, UI::LayoutParams *layoutParams = 0) - : UI::Choice(entry.name, layoutParams), entry_(entry) {} + : UI::StickyChoice(entry.name, "", layoutParams), entry_(entry) {} void GetContentDimensions(const UIContext &dc, float &w, float &h) const override { w = 300; h = 164; } - void Update() override; - void Draw(UIContext &dc) override; StoreEntry GetEntry() const { return entry_; } @@ -184,15 +182,6 @@ private: const StoreEntry &entry_; }; -void ProductItemView::Draw(UIContext &dc) { - UI::Choice::Draw(dc); - // dc.DrawText(entry_.name.c_str(), bounds_.centerX(), bounds_.centerY(), 0xFFFFFFFF, ALIGN_CENTER); -} - -void ProductItemView::Update() { - View::Update(); -} - // This is a "details" view of a game. Lets you install it. class ProductView : public UI::LinearLayout { public: @@ -326,7 +315,7 @@ UI::EventReturn ProductView::OnLaunchClick(UI::EventParams &e) { return UI::EVENT_DONE; } -StoreScreen::StoreScreen() : loading_(true), connectionError_(false) { +StoreScreen::StoreScreen() { StoreFilter noFilter; SetFilter(noFilter); lang_ = g_Config.sLanguageIni; @@ -438,23 +427,37 @@ void StoreScreen::CreateViews() { content->Add(new TextView(loading_ ? st->T("Loading...") : st->T("Connection Error"))); content->Add(new Button(di->T("Retry")))->OnClick.Handle(this, &StoreScreen::OnRetry); content->Add(new Button(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); + + scrollItemView_ = nullptr; + productPanel_ = nullptr; } else { content = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0f)); ScrollView *leftScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(WRAP_CONTENT, FILL_PARENT, 0.4f)); leftScroll->SetTag("StoreMainList"); content->Add(leftScroll); - LinearLayout *scrollItemView = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)); - leftScroll->Add(scrollItemView); + scrollItemView_ = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)); + leftScroll->Add(scrollItemView_); std::vector entries = FilterEntries(); for (size_t i = 0; i < entries.size(); i++) { - scrollItemView->Add(new ProductItemView(entries_[i]))->OnClick.Handle(this, &StoreScreen::OnGameSelected); + scrollItemView_->Add(new ProductItemView(entries_[i]))->OnClick.Handle(this, &StoreScreen::OnGameSelected); } // TODO: Similar apps, etc etc productPanel_ = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(0.5f)); leftScroll->SetTag("StoreMainProduct"); content->Add(productPanel_); + + ProductItemView *selectedItem = GetSelectedItem(); + if (selectedItem) { + ProductView *productView = new ProductView(selectedItem->GetEntry()); + productView->OnClickLaunch.Handle(this, &StoreScreen::OnGameLaunch); + productPanel_->Add(productView); + + selectedItem->Press(); + } else { + lastSelectedName_ = ""; + } } root_->Add(content); } @@ -469,6 +472,16 @@ std::vector StoreScreen::FilterEntries() { return filtered; } +ProductItemView *StoreScreen::GetSelectedItem() { + for (int i = 0; i < scrollItemView_->GetNumSubviews(); ++i) { + ProductItemView *item = static_cast(scrollItemView_->GetViewByIndex(i)); + if (item->GetEntry().name == lastSelectedName_) + return item; + } + + return nullptr; +} + UI::EventReturn StoreScreen::OnGameSelected(UI::EventParams &e) { ProductItemView *item = static_cast(e.v); if (!item) @@ -478,6 +491,11 @@ UI::EventReturn StoreScreen::OnGameSelected(UI::EventParams &e) { ProductView *productView = new ProductView(item->GetEntry()); productView->OnClickLaunch.Handle(this, &StoreScreen::OnGameLaunch); productPanel_->Add(productView); + + ProductItemView *previousItem = GetSelectedItem(); + if (previousItem && previousItem != item) + previousItem->Release(); + lastSelectedName_ = item->GetEntry().name; return UI::EVENT_DONE; } diff --git a/UI/Store.h b/UI/Store.h index a7eae478b6..1fff85a4c9 100644 --- a/UI/Store.h +++ b/UI/Store.h @@ -30,6 +30,7 @@ // Uses GameInfoCache heavily to implement the functionality. struct json_value; +class ProductItemView; enum EntryType { ENTRY_PBPZIP, @@ -74,6 +75,7 @@ protected: private: void SetFilter(const StoreFilter &filter); void ParseListing(std::string json); + ProductItemView *GetSelectedItem(); std::vector FilterEntries(); std::string GetStoreJsonURL(std::string storePath) const; @@ -86,8 +88,8 @@ private: // local filesystems at the moment. std::string storePath_; - bool loading_; - bool connectionError_; + bool loading_ = true; + bool connectionError_ = false; std::map categories_; @@ -97,7 +99,9 @@ private: StoreFilter filter_; std::string lang_; + std::string lastSelectedName_; + UI::ViewGroup *scrollItemView_; UI::ViewGroup *productPanel_; UI::TextView *titleText_; };