does not compile! had to commit for laptop access

This commit is contained in:
HJfod 2024-02-23 13:28:32 +02:00
parent 9db76274b5
commit 7a4b6ddad2
5 changed files with 121 additions and 32 deletions

View file

@ -44,7 +44,7 @@ void BaseModItem::updateState() {
m_viewMenu->removeAllChildren();
if (this->wantsRestart()) {
auto restartSpr = ButtonSprite::create("Restart", "bigFont.fnt", "GE_button_02.png"_spr, .8f);
restartSpr->setScale(.5f);
restartSpr->setScale(.55f);
auto restartBtn = CCMenuItemSpriteExtra::create(
restartSpr, this, nullptr
);
@ -52,7 +52,7 @@ void BaseModItem::updateState() {
}
else {
auto viewSpr = ButtonSprite::create("View", "bigFont.fnt", "GE_button_05.png"_spr, .8f);
viewSpr->setScale(.5f);
viewSpr->setScale(.55f);
auto viewBtn = CCMenuItemSpriteExtra::create(
viewSpr, this, nullptr
);

View file

@ -0,0 +1,44 @@
#include "ModListSource.hpp"
static size_t INSTALLED_MODS_PAGE_SIZE = 10;
struct InstalledModsList : ModListSource {
std::string_view getID() const override {
return "installed";
}
Promise<Page> loadNewPage(size_t page, bool) {
// You can't load new mods at runtime so update does nothing
return Promise([](auto resolve, auto _reject, auto _progress) {
std::thread([res = std::move(resolve)] {
std::this_thread::sleep_for(std::chrono::seconds(3));
auto page = Page();
auto all = Loader::get()->getAllMods();
for (size_t i = page * INSTALLED_MODS_PAGE_SIZE; i < all.size(); i += 1) {
page.push_back(InstalledModItem::create(all.at(i)));
}
res(page);
}).detach();
});
}
Promise<size_t> loadTotalPageCount() const {
return Promise([](auto resolve, auto _reject, auto _progress) {
resolve(Loader::get()->getAllMods().size() / INSTALLED_MODS_PAGE_SIZE + 1);
});
}
static InstalledModsList& get() {
static auto inst = InstalledModsList();
return inst;
}
};
std::optional<std::reference_wrapper<ModListSource>> ModListSource::get(std::string_view id) {
switch (hash(id)) {
case hash("installed"): {
return InstalledModsList::get();
} break;
}
return std::nullopt;
}

View file

@ -0,0 +1,24 @@
#pragma once
#include <Geode/utils/cocos.hpp>
#include <Geode/utils/Promise.hpp>
#include "ModItem.hpp"
using namespace geode::prelude;
// Handles loading the entries for the mods list
struct ModListSource {
using Page = std::vector<Ref<BaseModItem>>;
// ID of the list source
virtual std::string_view getID() const = 0;
// Load a page. Use update to force a reload on existing page. Up to the
// source impl to cache this
virtual Promise<Page> loadNewPage(size_t page, bool update = false) = 0;
// Get the total number of available pages
virtual Promise<size_t> loadTotalPageCount() const = 0;
static std::optional<std::reference_wrapper<ModListSource>> get(std::string_view id);
};

View file

@ -37,6 +37,7 @@ bool ModsLayer::init() {
CircleBaseSize::Medium
);
reloadSpr->setScale(.8f);
reloadSpr->setTopOffset(ccp(1, 0));
auto reloadBtn = CCMenuItemSpriteExtra::create(
reloadSpr, this, menu_selector(ModsLayer::onRefreshList)
);
@ -97,33 +98,35 @@ bool ModsLayer::init() {
{ "gj_folderBtn_001.png", "Mod Packs", "mod-packs" },
{ "search.png"_spr, "Search", "search" },
}) {
const CCSize itemSize { 100, 40 };
const CCSize iconSize { 20, 20 };
const CCSize itemSize { 100, 35 };
const CCSize iconSize { 18, 18 };
auto spr = CCNode::create();
spr->setContentSize(itemSize);
spr->setAnchorPoint({ .5f, .5f });
auto disabledBG = CCScale9Sprite::createWithSpriteFrameName("tab-bg.png"_spr);
disabledBG->setContentSize(itemSize);
disabledBG->setScale(.8f);
disabledBG->setContentSize(itemSize / .8f);
disabledBG->setID("disabled-bg");
disabledBG->setColor({ 26, 24, 29 });
spr->addChildAtPosition(disabledBG, Anchor::Center);
auto enabledBG = CCScale9Sprite::createWithSpriteFrameName("tab-bg.png"_spr);
enabledBG->setContentSize(itemSize);
enabledBG->setScale(.8f);
enabledBG->setContentSize(itemSize / .8f);
enabledBG->setID("enabled-bg");
enabledBG->setColor({ 168, 147, 185 });
spr->addChildAtPosition(enabledBG, Anchor::Center);
auto icon = CCSprite::createWithSpriteFrameName(std::get<0>(item));
limitNodeSize(icon, iconSize, 3.f, .1f);
spr->addChildAtPosition(icon, Anchor::Left, ccp(itemSize.height / 2, 0), false);
spr->addChildAtPosition(icon, Anchor::Left, ccp(16, 0), false);
auto title = CCLabelBMFont::create(std::get<1>(item), "bigFont.fnt");
title->limitLabelWidth(spr->getContentWidth() - itemSize.height - 10, .55f, .1f);
title->limitLabelWidth(spr->getContentWidth() - 34, .55f, .1f);
title->setAnchorPoint({ .0f, .5f });
spr->addChildAtPosition(title, Anchor::Left, ccp(itemSize.height, 0), false);
spr->addChildAtPosition(title, Anchor::Left, ccp(28, 0), false);
auto btn = CCMenuItemSpriteExtra::create(spr, this, menu_selector(ModsLayer::onTab));
btn->setID(std::get<2>(item));
@ -142,26 +145,41 @@ bool ModsLayer::init() {
return true;
}
void ModsLayer::loadList(std::string const& id, bool update) {
if (m_currentList) {
m_currentList->scrollPosition = m_list->m_contentLayer->getPositionY();
void ModsLayer::loadList(std::string const& id) {
if (!m_currentListID.empty()) {
m_listPosCaches[m_currentListID].scrollPosition = m_list->m_contentLayer->getPositionY();
m_listPosCaches[m_currentListID].page = m_currentPage;
}
if (!m_listPosCaches.contains(id)) {
m_listPosCaches.insert_or_assign(id, ListPosCache {
.page = 0,
.scrollPosition = std::numeric_limits<float>::max(),
});
}
m_currentListID = id;
if (auto srcOpt = ModListSource::get(id)) {
auto& src = srcOpt.value().get();
src.loadTotalPageCount()
.then([this](size_t count) {
// todo: show count in UI
this->loadPage(m_listPosCaches.at(id).page);
});
}
else {
}
}
void ModsLayer::loadPage(size_t page, bool update) {
m_list->m_contentLayer->removeAllChildren();
if (!m_listItemsCache.contains(id) || update) {
ListCache cache;
switch (hash(id.c_str())) {
case hash("installed"): {
for (auto mod : Loader::get()->getAllMods()) {
cache.items.push_back(InstalledModItem::create(mod));
}
} break;
}
cache.id = id;
cache.scrollPosition = std::numeric_limits<float>::max();
m_listItemsCache[id] = std::move(cache);
if (auto srcOpt = ModListSource::get(m_currentListID)) {
auto& src = srcOpt.value().get();
src.loadNewPage();
}
auto& cache = m_listItemsCache.at(id);
for (auto item : cache.items) {
else {
}
for (auto item : cache.source.loadNewPage(m_currentPage, update)) {
m_list->m_contentLayer->addChild(item);
item->updateSize(m_list->getContentWidth(), BIG_VIEW);
}

View file

@ -3,12 +3,13 @@
#include <Geode/ui/General.hpp>
#include <Geode/ui/ScrollLayer.hpp>
#include "ModItem.hpp"
#include "ModListSource.hpp"
using namespace geode::prelude;
struct ListCache {
std::string id;
std::vector<Ref<BaseModItem>> items;
// Stores the current page and scroll position for a given list
struct ListPosCache {
size_t page;
float scrollPosition;
};
@ -16,15 +17,17 @@ class ModsLayer : public CCLayer {
protected:
std::vector<CCMenuItemSpriteExtra*> m_tabs;
ScrollLayer* m_list;
ListCache* m_currentList = nullptr;
std::unordered_map<std::string, ListCache> m_listItemsCache;
std::string m_currentListID;
size_t m_currentPage = 0;
std::unordered_map<std::string, ListPosCache> m_listPosCaches;
bool init();
void keyBackClicked() override;
void onTab(CCObject* sender);
void gotoTab(std::string const& id);
void loadList(std::string const& id, bool update = false);
void loadList(std::string const& id);
void loadPage(size_t page, bool update = false);
public:
static ModsLayer* create();