mirror of
https://github.com/geode-sdk/geode.git
synced 2025-03-24 03:39:56 -04:00
initial work on new ui
This commit is contained in:
parent
6b59217ce1
commit
8985b32fc2
27 changed files with 515 additions and 89 deletions
loader
CMakeLists.txt
include/Geode/ui
resources
download.pngmod.json.inmods-list-bottom.pngmods-list-side.pngmods-list-top.pngsearch.png
swelve
tab-bg.pngsrc
|
@ -66,6 +66,7 @@ file(GLOB SOURCES CONFIGURE_DEPENDS
|
|||
src/utils/*.cpp
|
||||
src/ui/*.cpp
|
||||
src/ui/nodes/*.cpp
|
||||
src/ui/mods/*.cpp
|
||||
src/ui/internal/*.cpp
|
||||
src/ui/internal/info/*.cpp
|
||||
src/ui/internal/list/*.cpp
|
||||
|
|
|
@ -11,6 +11,31 @@ namespace geode {
|
|||
*/
|
||||
GEODE_DLL cocos2d::CCSprite* createLayerBG();
|
||||
|
||||
enum class SideArt {
|
||||
BottomLeft = 0b0001,
|
||||
BottomRight = 0b0010,
|
||||
TopLeft = 0b0100,
|
||||
TopRight = 0b1000,
|
||||
Bottom = 0b0011,
|
||||
Top = 0b1100,
|
||||
All = 0b1111,
|
||||
};
|
||||
constexpr SideArt operator|(SideArt a, SideArt b) {
|
||||
return static_cast<SideArt>(static_cast<int>(a) | static_cast<int>(b));
|
||||
}
|
||||
constexpr bool operator&(SideArt a, SideArt b) {
|
||||
return static_cast<bool>(static_cast<int>(a) & static_cast<int>(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add side art (corner pieces) for a layer
|
||||
* @param to Layer to add corner pieces to
|
||||
* @param sides Which corners to populate; by default, populates all
|
||||
* @param useAnchorLayout If true, `to` is given an `AnchorLayout` and the
|
||||
* corners' positions are dynamically updated
|
||||
*/
|
||||
GEODE_DLL void addSideArt(cocos2d::CCNode* to, SideArt sides = SideArt::All, bool useAnchorLayout = false);
|
||||
|
||||
/**
|
||||
* Add the rounded comment borders to a node
|
||||
*/
|
||||
|
|
|
@ -30,23 +30,14 @@ namespace geode {
|
|||
GEODE_DLL void openSettingsPopup(Mod* mod);
|
||||
/**
|
||||
* Create a default logo sprite
|
||||
* @param size Size of the sprite
|
||||
*/
|
||||
GEODE_DLL cocos2d::CCNode* createDefaultLogo(
|
||||
cocos2d::CCSize const& size
|
||||
);
|
||||
GEODE_DLL cocos2d::CCNode* createDefaultLogo();
|
||||
/**
|
||||
* Create a logo sprite for a mod
|
||||
* @param size Size of the sprite
|
||||
*/
|
||||
GEODE_DLL cocos2d::CCNode* createModLogo(
|
||||
Mod* mod, cocos2d::CCSize const& size
|
||||
);
|
||||
GEODE_DLL cocos2d::CCNode* createModLogo(Mod* mod);
|
||||
/**
|
||||
* Create a logo sprite for an index item
|
||||
* @param size Size of the sprite
|
||||
*/
|
||||
GEODE_DLL cocos2d::CCNode* createIndexItemLogo(
|
||||
IndexItemHandle item, cocos2d::CCSize const& size
|
||||
);
|
||||
GEODE_DLL cocos2d::CCNode* createIndexItemLogo(IndexItemHandle item);
|
||||
}
|
||||
|
|
BIN
loader/resources/download.png
Normal file
BIN
loader/resources/download.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 9.7 KiB |
|
@ -50,6 +50,9 @@
|
|||
],
|
||||
"BlankSheet": [
|
||||
"blanks/*.png"
|
||||
],
|
||||
"SwelveSheet": [
|
||||
"swelve/*.png"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
BIN
loader/resources/mods-list-bottom.png
Normal file
BIN
loader/resources/mods-list-bottom.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 5.3 KiB |
BIN
loader/resources/mods-list-side.png
Normal file
BIN
loader/resources/mods-list-side.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 623 B |
BIN
loader/resources/mods-list-top.png
Normal file
BIN
loader/resources/mods-list-top.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 6.3 KiB |
BIN
loader/resources/search.png
Normal file
BIN
loader/resources/search.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 17 KiB |
BIN
loader/resources/swelve/layer0.png
Normal file
BIN
loader/resources/swelve/layer0.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 2 KiB |
BIN
loader/resources/swelve/layer1.png
Normal file
BIN
loader/resources/swelve/layer1.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 3 KiB |
BIN
loader/resources/swelve/layer2.png
Normal file
BIN
loader/resources/swelve/layer2.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 2.1 KiB |
BIN
loader/resources/swelve/layer3.png
Normal file
BIN
loader/resources/swelve/layer3.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 267 B |
BIN
loader/resources/tab-bg.png
Normal file
BIN
loader/resources/tab-bg.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 3.2 KiB |
|
@ -1,5 +1,4 @@
|
|||
#include "../ui/internal/list/ModListLayer.hpp"
|
||||
|
||||
#include "../ui/mods/ModsLayer.hpp"
|
||||
#include <Geode/loader/Index.hpp>
|
||||
#include <Geode/modify/MenuLayer.hpp>
|
||||
#include <Geode/modify/Modify.hpp>
|
||||
|
@ -334,6 +333,6 @@ struct CustomMenuLayer : Modify<CustomMenuLayer, MenuLayer> {
|
|||
}
|
||||
|
||||
void onGeode(CCObject*) {
|
||||
ModListLayer::scene();
|
||||
ModsLayer::scene();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -66,66 +66,40 @@ void geode::openSettingsPopup(Mod* mod) {
|
|||
}
|
||||
}
|
||||
|
||||
CCNode* geode::createDefaultLogo(CCSize const& size) {
|
||||
CCNode* geode::createDefaultLogo() {
|
||||
CCNode* spr = CCSprite::createWithSpriteFrameName("no-logo.png"_spr);
|
||||
if (!spr) {
|
||||
spr = CCLabelBMFont::create("OwO", "goldFont.fnt");
|
||||
}
|
||||
limitNodeSize(spr, size, 1.f, .01f);
|
||||
return spr;
|
||||
}
|
||||
|
||||
CCNode* geode::createModLogo(Mod* mod, CCSize const& size) {
|
||||
CCNode* spr = mod == Mod::get() ?
|
||||
CCSprite::createWithSpriteFrameName("geode-logo.png"_spr) :
|
||||
CCSprite::create(fmt::format("{}/logo.png", mod->getID()).c_str());
|
||||
if (!spr) spr = CCSprite::createWithSpriteFrameName("no-logo.png"_spr);
|
||||
if (!spr) spr = CCLabelBMFont::create("N/A", "goldFont.fnt");
|
||||
limitNodeSize(spr, size, 1.f, .01f);
|
||||
spr->setPosition(size/2);
|
||||
spr->setAnchorPoint({.5f, .5f});
|
||||
|
||||
auto node = CCNode::create();
|
||||
node->addChild(spr);
|
||||
node->setContentSize(size);
|
||||
return node;
|
||||
CCNode* geode::createModLogo(Mod* mod) {
|
||||
CCNode* ret = nullptr;
|
||||
if (mod == Mod::get()) {
|
||||
ret = CCSprite::createWithSpriteFrameName("geode-logo.png"_spr);
|
||||
}
|
||||
else {
|
||||
ret = CCSprite::create(fmt::format("{}/logo.png", mod->getID()).c_str());
|
||||
}
|
||||
if (!ret) {
|
||||
ret = createDefaultLogo();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CCNode* geode::createIndexItemLogo(IndexItemHandle item, CCSize const& size) {
|
||||
CCNode* geode::createIndexItemLogo(IndexItemHandle item) {
|
||||
auto logoPath = ghc::filesystem::absolute(item->getRootPath() / "logo.png");
|
||||
CCNode* spr = CCSprite::create(logoPath.string().c_str());
|
||||
if (!spr) {
|
||||
spr = CCSprite::createWithSpriteFrameName("no-logo.png"_spr);
|
||||
}
|
||||
if (!spr) {
|
||||
spr = CCLabelBMFont::create("N/A", "goldFont.fnt");
|
||||
spr = createDefaultLogo();
|
||||
}
|
||||
if (item->isFeatured()) {
|
||||
auto glowSize = size + CCSize(4.f, 4.f);
|
||||
|
||||
auto logoGlow = CCSprite::createWithSpriteFrameName("logo-glow.png"_spr);
|
||||
logoGlow->setScaleX(glowSize.width / logoGlow->getContentSize().width);
|
||||
logoGlow->setScaleY(glowSize.height / logoGlow->getContentSize().height);
|
||||
|
||||
// i dont know why + 1 is needed and its too late for me to figure out why
|
||||
spr->setPosition(
|
||||
logoGlow->getContentSize().width / 2 + 1,
|
||||
logoGlow->getContentSize().height / 2 - 1
|
||||
);
|
||||
// scary mathematics
|
||||
spr->setScaleX(size.width / spr->getContentSize().width / logoGlow->getScaleX());
|
||||
spr->setScaleY(size.height / spr->getContentSize().height / logoGlow->getScaleY());
|
||||
logoGlow->addChild(spr);
|
||||
spr->setScaleX(logoGlow->getContentWidth() / spr->getContentWidth());
|
||||
spr->setScaleY(logoGlow->getContentHeight() / spr->getContentHeight());
|
||||
logoGlow->addChildAtPosition(spr, Anchor::Center);
|
||||
spr = logoGlow;
|
||||
}
|
||||
else {
|
||||
limitNodeSize(spr, size, 1.f, .01f);
|
||||
}
|
||||
spr->setPosition(size/2);
|
||||
spr->setAnchorPoint({.5f, .5f});
|
||||
|
||||
auto node = CCNode::create();
|
||||
node->addChild(spr);
|
||||
node->setContentSize(size);
|
||||
return node;
|
||||
return spr;
|
||||
}
|
||||
|
|
|
@ -444,7 +444,7 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
|
|||
}
|
||||
|
||||
CCNode* LocalModInfoPopup::createLogo(CCSize const& size) {
|
||||
return geode::createModLogo(m_mod, size);
|
||||
return geode::createModLogo(m_mod);
|
||||
}
|
||||
|
||||
ModMetadata LocalModInfoPopup::getMetadata() const {
|
||||
|
@ -677,7 +677,7 @@ void IndexItemInfoPopup::onInstall(CCObject*) {
|
|||
}
|
||||
|
||||
CCNode* IndexItemInfoPopup::createLogo(CCSize const& size) {
|
||||
return geode::createIndexItemLogo(m_item, size);
|
||||
return geode::createIndexItemLogo(m_item);
|
||||
}
|
||||
|
||||
ModMetadata IndexItemInfoPopup::getMetadata() const {
|
||||
|
|
|
@ -168,7 +168,7 @@ ModInstallListCell* ModInstallListCell::create(Mod* mod, InstallListPopup* list,
|
|||
}
|
||||
|
||||
CCNode* ModInstallListCell::createLogo(CCSize const& size) {
|
||||
return geode::createModLogo(m_mod, size);
|
||||
return geode::createModLogo(m_mod);
|
||||
}
|
||||
std::string ModInstallListCell::getID() const {
|
||||
return m_mod->getID();
|
||||
|
@ -292,7 +292,7 @@ IndexItemInstallListCell* IndexItemInstallListCell::create(
|
|||
}
|
||||
|
||||
CCNode* IndexItemInstallListCell::createLogo(CCSize const& size) {
|
||||
return geode::createIndexItemLogo(m_item, size);
|
||||
return geode::createIndexItemLogo(m_item);
|
||||
}
|
||||
std::string IndexItemInstallListCell::getID() const {
|
||||
return m_item->getMetadata().getID();
|
||||
|
@ -354,7 +354,7 @@ UnknownInstallListCell* UnknownInstallListCell::create(
|
|||
}
|
||||
|
||||
CCNode* UnknownInstallListCell::createLogo(CCSize const& size) {
|
||||
return geode::createDefaultLogo(size);
|
||||
return geode::createDefaultLogo();
|
||||
}
|
||||
std::string UnknownInstallListCell::getID() const {
|
||||
return m_dependency.id;
|
||||
|
@ -401,7 +401,7 @@ SelectVersionCell* SelectVersionCell::create(IndexItemHandle item, SelectVersion
|
|||
}
|
||||
|
||||
CCNode* SelectVersionCell::createLogo(CCSize const& size) {
|
||||
return geode::createIndexItemLogo(m_item, size);
|
||||
return geode::createIndexItemLogo(m_item);
|
||||
}
|
||||
std::string SelectVersionCell::getID() const {
|
||||
return m_item->getMetadata().getID();
|
||||
|
|
|
@ -344,7 +344,7 @@ std::optional<ModMetadata> ModCell::getModMetadata() const {
|
|||
}
|
||||
|
||||
CCNode* ModCell::createLogo(CCSize const& size) {
|
||||
return geode::createModLogo(m_mod, size);
|
||||
return geode::createModLogo(m_mod);
|
||||
}
|
||||
|
||||
// IndexItemCell
|
||||
|
@ -434,7 +434,7 @@ std::optional<ModMetadata> IndexItemCell::getModMetadata() const {
|
|||
}
|
||||
|
||||
CCNode* IndexItemCell::createLogo(CCSize const& size) {
|
||||
return geode::createIndexItemLogo(m_item, size);
|
||||
return geode::createIndexItemLogo(m_item);
|
||||
}
|
||||
|
||||
// InvalidGeodeFileCell
|
||||
|
|
83
loader/src/ui/mods/ModItem.cpp
Normal file
83
loader/src/ui/mods/ModItem.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
#include "ModItem.hpp"
|
||||
#include <Geode/ui/GeodeUI.hpp>
|
||||
|
||||
bool BaseModItem::init() {
|
||||
if (!CCNode::init())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BaseModItem::setupCommonInfo() {
|
||||
auto meta = this->getMetadata();
|
||||
|
||||
m_logo = this->createModLogo();
|
||||
this->addChild(m_logo);
|
||||
|
||||
m_title = CCLabelBMFont::create(meta.getName().c_str(), "bigFont.fnt");
|
||||
m_title->setAnchorPoint({ .0f, .5f });
|
||||
this->addChild(m_title);
|
||||
|
||||
auto by = "By " + ModMetadata::formatDeveloperDisplayString(meta.getDevelopers());
|
||||
auto developersBtn = CCMenuItemSpriteExtra::create(
|
||||
CCLabelBMFont::create(by.c_str(), "goldFont.fnt"),
|
||||
this, nullptr
|
||||
);
|
||||
m_developers = CCMenu::create();
|
||||
m_developers->ignoreAnchorPointForPosition(false);
|
||||
m_developers->setContentSize(developersBtn->getScaledContentSize());
|
||||
m_developers->addChildAtPosition(developersBtn, Anchor::Center);
|
||||
m_developers->setAnchorPoint({ .0f, .5f });
|
||||
this->addChild(m_developers);
|
||||
}
|
||||
|
||||
void BaseModItem::updateSize(float width, bool big) {
|
||||
this->setContentSize({ width, big ? 40.f : 25.f });
|
||||
|
||||
if (m_logo) {
|
||||
auto logoSize = m_obContentSize.height - 5;
|
||||
limitNodeSize(m_logo, { logoSize, logoSize }, 999, .1f);
|
||||
m_logo->setPosition(m_obContentSize.height / 2 + 5, m_obContentSize.height / 2);
|
||||
}
|
||||
CCSize titleSpace {
|
||||
m_obContentSize.width / 2 - m_obContentSize.height,
|
||||
m_obContentSize.height / 2
|
||||
};
|
||||
if (m_title) {
|
||||
m_title->setPosition(m_obContentSize.height + 10, m_obContentSize.height * .7f);
|
||||
limitNodeSize(m_title, titleSpace, 1.f, .1f);
|
||||
}
|
||||
if (m_developers) {
|
||||
m_developers->setPosition(m_obContentSize.height + 10, m_obContentSize.height * .3f);
|
||||
limitNodeSize(m_developers, titleSpace, .6f, .1f);
|
||||
}
|
||||
}
|
||||
|
||||
bool InstalledModItem::init(Mod* mod) {
|
||||
if (!BaseModItem::init())
|
||||
return false;
|
||||
|
||||
m_mod = mod;
|
||||
|
||||
this->setupCommonInfo();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
InstalledModItem* InstalledModItem::create(Mod* mod) {
|
||||
auto ret = new InstalledModItem();
|
||||
if (ret && ret->init(mod)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
CC_SAFE_DELETE(ret);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ModMetadata InstalledModItem::getMetadata() const {
|
||||
return m_mod->getMetadata();
|
||||
}
|
||||
|
||||
CCNode* InstalledModItem::createModLogo() const {
|
||||
return geode::createModLogo(m_mod);
|
||||
}
|
35
loader/src/ui/mods/ModItem.hpp
Normal file
35
loader/src/ui/mods/ModItem.hpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/ui/General.hpp>
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
class BaseModItem : public CCNode {
|
||||
protected:
|
||||
CCNode* m_logo = nullptr;
|
||||
CCNode* m_title = nullptr;
|
||||
CCNode* m_developers = nullptr;
|
||||
|
||||
bool init();
|
||||
|
||||
void setupCommonInfo();
|
||||
|
||||
public:
|
||||
virtual ModMetadata getMetadata() const = 0;
|
||||
virtual CCNode* createModLogo() const = 0;
|
||||
|
||||
virtual void updateSize(float width, bool big);
|
||||
};
|
||||
|
||||
class InstalledModItem : public BaseModItem {
|
||||
protected:
|
||||
Mod* m_mod;
|
||||
|
||||
bool init(Mod* mod);
|
||||
|
||||
public:
|
||||
static InstalledModItem* create(Mod* mod);
|
||||
|
||||
ModMetadata getMetadata() const override;
|
||||
CCNode* createModLogo() const override;
|
||||
};
|
193
loader/src/ui/mods/ModsLayer.cpp
Normal file
193
loader/src/ui/mods/ModsLayer.cpp
Normal file
|
@ -0,0 +1,193 @@
|
|||
#include "ModsLayer.hpp"
|
||||
#include "SwelvyBG.hpp"
|
||||
|
||||
static bool BIG_VIEW = false;
|
||||
|
||||
bool ModsLayer::init() {
|
||||
if (!CCLayer::init())
|
||||
return false;
|
||||
|
||||
auto winSize = CCDirector::get()->getWinSize();
|
||||
|
||||
this->addChild(SwelvyBG::create());
|
||||
|
||||
auto backMenu = CCMenu::create();
|
||||
backMenu->setContentWidth(100.f);
|
||||
backMenu->setAnchorPoint({ .0f, .5f });
|
||||
|
||||
auto backSpr = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png");
|
||||
auto backBtn = CCMenuItemSpriteExtra::create(
|
||||
backSpr, this, menu_selector(ModsLayer::onBack)
|
||||
);
|
||||
backMenu->addChild(backBtn);
|
||||
backMenu->setLayout(
|
||||
RowLayout::create()
|
||||
->setAxisAlignment(AxisAlignment::Start)
|
||||
);
|
||||
|
||||
this->addChildAtPosition(backMenu, Anchor::TopLeft, ccp(12, -25), false);
|
||||
|
||||
auto frame = CCNode::create();
|
||||
frame->setAnchorPoint({ .5f, .5f });
|
||||
frame->setContentSize({ 380, 205 });
|
||||
|
||||
auto frameBG = CCLayerColor::create({ 25, 17, 37, 255 });
|
||||
frameBG->setContentSize(frame->getContentSize());
|
||||
frameBG->ignoreAnchorPointForPosition(false);
|
||||
frame->addChildAtPosition(frameBG, Anchor::Center);
|
||||
|
||||
auto tabsTop = CCSprite::createWithSpriteFrameName("mods-list-top.png"_spr);
|
||||
tabsTop->setAnchorPoint({ .5f, .0f });
|
||||
frame->addChildAtPosition(tabsTop, Anchor::Top, ccp(0, -2));
|
||||
|
||||
auto tabsLeft = CCSprite::createWithSpriteFrameName("mods-list-side.png"_spr);
|
||||
tabsLeft->setScaleY(frame->getContentHeight() / tabsLeft->getContentHeight());
|
||||
frame->addChildAtPosition(tabsLeft, Anchor::Left, ccp(6, 0));
|
||||
|
||||
auto tabsRight = CCSprite::createWithSpriteFrameName("mods-list-side.png"_spr);
|
||||
tabsRight->setFlipX(true);
|
||||
tabsRight->setScaleY(frame->getContentHeight() / tabsRight->getContentHeight());
|
||||
frame->addChildAtPosition(tabsRight, Anchor::Right, ccp(-6, 0));
|
||||
|
||||
auto tabsBottom = CCSprite::createWithSpriteFrameName("mods-list-bottom.png"_spr);
|
||||
tabsBottom->setAnchorPoint({ .5f, 1.f });
|
||||
frame->addChildAtPosition(tabsBottom, Anchor::Bottom, ccp(0, 2));
|
||||
|
||||
this->addChildAtPosition(frame, Anchor::Center, ccp(0, -10), false);
|
||||
|
||||
m_list = ScrollLayer::create(frame->getContentSize() - ccp(24, 0));
|
||||
m_list->m_contentLayer->setLayout(
|
||||
ColumnLayout::create()
|
||||
->setAxisReverse(true)
|
||||
->setAxisAlignment(AxisAlignment::End)
|
||||
->setAutoGrowAxis(frame->getContentHeight())
|
||||
);
|
||||
this->addChildAtPosition(m_list, Anchor::Center, -m_list->getScaledContentSize() / 2 - ccp(0, 10), false);
|
||||
|
||||
auto mainTabs = CCMenu::create();
|
||||
mainTabs->setContentWidth(tabsTop->getContentWidth() - 45);
|
||||
mainTabs->setAnchorPoint({ .5f, .0f });
|
||||
mainTabs->setPosition(frame->convertToWorldSpace(tabsTop->getPosition() + ccp(0, 10)));
|
||||
|
||||
for (auto item : std::initializer_list<std::tuple<const char*, const char*, const char*>> {
|
||||
{ "download.png"_spr, "Installed", "installed" },
|
||||
{ "GJ_bigStar_noShadow_001.png", "Featured", "featured" },
|
||||
{ "GJ_sTrendingIcon_001.png", "Trending", "trending" },
|
||||
{ "gj_folderBtn_001.png", "Mod Packs", "mod-packs" },
|
||||
{ "search.png"_spr, "Search", "search" },
|
||||
}) {
|
||||
const CCSize itemSize { 100, 40 };
|
||||
const CCSize iconSize { 20, 20 };
|
||||
|
||||
auto spr = CCNode::create();
|
||||
spr->setContentSize(itemSize);
|
||||
spr->setAnchorPoint({ .5f, .5f });
|
||||
|
||||
auto disabledBG = CCScale9Sprite::createWithSpriteFrameName("tab-bg.png"_spr);
|
||||
disabledBG->setContentSize(itemSize);
|
||||
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->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(iconSize.width / 2 + 5, 0), false);
|
||||
|
||||
auto title = CCLabelBMFont::create(std::get<1>(item), "bigFont.fnt");
|
||||
title->limitLabelWidth(spr->getContentWidth() - iconSize.width - 15, .55f, .1f);
|
||||
title->setAnchorPoint({ .0f, .5f });
|
||||
spr->addChildAtPosition(title, Anchor::Left, ccp((iconSize.width + 10), 0), false);
|
||||
|
||||
auto btn = CCMenuItemSpriteExtra::create(spr, this, menu_selector(ModsLayer::onTab));
|
||||
btn->setID(std::get<2>(item));
|
||||
mainTabs->addChild(btn);
|
||||
m_tabs.push_back(btn);
|
||||
}
|
||||
|
||||
mainTabs->setLayout(RowLayout::create());
|
||||
this->addChild(mainTabs);
|
||||
|
||||
this->gotoTab("installed");
|
||||
|
||||
this->setKeypadEnabled(true);
|
||||
cocos::handleTouchPriority(this, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModsLayer::loadList(std::string const& id, bool update) {
|
||||
if (m_currentList) {
|
||||
m_currentList->scrollPosition = m_list->m_contentLayer->getPositionY();
|
||||
}
|
||||
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.scrollPosition = std::numeric_limits<float>::max();
|
||||
m_listItemsCache[id] = std::move(cache);
|
||||
}
|
||||
auto& cache = m_listItemsCache.at(id);
|
||||
for (auto item : cache.items) {
|
||||
m_list->m_contentLayer->addChild(item);
|
||||
item->updateSize(m_list->getContentWidth(), BIG_VIEW);
|
||||
}
|
||||
m_list->m_contentLayer->updateLayout();
|
||||
auto listTopScrollPos = -m_list->m_contentLayer->getContentHeight() + m_list->getContentHeight();
|
||||
if (cache.scrollPosition > 0.f || cache.scrollPosition < listTopScrollPos) {
|
||||
cache.scrollPosition = listTopScrollPos;
|
||||
}
|
||||
m_list->m_contentLayer->setPositionY(cache.scrollPosition);
|
||||
m_currentList = &cache;
|
||||
}
|
||||
|
||||
void ModsLayer::gotoTab(std::string const& id) {
|
||||
for (auto tab : m_tabs) {
|
||||
auto selected = tab->getID() == id;
|
||||
tab->getNormalImage()->getChildByID("disabled-bg")->setVisible(!selected);
|
||||
tab->getNormalImage()->getChildByID("enabled-bg")->setVisible(selected);
|
||||
tab->setEnabled(!selected);
|
||||
}
|
||||
this->loadList(id);
|
||||
}
|
||||
|
||||
void ModsLayer::onTab(CCObject* sender) {
|
||||
this->gotoTab(static_cast<CCNode*>(sender)->getID());
|
||||
}
|
||||
|
||||
void ModsLayer::keyBackClicked() {
|
||||
this->onBack(nullptr);
|
||||
}
|
||||
|
||||
void ModsLayer::onBack(CCObject*) {
|
||||
CCDirector::get()->replaceScene(CCTransitionFade::create(.5f, MenuLayer::scene(false)));
|
||||
}
|
||||
|
||||
ModsLayer* ModsLayer::create() {
|
||||
auto ret = new ModsLayer();
|
||||
if (ret && ret->init()) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
CC_SAFE_DELETE(ret);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ModsLayer* ModsLayer::scene() {
|
||||
auto scene = CCScene::create();
|
||||
auto layer = ModsLayer::create();
|
||||
scene->addChild(layer);
|
||||
CCDirector::sharedDirector()->replaceScene(CCTransitionFade::create(.5f, scene));
|
||||
return layer;
|
||||
}
|
33
loader/src/ui/mods/ModsLayer.hpp
Normal file
33
loader/src/ui/mods/ModsLayer.hpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/ui/General.hpp>
|
||||
#include <Geode/ui/ScrollLayer.hpp>
|
||||
#include "ModItem.hpp"
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
struct ListCache {
|
||||
std::vector<Ref<BaseModItem>> items;
|
||||
float scrollPosition;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
bool init();
|
||||
|
||||
void keyBackClicked() override;
|
||||
void onTab(CCObject* sender);
|
||||
void gotoTab(std::string const& id);
|
||||
void loadList(std::string const& id, bool update = false);
|
||||
|
||||
public:
|
||||
static ModsLayer* create();
|
||||
static ModsLayer* scene();
|
||||
|
||||
void onBack(CCObject*);
|
||||
};
|
67
loader/src/ui/mods/SwelvyBG.cpp
Normal file
67
loader/src/ui/mods/SwelvyBG.cpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
#include "SwelvyBG.hpp"
|
||||
#include <random>
|
||||
|
||||
bool SwelvyBG::init() {
|
||||
if (!CCSpriteBatchNode::initWithTexture(CCTextureCache::get()->textureForKey("SwelveSheet.png"_spr), 20))
|
||||
return false;
|
||||
|
||||
auto winSize = CCDirector::get()->getWinSize();
|
||||
this->setContentSize(winSize);
|
||||
this->setAnchorPoint({ 0.f, 0.f });
|
||||
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<> sign(0, 1);
|
||||
std::uniform_real_distribution<float> dis(.05f, .15f);
|
||||
|
||||
float y = m_obContentSize.height + 5;
|
||||
for (auto layer : std::initializer_list<std::pair<ccColor3B, const char*>> {
|
||||
{ ccc3(244, 212, 142), "layer3.png"_spr },
|
||||
{ ccc3(245, 174, 125), "layer0.png"_spr },
|
||||
{ ccc3(236, 137, 124), "layer1.png"_spr },
|
||||
{ ccc3(213, 105, 133), "layer2.png"_spr },
|
||||
{ ccc3(173, 84, 146), "layer1.png"_spr },
|
||||
{ ccc3(113, 74, 154), "layer0.png"_spr },
|
||||
}) {
|
||||
float speed = dis(gen);
|
||||
if (sign(gen) == 0) {
|
||||
speed = -speed;
|
||||
}
|
||||
auto frame = CCSpriteFrameCache::get()->spriteFrameByName(layer.second);
|
||||
auto repeatCount = static_cast<int>(floor(winSize.width / frame->getRect().size.width)) + 2;
|
||||
for (int i = 0; i < repeatCount; i += 1) {
|
||||
auto sprite = CCSprite::createWithSpriteFrame(frame);
|
||||
sprite->setColor(layer.first);
|
||||
sprite->setAnchorPoint({ (speed < 0 ? 0.f : 1.f), 1 });
|
||||
sprite->setPosition({ (i + 1) * (sprite->getContentWidth() - 1), y });
|
||||
sprite->schedule(schedule_selector(SwelvyBG::updateSpritePosition));
|
||||
sprite->setUserData(std::bit_cast<void*>(speed));
|
||||
sprite->setTag(repeatCount);
|
||||
this->addChild(sprite);
|
||||
}
|
||||
y -= m_obContentSize.height / 6;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SwelvyBG::updateSpritePosition(float dt) {
|
||||
auto speed = std::bit_cast<float>(this->getUserData());
|
||||
this->setPositionX(this->getPositionX() - speed);
|
||||
if (speed > 0 && this->getPositionX() < 0.f) {
|
||||
this->setPositionX(this->getPositionX() + (this->getContentWidth() - 1) * this->getTag());
|
||||
}
|
||||
else if (speed < 0 && this->getPositionX() > this->getParent()->getContentWidth()) {
|
||||
this->setPositionX(this->getPositionX() - (this->getContentWidth() - 1) * this->getTag());
|
||||
}
|
||||
}
|
||||
|
||||
SwelvyBG* SwelvyBG::create() {
|
||||
auto ret = new SwelvyBG();
|
||||
if (ret && ret->init()) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
CC_SAFE_DELETE(ret);
|
||||
return nullptr;
|
||||
}
|
15
loader/src/ui/mods/SwelvyBG.hpp
Normal file
15
loader/src/ui/mods/SwelvyBG.hpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/ui/General.hpp>
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
class SwelvyBG : public CCSpriteBatchNode {
|
||||
protected:
|
||||
bool init();
|
||||
|
||||
void updateSpritePosition(float dt);
|
||||
|
||||
public:
|
||||
static SwelvyBG* create();
|
||||
};
|
|
@ -18,6 +18,29 @@ CCSprite* geode::createLayerBG() {
|
|||
return bg;
|
||||
}
|
||||
|
||||
void geode::addSideArt(CCNode* to, SideArt sides, bool useAnchorLayout) {
|
||||
if (sides & SideArt::BottomLeft) {
|
||||
auto spr = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png");
|
||||
to->addChildAtPosition(spr, Anchor::BottomLeft, ccp(35, 35), useAnchorLayout);
|
||||
}
|
||||
if (sides & SideArt::BottomRight) {
|
||||
auto spr = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png");
|
||||
spr->setFlipX(true);
|
||||
to->addChildAtPosition(spr, Anchor::BottomRight, ccp(-35, 35), useAnchorLayout);
|
||||
}
|
||||
if (sides & SideArt::TopLeft) {
|
||||
auto spr = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png");
|
||||
spr->setFlipY(true);
|
||||
to->addChildAtPosition(spr, Anchor::TopLeft, ccp(35, -35), useAnchorLayout);
|
||||
}
|
||||
if (sides & SideArt::TopRight) {
|
||||
auto spr = CCSprite::createWithSpriteFrameName("GJ_sideArt_001.png");
|
||||
spr->setFlipX(true);
|
||||
spr->setFlipY(true);
|
||||
to->addChildAtPosition(spr, Anchor::TopRight, ccp(-35, -35), useAnchorLayout);
|
||||
}
|
||||
}
|
||||
|
||||
void geode::addListBorders(CCNode* to, CCPoint const& center, CCSize const& size) {
|
||||
// if the size is 346.f, the top aligns perfectly by default :3
|
||||
if (size.width == 346.f) {
|
||||
|
|
|
@ -418,32 +418,16 @@ CCRect geode::cocos::calculateChildCoverage(CCNode* parent) {
|
|||
return calculateNodeCoverage(parent->getChildren());
|
||||
}
|
||||
|
||||
void geode::cocos::limitNodeSize(cocos2d::CCNode* spr, cocos2d::CCSize const& size, float def, float min) {
|
||||
spr->setScale(1.f);
|
||||
auto [cwidth, cheight] = spr->getContentSize();
|
||||
|
||||
float scale = def;
|
||||
if (size.height && size.height < cheight) {
|
||||
scale = size.height / cheight;
|
||||
}
|
||||
if (size.width && size.width < cwidth) {
|
||||
if (size.width / cwidth < scale) scale = size.width / cwidth;
|
||||
}
|
||||
if (def && def < scale) {
|
||||
scale = def;
|
||||
}
|
||||
if (min && scale < min) {
|
||||
scale = min;
|
||||
}
|
||||
spr->setScale(scale);
|
||||
void geode::cocos::limitNodeSize(CCNode* spr, CCSize const& size, float def, float min) {
|
||||
spr->setScale(clamp(std::min(size.height / spr->getContentHeight(), size.width / spr->getContentWidth()), min, def));
|
||||
}
|
||||
|
||||
bool geode::cocos::nodeIsVisible(cocos2d::CCNode* node) {
|
||||
bool geode::cocos::nodeIsVisible(CCNode* node) {
|
||||
if (!node->isVisible()) {
|
||||
return false;
|
||||
}
|
||||
if (node->getParent()) {
|
||||
return nodeIsVisible(node->getParent());
|
||||
if (auto parent = node->getParent()) {
|
||||
return nodeIsVisible(parent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue