mirror of
https://github.com/geode-sdk/geode.git
synced 2025-04-10 03:55:43 -04:00
initial mod popup work! :)
This commit is contained in:
parent
65f6158774
commit
6414737b0c
6 changed files with 183 additions and 40 deletions
loader
resources/images
src/ui/mods
BIN
loader/resources/images/GE_square01.png
Normal file
BIN
loader/resources/images/GE_square01.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 4.2 KiB |
|
@ -48,6 +48,63 @@ GeodeSquareSprite* GeodeSquareSprite::createWithSpriteFrameName(const char* top,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
ButtonSprite* createGeodeButton(std::string const& text) {
|
||||
return ButtonSprite::create(text.c_str(), "bigFont.fnt", "GE_button_05.png"_spr, .8f);
|
||||
ButtonSprite* createGeodeButton(std::string const& text, std::string const& bg) {
|
||||
return ButtonSprite::create(text.c_str(), "bigFont.fnt", bg.c_str(), .8f);
|
||||
}
|
||||
|
||||
bool GeodeTabSprite::init(const char* iconFrame, const char* text, float width) {
|
||||
if (!CCNode::init())
|
||||
return false;
|
||||
|
||||
const CCSize itemSize { width, 35 };
|
||||
const CCSize iconSize { 18, 18 };
|
||||
|
||||
this->setContentSize(itemSize);
|
||||
this->setAnchorPoint({ .5f, .5f });
|
||||
|
||||
m_deselectedBG = CCScale9Sprite::createWithSpriteFrameName("tab-bg.png"_spr);
|
||||
m_deselectedBG->setScale(.8f);
|
||||
m_deselectedBG->setContentSize(itemSize / .8f);
|
||||
m_deselectedBG->setColor({ 26, 24, 29 });
|
||||
this->addChildAtPosition(m_deselectedBG, Anchor::Center);
|
||||
|
||||
m_selectedBG = CCScale9Sprite::createWithSpriteFrameName("tab-bg.png"_spr);
|
||||
m_selectedBG->setScale(.8f);
|
||||
m_selectedBG->setContentSize(itemSize / .8f);
|
||||
m_selectedBG->setColor({ 168, 147, 185 });
|
||||
this->addChildAtPosition(m_selectedBG, Anchor::Center);
|
||||
|
||||
m_icon = CCSprite::createWithSpriteFrameName(iconFrame);
|
||||
limitNodeSize(m_icon, iconSize, 3.f, .1f);
|
||||
this->addChildAtPosition(m_icon, Anchor::Left, ccp(16, 0), false);
|
||||
|
||||
m_label = CCLabelBMFont::create(text, "bigFont.fnt");
|
||||
m_label->limitLabelWidth(this->getContentWidth() - 34, .55f, .1f);
|
||||
m_label->setAnchorPoint({ .0f, .5f });
|
||||
this->addChildAtPosition(m_label, Anchor::Left, ccp(28, 0), false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GeodeTabSprite* GeodeTabSprite::create(const char* iconFrame, const char* text, float width) {
|
||||
auto ret = new GeodeTabSprite();
|
||||
if (ret && ret->init(iconFrame, text, width)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
CC_SAFE_DELETE(ret);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GeodeTabSprite::select(bool selected) {
|
||||
m_deselectedBG->setVisible(!selected);
|
||||
m_selectedBG->setVisible(selected);
|
||||
}
|
||||
|
||||
void GeodeTabSprite::disable(bool disabled) {
|
||||
auto color = disabled ? ccc3(95, 95, 95) : ccc3(255, 255, 255);
|
||||
m_deselectedBG->setColor(color);
|
||||
m_selectedBG->setColor(color);
|
||||
m_icon->setColor(color);
|
||||
m_label->setColor(color);
|
||||
}
|
||||
|
|
|
@ -18,12 +18,20 @@ public:
|
|||
static GeodeSquareSprite* createWithSpriteFrameName(const char* top, bool* state = nullptr);
|
||||
};
|
||||
|
||||
ButtonSprite* createGeodeButton(std::string const& text);
|
||||
ButtonSprite* createGeodeButton(std::string const& text, std::string const& bg = "GE_button_05.png"_spr);
|
||||
|
||||
class GeodeButtonSprite : public ButtonSprite {
|
||||
class GeodeTabSprite : public CCNode {
|
||||
protected:
|
||||
bool init(std::string const& text);
|
||||
CCScale9Sprite* m_deselectedBG;
|
||||
CCScale9Sprite* m_selectedBG;
|
||||
CCSprite* m_icon;
|
||||
CCLabelBMFont* m_label;
|
||||
|
||||
bool init(const char* iconFrame, const char* text, float width);
|
||||
|
||||
public:
|
||||
static GeodeButtonSprite* create(std::string const& text);
|
||||
static GeodeTabSprite* create(const char* iconFrame, const char* text, float width);
|
||||
|
||||
void select(bool selected);
|
||||
void disable(bool disabled);
|
||||
};
|
||||
|
|
|
@ -1,15 +1,109 @@
|
|||
#include "ModPopup.hpp"
|
||||
#include <Geode/ui/MDTextArea.hpp>
|
||||
#include "GeodeStyle.hpp"
|
||||
|
||||
std::optional<std::string> getModMarkdownData(ModSource const& src, ModMarkdownData data) {
|
||||
switch (data) {
|
||||
default: return std::nullopt;
|
||||
case ModMarkdownData::Details: return src.getMetadata().getDetails().value_or("No description provided");
|
||||
case ModMarkdownData::Changelog: return src.getMetadata().getChangelog();
|
||||
}
|
||||
}
|
||||
|
||||
bool ModPopup::setup(ModSource&& src) {
|
||||
m_source = std::move(src);
|
||||
m_noElasticity = true;
|
||||
|
||||
const CCSize titleSize { 230, 50 };
|
||||
const float titlePad = 10;
|
||||
|
||||
auto titleContainer = CCNode::create();
|
||||
titleContainer->setContentSize(titleSize);
|
||||
titleContainer->setAnchorPoint({ 0, 1 });
|
||||
titleContainer->setScale(.6f);
|
||||
|
||||
auto logo = m_source.createModLogo();
|
||||
limitNodeSize(logo, { titleSize.height, titleSize.height }, 5.f, .1f);
|
||||
titleContainer->addChildAtPosition(logo, Anchor::Left, ccp(titleSize.height / 2, 0));
|
||||
|
||||
auto title = CCLabelBMFont::create(m_source.getMetadata().getName().c_str(), "bigFont.fnt");
|
||||
title->limitLabelWidth(titleSize.width - titleSize.height - titlePad, 1.f, .1f);
|
||||
title->setAnchorPoint({ .0f, .5f });
|
||||
titleContainer->addChildAtPosition(title, Anchor::TopLeft, ccp(titleSize.height + titlePad, -titleSize.height * .25f));
|
||||
|
||||
auto by = "By " + ModMetadata::formatDeveloperDisplayString(m_source.getMetadata().getDevelopers());
|
||||
auto dev = CCLabelBMFont::create(by.c_str(), "goldFont.fnt");
|
||||
dev->limitLabelWidth(titleSize.width - titleSize.height - titlePad, .75f, .1f);
|
||||
dev->setAnchorPoint({ .0f, .5f });
|
||||
titleContainer->addChildAtPosition(dev, Anchor::BottomLeft, ccp(titleSize.height + titlePad, titleSize.height * .25f));
|
||||
|
||||
m_mainLayer->addChildAtPosition(titleContainer, Anchor::TopLeft, ccp(20, -35));
|
||||
|
||||
auto statsBG = CCScale9Sprite::create("square02b_001.png");
|
||||
statsBG->setColor({ 0, 0, 0 });
|
||||
statsBG->setOpacity(90);
|
||||
statsBG->setAnchorPoint({ 0, 0 });
|
||||
statsBG->setContentSize({ 120, 130 });
|
||||
m_mainLayer->addChildAtPosition(statsBG, Anchor::BottomLeft, ccp(30, 30));
|
||||
|
||||
auto tabsSize = CCSize { 250, 250 };
|
||||
auto tabsContainer = CCNode::create();
|
||||
tabsContainer->setContentSize(tabsSize);
|
||||
tabsContainer->setAnchorPoint({ 1.f, .5f });
|
||||
|
||||
m_mdArea = MDTextArea::create("", (tabsSize - ccp(0, 30)));
|
||||
m_mdArea->setAnchorPoint({ .5f, .0f });
|
||||
tabsContainer->addChildAtPosition(m_mdArea, Anchor::Bottom);
|
||||
|
||||
m_tabsMenu = CCMenu::create();
|
||||
m_tabsMenu->ignoreAnchorPointForPosition(false);
|
||||
m_tabsMenu->setScale(.65f);
|
||||
m_tabsMenu->setContentWidth(m_mdArea->getScaledContentSize().width / m_tabsMenu->getScale());
|
||||
m_tabsMenu->setAnchorPoint({ .5f, 1.f });
|
||||
|
||||
for (auto mdTab : std::initializer_list<std::tuple<const char*, const char*, ModMarkdownData>> {
|
||||
{ "GJ_chatBtn_02_001.png", "Description", ModMarkdownData::Details },
|
||||
{ "changelog.png"_spr, "Changelog", ModMarkdownData::Changelog },
|
||||
}) {
|
||||
auto btn = CCMenuItemSpriteExtra::create(
|
||||
GeodeTabSprite::create(std::get<0>(mdTab), std::get<1>(mdTab), 140),
|
||||
this, menu_selector(ModPopup::onMDTab)
|
||||
);
|
||||
if (auto data = getModMarkdownData(m_source, std::get<2>(mdTab))) {
|
||||
btn->setTag(static_cast<int>(std::get<2>(mdTab)));
|
||||
}
|
||||
else {
|
||||
btn->setEnabled(false);
|
||||
static_cast<GeodeTabSprite*>(btn->getNormalImage())->disable(true);
|
||||
}
|
||||
m_tabsMenu->addChild(btn);
|
||||
}
|
||||
|
||||
m_tabsMenu->setLayout(RowLayout::create());
|
||||
tabsContainer->addChildAtPosition(m_tabsMenu, Anchor::Top);
|
||||
|
||||
m_mainLayer->addChildAtPosition(tabsContainer, Anchor::Right, ccp(-20, 0));
|
||||
|
||||
// Select details tab
|
||||
this->onMDTab(m_tabsMenu->getChildren()->firstObject());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModPopup::onMDTab(CCObject* sender) {
|
||||
if (auto data = getModMarkdownData(m_source, static_cast<ModMarkdownData>(sender->getTag()))) {
|
||||
m_mdArea->setString(data.value().c_str());
|
||||
}
|
||||
|
||||
// Highlight selected tab
|
||||
for (auto tab : CCArrayExt<CCMenuItemSpriteExtra*>(m_tabsMenu->getChildren())) {
|
||||
static_cast<GeodeTabSprite*>(tab->getNormalImage())->select(tab->getTag() == sender->getTag());
|
||||
}
|
||||
}
|
||||
|
||||
ModPopup* ModPopup::create(ModSource&& src) {
|
||||
auto ret = new ModPopup();
|
||||
if (ret && ret->init(358.f, 250.f, std::move(src))) {
|
||||
if (ret && ret->initAnchored(440, 280, std::move(src), "GE_square01.png"_spr)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/ui/Popup.hpp>
|
||||
#include <Geode/ui/MDTextArea.hpp>
|
||||
#include "ModSource.hpp"
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
enum class ModMarkdownData {
|
||||
Details,
|
||||
Changelog,
|
||||
};
|
||||
|
||||
std::optional<std::string> getModMarkdownData(ModSource const& src, ModMarkdownData data);
|
||||
|
||||
class ModPopup : public Popup<ModSource&&> {
|
||||
protected:
|
||||
ModSource m_source;
|
||||
MDTextArea* m_mdArea;
|
||||
CCMenu* m_tabsMenu;
|
||||
|
||||
bool setup(ModSource&& src) override;
|
||||
|
||||
void onMDTab(CCObject* sender);
|
||||
|
||||
public:
|
||||
static ModPopup* create(ModSource&& src);
|
||||
};
|
||||
|
|
|
@ -92,37 +92,10 @@ bool ModsLayer::init() {
|
|||
{ "GJ_sTrendingIcon_001.png", "Trending", ModListSourceType::Trending },
|
||||
{ "gj_folderBtn_001.png", "Mod Packs", ModListSourceType::ModPacks },
|
||||
}) {
|
||||
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->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->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(16, 0), false);
|
||||
|
||||
auto title = CCLabelBMFont::create(std::get<1>(item), "bigFont.fnt");
|
||||
title->limitLabelWidth(spr->getContentWidth() - 34, .55f, .1f);
|
||||
title->setAnchorPoint({ .0f, .5f });
|
||||
spr->addChildAtPosition(title, Anchor::Left, ccp(28, 0), false);
|
||||
|
||||
auto btn = CCMenuItemSpriteExtra::create(spr, this, menu_selector(ModsLayer::onTab));
|
||||
auto btn = CCMenuItemSpriteExtra::create(
|
||||
GeodeTabSprite::create(std::get<0>(item), std::get<1>(item), 100),
|
||||
this, menu_selector(ModsLayer::onTab)
|
||||
);
|
||||
btn->setTag(static_cast<int>(std::get<2>(item)));
|
||||
mainTabs->addChild(btn);
|
||||
m_tabs.push_back(btn);
|
||||
|
@ -203,8 +176,7 @@ void ModsLayer::gotoTab(ModListSourceType type) {
|
|||
// Update selected tab
|
||||
for (auto tab : m_tabs) {
|
||||
auto selected = tab->getTag() == static_cast<int>(type);
|
||||
tab->getNormalImage()->getChildByID("disabled-bg")->setVisible(!selected);
|
||||
tab->getNormalImage()->getChildByID("enabled-bg")->setVisible(selected);
|
||||
static_cast<GeodeTabSprite*>(tab->getNormalImage())->select(selected);
|
||||
tab->setEnabled(!selected);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue