mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-15 03:25:01 -05:00
show updates button state is now properly updated :3
This commit is contained in:
parent
17f6aa09bb
commit
6d3f72209f
7 changed files with 101 additions and 35 deletions
|
@ -205,7 +205,7 @@ void ModsLayer::gotoTab(ModListSource* src) {
|
|||
// Update the state of the current list
|
||||
m_lists.at(m_currentSource)->updateSize(m_bigView);
|
||||
m_lists.at(m_currentSource)->activateSearch(m_showSearch);
|
||||
m_lists.at(m_currentSource)->updatePageNumber();
|
||||
m_lists.at(m_currentSource)->updateState();
|
||||
}
|
||||
|
||||
void ModsLayer::keyBackClicked() {
|
||||
|
|
|
@ -47,7 +47,6 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
|
|||
// search query
|
||||
if (m_source->isInstalledMods()) {
|
||||
m_source->search(m_searchInput->getString());
|
||||
this->gotoPage(0);
|
||||
return;
|
||||
}
|
||||
// Otherwise buffer inputs by a bit
|
||||
|
@ -60,7 +59,6 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
|
|||
if (m_searchInputThreads == 0) {
|
||||
Loader::get()->queueInMainThread([this] {
|
||||
m_source->search(m_searchInput->getString());
|
||||
this->gotoPage(0);
|
||||
});
|
||||
}
|
||||
}).detach();
|
||||
|
@ -124,17 +122,18 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
|
|||
CCSprite::createWithSpriteFrameName("GJ_filterIcon_001.png"),
|
||||
"Hide Updates", "GE_button_05.png"_spr
|
||||
);
|
||||
auto viewUpdatesBtn = CCMenuItemToggler::create(
|
||||
showUpdatesSpr, hideUpdatesSpr, this, nullptr
|
||||
m_toggleUpdatesOnlyBtn = CCMenuItemToggler::create(
|
||||
showUpdatesSpr, hideUpdatesSpr, this, menu_selector(ModList::onToggleUpdates)
|
||||
);
|
||||
updateAllMenu->addChild(viewUpdatesBtn);
|
||||
m_toggleUpdatesOnlyBtn->m_notClickable = true;
|
||||
updateAllMenu->addChild(m_toggleUpdatesOnlyBtn);
|
||||
|
||||
auto updateAllSpr = createGeodeButton(
|
||||
CCSprite::createWithSpriteFrameName("update.png"_spr),
|
||||
"Update All", "GE_button_01.png"_spr
|
||||
);
|
||||
auto updateAllBtn = CCMenuItemSpriteExtra::create(
|
||||
updateAllSpr, this, nullptr
|
||||
updateAllSpr, this, menu_selector(ModList::onUpdateAll)
|
||||
);
|
||||
updateAllMenu->addChild(updateAllBtn);
|
||||
|
||||
|
@ -240,6 +239,9 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
|
|||
|
||||
m_listener.bind(this, &ModList::onPromise);
|
||||
|
||||
m_invalidateCacheListener.bind(this, &ModList::onInvalidateCache);
|
||||
m_invalidateCacheListener.setFilter(InvalidateCacheFilter(m_source));
|
||||
|
||||
this->gotoPage(0);
|
||||
this->updateTopContainer();
|
||||
|
||||
|
@ -272,7 +274,7 @@ void ModList::onPromise(typename ModListSource::PageLoadEvent* event) {
|
|||
m_list->m_contentLayer->setPositionY(listTopScrollPos);
|
||||
|
||||
// Update page UI
|
||||
this->updatePageNumber();
|
||||
this->updateState();
|
||||
}
|
||||
else if (auto progress = event->getProgress()) {
|
||||
// todo: percentage in a loading bar
|
||||
|
@ -287,7 +289,7 @@ void ModList::onPromise(typename ModListSource::PageLoadEvent* event) {
|
|||
}
|
||||
else if (auto rejected = event->getReject()) {
|
||||
this->showStatus(ModListErrorStatus(), rejected->message, rejected->details);
|
||||
this->updatePageNumber();
|
||||
this->updateState();
|
||||
}
|
||||
|
||||
if (event->isFinally()) {
|
||||
|
@ -335,6 +337,10 @@ void ModList::onCheckUpdates(PromiseEvent<std::vector<std::string>, server::Serv
|
|||
}
|
||||
}
|
||||
|
||||
void ModList::onInvalidateCache(InvalidateCacheEvent* event) {
|
||||
this->gotoPage(0);
|
||||
}
|
||||
|
||||
void ModList::activateSearch(bool activate) {
|
||||
m_searchMenu->setVisible(activate);
|
||||
this->updateTopContainer();
|
||||
|
@ -393,7 +399,15 @@ void ModList::updateSize(bool big) {
|
|||
) * oldPosition);
|
||||
}
|
||||
|
||||
void ModList::updatePageNumber() {
|
||||
void ModList::updateState() {
|
||||
// Update the "Show Updates" button on the updates available banner
|
||||
if (m_toggleUpdatesOnlyBtn) {
|
||||
auto src = typeinfo_cast<InstalledModListSource*>(m_source);
|
||||
if (src) {
|
||||
m_toggleUpdatesOnlyBtn->toggle(src->getQuery().onlyUpdates);
|
||||
}
|
||||
}
|
||||
|
||||
auto pageCount = m_source->getPageCount();
|
||||
|
||||
// Hide if page count hasn't been loaded
|
||||
|
@ -420,7 +434,7 @@ void ModList::gotoPage(size_t page, bool update) {
|
|||
|
||||
// Do initial eager update on page UI (to prevent user spamming arrows
|
||||
// to access invalid pages)
|
||||
this->updatePageNumber();
|
||||
this->updateState();
|
||||
}
|
||||
|
||||
void ModList::showStatus(ModListStatus status, std::string const& message, std::optional<std::string> const& details) {
|
||||
|
@ -453,15 +467,21 @@ void ModList::showStatus(ModListStatus status, std::string const& message, std::
|
|||
}
|
||||
|
||||
void ModList::onFilters(CCObject*) {
|
||||
TagsPopup::create(m_source, [this]() {
|
||||
this->gotoPage(0);
|
||||
})->show();
|
||||
TagsPopup::create(m_source)->show();
|
||||
}
|
||||
|
||||
void ModList::onClearFilters(CCObject*) {
|
||||
m_searchInput->setString("", true);
|
||||
}
|
||||
|
||||
void ModList::onToggleUpdates(CCObject*) {
|
||||
if (auto src = typeinfo_cast<InstalledModListSource*>(m_source)) {
|
||||
src->getQueryMut()->onlyUpdates = !src->getQuery().onlyUpdates;
|
||||
}
|
||||
}
|
||||
|
||||
void ModList::onUpdateAll(CCObject*) {}
|
||||
|
||||
size_t ModList::getPage() const {
|
||||
return m_page;
|
||||
}
|
||||
|
|
|
@ -33,9 +33,10 @@ protected:
|
|||
CCNode* m_topContainer;
|
||||
CCNode* m_searchMenu;
|
||||
CCNode* m_updateAllMenu = nullptr;
|
||||
CCMenuItemToggler* m_toggleUpdatesOnlyBtn = nullptr;
|
||||
TextArea* m_updateCountLabel = nullptr;
|
||||
TextInput* m_searchInput;
|
||||
EventListener<UpdateModListStateFilter> m_updateStateListener;
|
||||
EventListener<InvalidateCacheFilter> m_invalidateCacheListener;
|
||||
EventListener<PromiseEventFilter<std::vector<std::string>, server::ServerError>> m_checkUpdatesListener;
|
||||
bool m_bigSize = false;
|
||||
std::atomic<size_t> m_searchInputThreads = 0;
|
||||
|
@ -44,12 +45,15 @@ protected:
|
|||
|
||||
void updateTopContainer();
|
||||
void onCheckUpdates(PromiseEvent<std::vector<std::string>, server::ServerError>* event);
|
||||
void onInvalidateCache(InvalidateCacheEvent* event);
|
||||
|
||||
void onPromise(ModListSource::PageLoadEvent* event);
|
||||
void onPage(CCObject*);
|
||||
void onShowStatusDetails(CCObject*);
|
||||
void onFilters(CCObject*);
|
||||
void onClearFilters(CCObject*);
|
||||
void onToggleUpdates(CCObject*);
|
||||
void onUpdateAll(CCObject*);
|
||||
|
||||
public:
|
||||
static ModList* create(ModListSource* src, CCSize const& size);
|
||||
|
@ -60,7 +64,7 @@ public:
|
|||
void gotoPage(size_t page, bool update = false);
|
||||
void showStatus(ModListStatus status, std::string const& message, std::optional<std::string> const& details = std::nullopt);
|
||||
|
||||
void updatePageNumber();
|
||||
void updateState();
|
||||
void updateSize(bool big);
|
||||
void activateSearch(bool activate);
|
||||
};
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
#include "TagsPopup.hpp"
|
||||
|
||||
bool TagsPopup::setup(ModListSource* src, MiniFunction<void()> onClose) {
|
||||
bool TagsPopup::setup(ModListSource* src) {
|
||||
m_noElasticity = true;
|
||||
m_source = src;
|
||||
m_onClose = onClose;
|
||||
|
||||
this->setTitle("Select Tags");
|
||||
|
||||
|
@ -13,13 +12,13 @@ bool TagsPopup::setup(ModListSource* src, MiniFunction<void()> onClose) {
|
|||
}
|
||||
|
||||
void TagsPopup::onClose(CCObject* sender) {
|
||||
if (m_onClose) m_onClose();
|
||||
InvalidateCacheEvent(m_source).post();
|
||||
Popup::onClose(sender);
|
||||
}
|
||||
|
||||
TagsPopup* TagsPopup::create(ModListSource* src, MiniFunction<void()> onClose) {
|
||||
TagsPopup* TagsPopup::create(ModListSource* src) {
|
||||
auto ret = new TagsPopup();
|
||||
if (ret && ret->init(260, 200, src, onClose)) {
|
||||
if (ret && ret->init(260, 200, src)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -6,15 +6,14 @@
|
|||
|
||||
using namespace geode::prelude;
|
||||
|
||||
class TagsPopup : public GeodePopup<ModListSource*, MiniFunction<void()>> {
|
||||
class TagsPopup : public GeodePopup<ModListSource*> {
|
||||
protected:
|
||||
ModListSource* m_source;
|
||||
MiniFunction<void()> m_onClose;
|
||||
|
||||
bool setup(ModListSource* src, MiniFunction<void()> onClose) override;
|
||||
bool setup(ModListSource* src) override;
|
||||
|
||||
void onClose(CCObject*) override;
|
||||
|
||||
public:
|
||||
static TagsPopup* create(ModListSource* src, MiniFunction<void()> onClose);
|
||||
static TagsPopup* create(ModListSource* src);
|
||||
};
|
||||
|
|
|
@ -82,6 +82,17 @@ static void filterModsWithQuery(InstalledModListSource::ProvidedMods& mods, Inst
|
|||
mods.totalModCount = filtered.size();
|
||||
}
|
||||
|
||||
InvalidateCacheEvent::InvalidateCacheEvent(ModListSource* src) : source(src) {}
|
||||
|
||||
ListenerResult InvalidateCacheFilter::handle(MiniFunction<Callback> fn, InvalidateCacheEvent* event) {
|
||||
if (event->source == m_source) {
|
||||
fn(event);
|
||||
}
|
||||
return ListenerResult::Propagate;
|
||||
}
|
||||
|
||||
InvalidateCacheFilter::InvalidateCacheFilter(ModListSource* src) : m_source(src) {}
|
||||
|
||||
typename ModListSource::PagePromise ModListSource::loadPage(size_t page, bool update) {
|
||||
if (!update && m_cachedPages.contains(page)) {
|
||||
return PagePromise([this, page](auto resolve, auto) {
|
||||
|
@ -127,6 +138,7 @@ void ModListSource::reset() {
|
|||
void ModListSource::clearCache() {
|
||||
m_cachedPages.clear();
|
||||
m_cachedItemCount = std::nullopt;
|
||||
InvalidateCacheEvent(this).post();
|
||||
}
|
||||
void ModListSource::search(std::string const& query) {
|
||||
this->setSearchQuery(query);
|
||||
|
@ -211,9 +223,8 @@ InstalledModsQuery const& InstalledModListSource::getQuery() const {
|
|||
return m_query;
|
||||
}
|
||||
|
||||
InstalledModsQuery& InstalledModListSource::getQueryMut() {
|
||||
this->clearCache();
|
||||
return m_query;
|
||||
InvalidateQueryAfter<InstalledModsQuery> InstalledModListSource::getQueryMut() {
|
||||
return InvalidateQueryAfter(m_query, this);
|
||||
}
|
||||
|
||||
bool InstalledModListSource::isInstalledMods() const {
|
||||
|
@ -313,9 +324,8 @@ void ServerModListSource::setSearchQuery(std::string const& query) {
|
|||
server::ModsQuery const& ServerModListSource::getQuery() const {
|
||||
return m_query;
|
||||
}
|
||||
server::ModsQuery& ServerModListSource::getQueryMut() {
|
||||
this->clearCache();
|
||||
return m_query;
|
||||
InvalidateQueryAfter<server::ModsQuery> ServerModListSource::getQueryMut() {
|
||||
return InvalidateQueryAfter(m_query, this);
|
||||
}
|
||||
|
||||
bool ServerModListSource::isInstalledMods() const {
|
||||
|
|
|
@ -7,6 +7,26 @@
|
|||
|
||||
using namespace geode::prelude;
|
||||
|
||||
class ModListSource;
|
||||
|
||||
struct InvalidateCacheEvent : public Event {
|
||||
ModListSource* source;
|
||||
InvalidateCacheEvent(ModListSource* src);
|
||||
};
|
||||
|
||||
class InvalidateCacheFilter : public EventFilter<InvalidateCacheEvent> {
|
||||
protected:
|
||||
ModListSource* m_source;
|
||||
|
||||
public:
|
||||
using Callback = void(InvalidateCacheEvent*);
|
||||
|
||||
ListenerResult handle(MiniFunction<Callback> fn, InvalidateCacheEvent* event);
|
||||
|
||||
InvalidateCacheFilter() = default;
|
||||
InvalidateCacheFilter(ModListSource* src);
|
||||
};
|
||||
|
||||
struct InstalledModsQuery final {
|
||||
std::optional<std::string> query;
|
||||
bool onlyUpdates = false;
|
||||
|
@ -69,6 +89,22 @@ public:
|
|||
virtual bool wantsRestart() const = 0;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class InvalidateQueryAfter final {
|
||||
private:
|
||||
ModListSource* m_source;
|
||||
T& m_ref;
|
||||
|
||||
public:
|
||||
InvalidateQueryAfter(T& ref, ModListSource* source) : m_ref(ref), m_source(source) {}
|
||||
~InvalidateQueryAfter() {
|
||||
m_source->clearCache();
|
||||
}
|
||||
T* operator->() const {
|
||||
return &m_ref;
|
||||
}
|
||||
};
|
||||
|
||||
class InstalledModListSource : public ModListSource {
|
||||
protected:
|
||||
bool m_onlyUpdates;
|
||||
|
@ -85,8 +121,7 @@ public:
|
|||
void setSearchQuery(std::string const& query) override;
|
||||
|
||||
InstalledModsQuery const& getQuery() const;
|
||||
// Get mutable access to the current query; this clears the cache
|
||||
InstalledModsQuery& getQueryMut();
|
||||
InvalidateQueryAfter<InstalledModsQuery> getQueryMut();
|
||||
|
||||
bool isInstalledMods() const override;
|
||||
bool wantsRestart() const override;
|
||||
|
@ -115,8 +150,7 @@ public:
|
|||
void setSearchQuery(std::string const& query) override;
|
||||
|
||||
server::ModsQuery const& getQuery() const;
|
||||
// Get mutable access to the current query; this clears the cache
|
||||
server::ModsQuery& getQueryMut();
|
||||
InvalidateQueryAfter<server::ModsQuery> getQueryMut();
|
||||
|
||||
bool isInstalledMods() const override;
|
||||
bool wantsRestart() const override;
|
||||
|
|
Loading…
Reference in a new issue