mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
expanded view for mods list + fix member lambda errors
This commit is contained in:
parent
67a88d7ffc
commit
6dc8660801
9 changed files with 122 additions and 33 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -26,6 +26,7 @@ protected:
|
|||
LoadingCircle* m_loadingCircle = nullptr;
|
||||
ModListQuery m_query;
|
||||
CCMenuItemSpriteExtra* m_filterBtn;
|
||||
bool m_expandedList = false;
|
||||
|
||||
virtual ~ModListLayer();
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue