expanded view for mods list + fix member lambda errors

This commit is contained in:
HJfod 2022-09-04 21:24:33 +03:00
parent 67a88d7ffc
commit 6dc8660801
9 changed files with 122 additions and 33 deletions

View file

@ -400,10 +400,11 @@ namespace geode::cocos {
}
}
void assign(F&& func) {
if (!m_assigned) {
new (&m_lambda) F(func);
m_assigned = true;
if (m_assigned) {
m_lambda.~F();
}
new (&m_lambda) F(func);
m_assigned = true;
}
};
@ -438,6 +439,12 @@ namespace geode::cocos {
* callbacks that have to be members of a class without having to deal
* with all of the boilerplate associated with defining a new class
* member function.
*
* Do note that due to implementation problems, captures may have
* unexpected side-effects. In practice, lambda member functions with
* captures do not work properly in loops. If you assign the same
* member lambda to multiple different targets, they will share the
* same captured values.
*/
template<class Base, class Func>
static auto makeMemberFunction(Func&& function) {
@ -450,6 +457,12 @@ namespace geode::cocos {
* for adding callbacks to CCMenuItemSpriteExtras without needing to add
* the callback as a member to a class. Use the GEODE_MENU_SELECTOR class
* for even more concise code.
*
* Do note that due to implementation problems, captures may have
* unexpected side-effects. In practice, lambda member functions with
* captures do not work properly in loops. If you assign the same
* member lambda to multiple different targets, they will share the
* same captured values.
*/
template<class Func>
static cocos2d::SEL_MenuHandler makeMenuSelector(Func&& selector) {

View file

@ -7,7 +7,7 @@ static ModInfo getInternalModInfo() {
info.m_id = "geode.loader";
info.m_name = "Geode";
info.m_developer = "Geode Team";
info.m_description = "Internal representation";
info.m_description = "The mod loader";
info.m_details = LOADER_ABOUT_MD;
info.m_version = LOADER_VERSION;
info.m_supportsDisabling = false;

View file

@ -57,7 +57,7 @@ void Loader::updateResourcePaths() {
);
// add mods directory
CCFileUtils::sharedFileUtils()->addSearchPath(
(this->getGeodeDirectory() / GEODE_MOD_DIRECTORY).string().c_str()
(this->getGeodeDirectory() / GEODE_TEMP_DIRECTORY).string().c_str()
);
}

View file

@ -684,11 +684,11 @@ CCNode* ModInfoLayer::createLogoSpr(ModObject* modObj) {
CCNode* ModInfoLayer::createLogoSpr(Mod* mod) {
CCNode* spr = nullptr;
if (mod == Loader::getInternalMod()) {
spr = CCSprite::create("geode.api.png");
spr = CCSprite::createWithSpriteFrameName("geode-logo.png"_spr);
} else {
spr = CCSprite::create(
CCString::createWithFormat(
"%s.png",
"%s/logo.png",
mod->getID().c_str()
)->getCString()
);

View file

@ -55,8 +55,36 @@ bool ModListLayer::init() {
auto openBtn = CCMenuItemSpriteExtra::create(
openSpr, this, menu_selector(ModListLayer::onOpenFolder)
);
openBtn->setPosition(-winSize.width / 2 + 30.0f, - winSize.height / 2 + 80.0f);
this->m_menu->addChild(openBtn);
openBtn->setPosition(-winSize.width / 2 + 30.0f, -winSize.height / 2 + 80.0f);
m_menu->addChild(openBtn);
// add list display button
auto unextendedIconSpr = CCSprite::create("GJ_button_01.png");
unextendedIconSpr->setScale(.75f);
auto unextendedIconTopSpr = CCSprite::createWithSpriteFrameName("GJ_extendedIcon_001.png");
unextendedIconTopSpr->setPosition(unextendedIconSpr->getContentSize() / 2);
unextendedIconSpr->addChild(unextendedIconTopSpr);
auto extendedIconSpr = CCSprite::create("GJ_button_02.png");
extendedIconSpr->setScale(.75f);
auto extendedIconTopSpr = CCSprite::createWithSpriteFrameName("GJ_extendedIcon_001.png");
extendedIconTopSpr->setPosition(extendedIconSpr->getContentSize() / 2);
extendedIconSpr->addChild(extendedIconTopSpr);
auto listDisplayType = CCMenuItemToggler::create(
unextendedIconSpr,
extendedIconSpr,
this,
makeMenuSelector([this](CCMenuItemToggler* toggle) {
m_expandedList = !toggle->isToggled();
this->reloadList();
})
);
listDisplayType->setPosition(-210.f, .0f);
m_topMenu->addChild(listDisplayType);
// add list status label
@ -245,8 +273,11 @@ void ModListLayer::reloadList() {
m_searchInput &&
m_searchInput->getString() &&
strlen(m_searchInput->getString()) ?
std::optional<std::string>(m_searchInput->getString()) : std::nullopt;
auto list = ModListView::create(g_tab, 358.f, 190.f, m_query);
std::optional<std::string>(m_searchInput->getString()) :
std::nullopt;
auto list = ModListView::create(
g_tab, m_expandedList, 358.f, 190.f, m_query
);
list->setLayer(this);
// set list status

View file

@ -26,6 +26,7 @@ protected:
LoadingCircle* m_loadingCircle = nullptr;
ModListQuery m_query;
CCMenuItemSpriteExtra* m_filterBtn;
bool m_expandedList = false;
virtual ~ModListLayer();

View file

@ -116,7 +116,7 @@ void ModCell::setupLoadedButtons() {
m_enableToggle = CCMenuItemToggler::createWithStandardSprites(
this, menu_selector(ModCell::onEnable), .7f
);
m_enableToggle->setPosition(-50.f, 0.f);
m_enableToggle->setPosition(-45.f, 0.f);
m_menu->addChild(m_enableToggle);
}
@ -127,11 +127,10 @@ void ModCell::setupLoadedButtons() {
exMark, this, menu_selector(ModCell::onUnresolvedInfo)
);
m_unresolvedExMark->setPosition(-80.f, 0.f);
m_unresolvedExMark->setVisible(false);
m_menu->addChild(m_unresolvedExMark);
if (!m_obj->m_mod->wasSuccesfullyLoaded()) {
m_unresolvedExMark->setVisible(false);
} else {
if (m_obj->m_mod->wasSuccesfullyLoaded()) {
if (Index::get()->isUpdateAvailableForItem(m_obj->m_mod->getID())) {
viewSpr->updateBGImage("GE_button_01.png"_spr);
@ -167,10 +166,10 @@ void ModCell::loadFromObject(ModObject* modobj) {
m_backgroundLayer->setOpacity(255);
m_menu = CCMenu::create();
m_menu->setPosition(m_width - m_height, m_height / 2);
m_menu->setPosition(m_width - 40.f, m_height / 2);
m_mainLayer->addChild(m_menu);
auto logoSize = m_height - 12.f;
auto logoSize = m_height / 1.5f;
auto logoSpr = ModInfoLayer::createLogoSpr(modobj);
logoSpr->setPosition({ logoSize / 2 + 12.f, m_height / 2 });
@ -190,10 +189,15 @@ void ModCell::loadFromObject(ModObject* modobj) {
default: return;
}
bool hasDesc = m_expanded && info.m_description.size();
auto titleLabel = CCLabelBMFont::create(info.m_name.c_str(), "bigFont.fnt");
titleLabel->setAnchorPoint({ .0f, .5f });
titleLabel->setPosition(m_height / 2 + logoSize, m_height / 2 + 7.f);
titleLabel->limitLabelWidth(m_width / 2 - 30.f, .5f, .1f);
titleLabel->setPosition(
m_height / 2 + logoSize / 2 + 13.f,
(hasDesc ? m_height / 2 + 15.f : m_height / 2 + 7.f)
);
titleLabel->limitLabelWidth(m_width / 2 - 40.f, .5f, .1f);
m_mainLayer->addChild(titleLabel);
auto versionLabel = CCLabelBMFont::create(
@ -203,7 +207,7 @@ void ModCell::loadFromObject(ModObject* modobj) {
versionLabel->setScale(.3f);
versionLabel->setPosition(
titleLabel->getPositionX() + titleLabel->getScaledContentSize().width + 5.f,
m_height / 2 + 7.f
(hasDesc ? m_height / 2 + 15.f : m_height / 2 + 7.f)
);
versionLabel->setColor({ 0, 255, 0 });
m_mainLayer->addChild(versionLabel);
@ -214,9 +218,40 @@ void ModCell::loadFromObject(ModObject* modobj) {
);
creatorLabel->setAnchorPoint({ .0f, .5f });
creatorLabel->setScale(.43f);
creatorLabel->setPosition(m_height / 2 + logoSize, m_height / 2 - 7.f);
creatorLabel->setPosition(
m_height / 2 + logoSize / 2 + 13.f,
(hasDesc ? m_height / 2 : m_height / 2 - 7.f)
);
m_mainLayer->addChild(creatorLabel);
if (hasDesc) {
auto descBG = CCScale9Sprite::create(
"square02b_001.png", { 0.0f, 0.0f, 80.0f, 80.0f }
);
descBG->setColor({ 0, 0, 0 });
descBG->setOpacity(90);
descBG->setContentSize({ m_width * 2, 60.f });
descBG->setAnchorPoint({ .0f, .5f });
descBG->setPosition(
m_height / 2 + logoSize / 2 + 13.f,
m_height / 2 - 17.f
);
descBG->setScale(.25f);
m_mainLayer->addChild(descBG);
auto descText = CCLabelBMFont::create(
info.m_description.c_str(),
"chatFont.fnt"
);
descText->setAnchorPoint({ .0f, .5f });
descText->setPosition(
m_height / 2 + logoSize / 2 + 18.f,
m_height / 2 - 17.f
);
descText->limitLabelWidth(m_width / 2 - 10.f, .5f, .1f);
m_mainLayer->addChild(descText);
}
switch (modobj->m_type) {
case ModObjectType::Mod:
this->setupLoadedButtons();
@ -285,8 +320,9 @@ void ModCell::onUnresolvedInfo(CCObject* pSender) {
)->show();
}
bool ModCell::init(ModListView* list) {
bool ModCell::init(ModListView* list, bool expanded) {
m_list = list;
m_expanded = expanded;
return true;
}
@ -305,9 +341,9 @@ void ModCell::updateState(bool invert) {
}
}
ModCell* ModCell::create(ModListView* list, const char* key, CCSize size) {
ModCell* ModCell::create(ModListView* list, bool expanded, const char* key, CCSize size) {
auto pRet = new ModCell(key, size);
if (pRet && pRet->init(list)) {
if (pRet && pRet->init(list, expanded)) {
return pRet;
}
CC_SAFE_DELETE(pRet);
@ -322,7 +358,7 @@ void ModListView::updateAllStates(ModCell* toggled) {
}
void ModListView::setupList() {
m_itemSeparation = 40.0f;
m_itemSeparation = m_expandedList ? 60.f : 40.0f;
if (!m_entries->count()) return;
@ -346,7 +382,7 @@ void ModListView::setupList() {
}
TableViewCell* ModListView::getListCell(const char* key) {
return ModCell::create(this, key, { m_width, m_itemSeparation });
return ModCell::create(this, m_expandedList, key, { m_width, m_itemSeparation });
}
void ModListView::loadCell(TableViewCell* cell, unsigned int index) {
@ -443,10 +479,12 @@ static std::vector<Mod*> sortedInstalledMods() {
bool ModListView::init(
CCArray* mods,
ModListType type,
bool expanded,
float width,
float height,
ModListQuery query
) {
m_expandedList = expanded;
if (!mods) {
switch (type) {
case ModListType::Installed: {
@ -501,13 +539,14 @@ bool ModListView::init(
ModListView* ModListView::create(
CCArray* mods,
ModListType type,
bool expanded,
float width,
float height,
ModListQuery const& query
) {
auto pRet = new ModListView;
if (pRet) {
if (pRet->init(mods, type, width, height, query)) {
if (pRet->init(mods, type, expanded, width, height, query)) {
pRet->autorelease();
return pRet;
}
@ -518,11 +557,12 @@ ModListView* ModListView::create(
ModListView* ModListView::create(
ModListType type,
bool expanded,
float width,
float height,
ModListQuery const& query
) {
return ModListView::create(nullptr, type, width, height, query);
return ModListView::create(nullptr, type, expanded, width, height, query);
}
ModListView::Status ModListView::getStatus() const {

View file

@ -52,6 +52,7 @@ protected:
CCMenu* m_menu;
CCMenuItemToggler* m_enableToggle = nullptr;
CCMenuItemSpriteExtra* m_unresolvedExMark;
bool m_expanded;
ModCell(const char* name, CCSize size);
@ -67,14 +68,14 @@ protected:
void FLAlert_Clicked(FLAlertLayer*, bool btn2) override;
bool init(ModListView* list);
bool init(ModListView* list, bool expanded);
public:
void updateBGColor(int index);
void loadFromObject(ModObject*);
void updateState(bool invert = false);
static ModCell* create(ModListView* list, const char* key, CCSize size);
static ModCell* create(ModListView* list, bool expanded, const char* key, CCSize size);
};
struct SearchFlag {
@ -116,6 +117,7 @@ protected:
Status m_status = Status::OK;
ModListLayer* m_layer = nullptr;
bool m_expandedList;
void setupList() override;
TableViewCell* getListCell(const char* key) override;
@ -124,6 +126,7 @@ protected:
bool init(
CCArray* mods,
ModListType type,
bool expanded,
float width,
float height,
ModListQuery query
@ -135,12 +138,14 @@ public:
static ModListView* create(
CCArray* mods,
ModListType type = ModListType::Installed,
bool expanded = false,
float width = 358.f,
float height = 220.f,
ModListQuery const& query = ModListQuery()
);
static ModListView* create(
ModListType type,
bool expanded = false,
float width = 358.f,
float height = 220.f,
ModListQuery const& query = ModListQuery()

View file

@ -87,9 +87,8 @@ bool SearchFilterPopup::setup(ModListLayer* layer, ModListType type) {
this->addToggle(
category.c_str(),
makeMenuSelector([this](CCMenuItemToggler* toggle) {
// seems like C++ generates the same lambda if you try to
// capture category so all toggles will use the same one
// which is not wanted
// due to implementation problems in makeMemberFunction,
// category can't be passed through capture
try {
if (!toggle->isToggled()) {
m_modLayer->m_query.m_categories.insert(