mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-27 01:45:35 -05:00
move page number & list actions to ModsLayer rather than the list itself
This commit is contained in:
parent
fe4dbd96ed
commit
5109acf725
4 changed files with 257 additions and 80 deletions
|
@ -19,7 +19,27 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
|
||||||
// This is half the normal size for separators
|
// This is half the normal size for separators
|
||||||
->setGap(2.5f)
|
->setGap(2.5f)
|
||||||
);
|
);
|
||||||
this->addChildAtPosition(m_list, Anchor::Center, -m_list->getScaledContentSize() / 2);
|
this->addChildAtPosition(m_list, Anchor::Bottom, ccp(-m_list->getScaledContentSize().width / 2, 0));
|
||||||
|
|
||||||
|
m_searchMenu = CCMenu::create();
|
||||||
|
m_searchMenu->ignoreAnchorPointForPosition(false);
|
||||||
|
m_searchMenu->setContentSize({ size.width, 30 });
|
||||||
|
m_searchMenu->setAnchorPoint({ .5f, 1.f });
|
||||||
|
|
||||||
|
auto searchBG = CCLayerColor::create({ 83, 65, 109, 255 });
|
||||||
|
searchBG->setContentSize(m_searchMenu->getContentSize());
|
||||||
|
searchBG->ignoreAnchorPointForPosition(false);
|
||||||
|
m_searchMenu->addChildAtPosition(searchBG, Anchor::Center);
|
||||||
|
|
||||||
|
auto searchInput = TextInput::create(size.width, "Search Mods");
|
||||||
|
searchInput->setScale(.75f);
|
||||||
|
searchInput->setAnchorPoint({ 0, .5f });
|
||||||
|
searchInput->setTextAlign(TextInputAlign::Left);
|
||||||
|
m_searchMenu->addChildAtPosition(searchInput, Anchor::Left, ccp(10, 0));
|
||||||
|
|
||||||
|
// Do not add search menu; that's handled by onSearch
|
||||||
|
|
||||||
|
// Paging
|
||||||
|
|
||||||
auto pageLeftMenu = CCMenu::create();
|
auto pageLeftMenu = CCMenu::create();
|
||||||
pageLeftMenu->setContentWidth(30.f);
|
pageLeftMenu->setContentWidth(30.f);
|
||||||
|
@ -58,23 +78,7 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
|
||||||
);
|
);
|
||||||
this->addChildAtPosition(pageRightMenu, Anchor::Right, ccp(5, 0));
|
this->addChildAtPosition(pageRightMenu, Anchor::Right, ccp(5, 0));
|
||||||
|
|
||||||
auto pageLabelMenu = CCMenu::create();
|
// Status
|
||||||
pageLabelMenu->setContentWidth(200.f);
|
|
||||||
pageLabelMenu->setAnchorPoint({ .5f, 1.f });
|
|
||||||
|
|
||||||
// Default text is so that the button gets a proper hitbox, since it's
|
|
||||||
// based on sprite content size
|
|
||||||
m_pageLabel = CCLabelBMFont::create("Page XX/XX", "bigFont.fnt");
|
|
||||||
m_pageLabel->setAnchorPoint({ .5f, 1.f });
|
|
||||||
m_pageLabel->setScale(.45f);
|
|
||||||
|
|
||||||
m_pageLabelBtn = CCMenuItemSpriteExtra::create(
|
|
||||||
m_pageLabel, this, menu_selector(ModList::onGoToPage)
|
|
||||||
);
|
|
||||||
pageLabelMenu->addChild(m_pageLabelBtn);
|
|
||||||
|
|
||||||
pageLabelMenu->setLayout(RowLayout::create());
|
|
||||||
this->addChildAtPosition(pageLabelMenu, Anchor::Bottom, ccp(0, -5));
|
|
||||||
|
|
||||||
m_statusContainer = CCMenu::create();
|
m_statusContainer = CCMenu::create();
|
||||||
m_statusContainer->setScale(.5f);
|
m_statusContainer->setScale(.5f);
|
||||||
|
@ -140,15 +144,13 @@ void ModList::onPromise(typename ModListSource::PageLoadEvent* event) {
|
||||||
m_list->m_contentLayer->addChild(item);
|
m_list->m_contentLayer->addChild(item);
|
||||||
}
|
}
|
||||||
this->updateSize(m_bigSize);
|
this->updateSize(m_bigSize);
|
||||||
// Auto-grow the size of the list content
|
|
||||||
m_list->m_contentLayer->updateLayout();
|
|
||||||
|
|
||||||
// Scroll list to top
|
// Scroll list to top
|
||||||
auto listTopScrollPos = -m_list->m_contentLayer->getContentHeight() + m_list->getContentHeight();
|
auto listTopScrollPos = -m_list->m_contentLayer->getContentHeight() + m_list->getContentHeight();
|
||||||
m_list->m_contentLayer->setPositionY(listTopScrollPos);
|
m_list->m_contentLayer->setPositionY(listTopScrollPos);
|
||||||
|
|
||||||
// Update page UI
|
// Update page UI
|
||||||
this->updatePageUI();
|
this->updatePageNumber();
|
||||||
}
|
}
|
||||||
else if (auto progress = event->getProgress()) {
|
else if (auto progress = event->getProgress()) {
|
||||||
// todo: percentage in a loading bar
|
// todo: percentage in a loading bar
|
||||||
|
@ -163,8 +165,7 @@ void ModList::onPromise(typename ModListSource::PageLoadEvent* event) {
|
||||||
}
|
}
|
||||||
else if (auto rejected = event->getReject()) {
|
else if (auto rejected = event->getReject()) {
|
||||||
this->showStatus(ModListErrorStatus(), rejected->message, rejected->details);
|
this->showStatus(ModListErrorStatus(), rejected->message, rejected->details);
|
||||||
// todo: details
|
this->updatePageNumber();
|
||||||
this->updatePageUI(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->isFinally()) {
|
if (event->isFinally()) {
|
||||||
|
@ -173,23 +174,6 @@ void ModList::onPromise(typename ModListSource::PageLoadEvent* event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModList::updateSize(bool big) {
|
|
||||||
m_bigSize = big;
|
|
||||||
for (auto& node : CCArrayExt<CCNode*>(m_list->m_contentLayer->getChildren())) {
|
|
||||||
if (auto item = typeinfo_cast<BaseModItem*>(node)) {
|
|
||||||
item->updateSize(m_list->getContentWidth(), big);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModList::onGoToPage(CCObject*) {
|
|
||||||
auto popup = SetTextPopup::create("", "Page", 5, "Go to Page", "OK", true, 60.f);
|
|
||||||
popup->m_delegate = this;
|
|
||||||
popup->m_input->m_allowedChars = getCommonFilterAllowedChars(CommonFilter::Uint);
|
|
||||||
popup->setID("go-to-page"_spr);
|
|
||||||
popup->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModList::onPage(CCObject* sender) {
|
void ModList::onPage(CCObject* sender) {
|
||||||
// If no page count has been loaded yet, we can't do anything
|
// If no page count has been loaded yet, we can't do anything
|
||||||
if (!m_source->getPageCount()) return;
|
if (!m_source->getPageCount()) return;
|
||||||
|
@ -214,33 +198,76 @@ void ModList::onShowStatusDetails(CCObject*) {
|
||||||
m_statusContainer->updateLayout();
|
m_statusContainer->updateLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModList::updatePageUI(bool hide) {
|
void ModList::activateSearch(bool activate) {
|
||||||
|
// Add the menu or remove it depending on new state
|
||||||
|
if (activate) {
|
||||||
|
if (!m_searchMenu->getParent()) {
|
||||||
|
this->addChildAtPosition(m_searchMenu, Anchor::Top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_searchMenu->removeFromParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store old relative scroll position (ensuring no divide by zero happens)
|
||||||
|
auto oldPositionArea = m_list->m_contentLayer->getContentHeight() - m_list->getContentHeight();
|
||||||
|
auto oldPosition = oldPositionArea > 0.f ?
|
||||||
|
m_list->m_contentLayer->getPositionY() / oldPositionArea :
|
||||||
|
-1.f;
|
||||||
|
|
||||||
|
// Update list size to account for the search menu
|
||||||
|
// (giving a little bit of extra padding for it, the same size as gap)
|
||||||
|
m_list->setContentHeight(
|
||||||
|
activate ?
|
||||||
|
this->getContentHeight() - m_searchMenu->getContentHeight() - 2.5f :
|
||||||
|
this->getContentHeight()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Preserve relative scroll position
|
||||||
|
m_list->m_contentLayer->setPositionY((
|
||||||
|
m_list->m_contentLayer->getContentHeight() - m_list->getContentHeight()
|
||||||
|
) * oldPosition);
|
||||||
|
|
||||||
|
// ModList uses an anchor layout, so this puts the list in the right place
|
||||||
|
this->updateLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModList::updateSize(bool big) {
|
||||||
|
m_bigSize = big;
|
||||||
|
|
||||||
|
// Update all BaseModItems that are children of the list
|
||||||
|
// There may be non-BaseModItems there (like separators) so gotta be type-safe
|
||||||
|
for (auto& node : CCArrayExt<CCNode*>(m_list->m_contentLayer->getChildren())) {
|
||||||
|
if (auto item = typeinfo_cast<BaseModItem*>(node)) {
|
||||||
|
item->updateSize(m_list->getContentWidth(), big);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store old relative scroll position (ensuring no divide by zero happens)
|
||||||
|
auto oldPositionArea = m_list->m_contentLayer->getContentHeight() - m_list->getContentHeight();
|
||||||
|
auto oldPosition = oldPositionArea > 0.f ?
|
||||||
|
m_list->m_contentLayer->getPositionY() / oldPositionArea :
|
||||||
|
-1.f;
|
||||||
|
|
||||||
|
// Auto-grow the size of the list content
|
||||||
|
m_list->m_contentLayer->updateLayout();
|
||||||
|
|
||||||
|
// Preserve relative scroll position
|
||||||
|
m_list->m_contentLayer->setPositionY((
|
||||||
|
m_list->m_contentLayer->getContentHeight() - m_list->getContentHeight()
|
||||||
|
) * oldPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModList::updatePageNumber() {
|
||||||
auto pageCount = m_source->getPageCount();
|
auto pageCount = m_source->getPageCount();
|
||||||
|
|
||||||
// Hide if page count hasn't been loaded
|
// Hide if page count hasn't been loaded
|
||||||
if (!pageCount) {
|
m_pagePrevBtn->setVisible(pageCount && m_page > 0);
|
||||||
hide = true;
|
m_pageNextBtn->setVisible(pageCount && m_page < pageCount.value() - 1);
|
||||||
}
|
|
||||||
m_pagePrevBtn->setVisible(!hide && m_page > 0);
|
|
||||||
m_pageNextBtn->setVisible(!hide && m_page < pageCount.value() - 1);
|
|
||||||
m_pageLabelBtn->setVisible(!hide);
|
|
||||||
if (pageCount > 0u) {
|
|
||||||
auto fmt = fmt::format(
|
|
||||||
"Page {}/{} (Total {})",
|
|
||||||
m_page + 1, pageCount.value(), m_source->getItemCount().value()
|
|
||||||
);
|
|
||||||
m_pageLabel->setString(fmt.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModList::setTextPopupClosed(SetTextPopup* popup, gd::string value) {
|
// Notify container about page count update
|
||||||
if (popup->getID() == "go-to-page"_spr) {
|
if (m_pageUpdated) {
|
||||||
if (auto res = numFromString<size_t>(value)) {
|
m_pageUpdated();
|
||||||
size_t num = res.unwrap();
|
|
||||||
// The page indices are 0-based but people think in 1-based
|
|
||||||
if (num > 0) num -= 1;
|
|
||||||
this->gotoPage(num);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +287,7 @@ void ModList::gotoPage(size_t page, bool update) {
|
||||||
|
|
||||||
// Do initial eager update on page UI (to prevent user spamming arrows
|
// Do initial eager update on page UI (to prevent user spamming arrows
|
||||||
// to access invalid pages)
|
// to access invalid pages)
|
||||||
this->updatePageUI();
|
this->updatePageNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModList::showStatus(ModListStatus status, std::string const& message, std::optional<std::string> const& details) {
|
void ModList::showStatus(ModListStatus status, std::string const& message, std::optional<std::string> const& details) {
|
||||||
|
@ -292,6 +319,14 @@ void ModList::showStatus(ModListStatus status, std::string const& message, std::
|
||||||
m_statusContainer->updateLayout();
|
m_statusContainer->updateLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModList::onPageUpdated(ModListPageUpdated listener) {
|
||||||
|
m_pageUpdated = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ModList::getPage() const {
|
||||||
|
return m_page;
|
||||||
|
}
|
||||||
|
|
||||||
ModList* ModList::create(ModListSource* src, CCSize const& size) {
|
ModList* ModList::create(ModListSource* src, CCSize const& size) {
|
||||||
auto ret = new ModList();
|
auto ret = new ModList();
|
||||||
if (ret && ret->init(src, size)) {
|
if (ret && ret->init(src, size)) {
|
||||||
|
|
|
@ -15,7 +15,9 @@ struct ModListProgressStatus {
|
||||||
};
|
};
|
||||||
using ModListStatus = std::variant<ModListErrorStatus, ModListUnkProgressStatus, ModListProgressStatus>;
|
using ModListStatus = std::variant<ModListErrorStatus, ModListUnkProgressStatus, ModListProgressStatus>;
|
||||||
|
|
||||||
class ModList : public CCNode, public SetTextPopupDelegate {
|
using ModListPageUpdated = MiniFunction<void()>;
|
||||||
|
|
||||||
|
class ModList : public CCNode {
|
||||||
protected:
|
protected:
|
||||||
Ref<ModListSource> m_source;
|
Ref<ModListSource> m_source;
|
||||||
size_t m_page = 0;
|
size_t m_page = 0;
|
||||||
|
@ -29,26 +31,28 @@ protected:
|
||||||
ModListSource::PageLoadEventListener m_listener;
|
ModListSource::PageLoadEventListener m_listener;
|
||||||
CCMenuItemSpriteExtra* m_pagePrevBtn;
|
CCMenuItemSpriteExtra* m_pagePrevBtn;
|
||||||
CCMenuItemSpriteExtra* m_pageNextBtn;
|
CCMenuItemSpriteExtra* m_pageNextBtn;
|
||||||
CCMenuItemSpriteExtra* m_pageLabelBtn;
|
Ref<CCMenu> m_searchMenu;
|
||||||
CCLabelBMFont* m_pageLabel;
|
ModListPageUpdated m_pageUpdated = nullptr;
|
||||||
bool m_bigSize = false;
|
bool m_bigSize = false;
|
||||||
|
|
||||||
bool init(ModListSource* src, CCSize const& size);
|
bool init(ModListSource* src, CCSize const& size);
|
||||||
|
|
||||||
void onPromise(ModListSource::PageLoadEvent* event);
|
void onPromise(ModListSource::PageLoadEvent* event);
|
||||||
void onPage(CCObject*);
|
void onPage(CCObject*);
|
||||||
void onGoToPage(CCObject*);
|
|
||||||
void onShowStatusDetails(CCObject*);
|
void onShowStatusDetails(CCObject*);
|
||||||
|
|
||||||
void setTextPopupClosed(SetTextPopup*, gd::string value) override;
|
|
||||||
|
|
||||||
void updatePageUI(bool hide = false);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ModList* create(ModListSource* src, CCSize const& size);
|
static ModList* create(ModListSource* src, CCSize const& size);
|
||||||
|
|
||||||
|
// poor man's delegate
|
||||||
|
void onPageUpdated(ModListPageUpdated listener);
|
||||||
|
size_t getPage() const;
|
||||||
|
|
||||||
void reloadPage();
|
void reloadPage();
|
||||||
void gotoPage(size_t page, bool update = false);
|
void gotoPage(size_t page, bool update = false);
|
||||||
void showStatus(ModListStatus status, std::string const& message, std::optional<std::string> const& details = std::nullopt);
|
void showStatus(ModListStatus status, std::string const& message, std::optional<std::string> const& details = std::nullopt);
|
||||||
|
|
||||||
|
void updatePageNumber();
|
||||||
void updateSize(bool big);
|
void updateSize(bool big);
|
||||||
|
void activateSearch(bool activate);
|
||||||
};
|
};
|
||||||
|
|
|
@ -129,6 +129,56 @@ bool ModsLayer::init() {
|
||||||
mainTabs->setLayout(RowLayout::create());
|
mainTabs->setLayout(RowLayout::create());
|
||||||
this->addChild(mainTabs);
|
this->addChild(mainTabs);
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
|
||||||
|
auto listActionsMenu = CCMenu::create();
|
||||||
|
listActionsMenu->setContentHeight(100);
|
||||||
|
listActionsMenu->setAnchorPoint({ 1, 0 });
|
||||||
|
listActionsMenu->setScale(.65f);
|
||||||
|
|
||||||
|
m_bigSizeBtnSpr = CCSprite::create("GE_button_05.png"_spr);
|
||||||
|
auto bigSizeBtnTop = CCSprite::createWithSpriteFrameName("GJ_smallModeIcon_001.png");
|
||||||
|
limitNodeSize(bigSizeBtnTop, m_bigSizeBtnSpr->getContentSize() * .65f, 2.f, .1f);
|
||||||
|
m_bigSizeBtnSpr->addChildAtPosition(bigSizeBtnTop, Anchor::Center);
|
||||||
|
auto bigSizeBtn = CCMenuItemSpriteExtra::create(
|
||||||
|
m_bigSizeBtnSpr, this, menu_selector(ModsLayer::onBigView)
|
||||||
|
);
|
||||||
|
listActionsMenu->addChild(bigSizeBtn);
|
||||||
|
|
||||||
|
m_searchBtnSpr = CCSprite::create("GE_button_05.png"_spr);
|
||||||
|
auto searchBtnTop = CCSprite::createWithSpriteFrameName("search.png"_spr);
|
||||||
|
limitNodeSize(searchBtnTop, m_searchBtnSpr->getContentSize() * .65f, 2.f, .1f);
|
||||||
|
m_searchBtnSpr->addChildAtPosition(searchBtnTop, Anchor::Center);
|
||||||
|
auto searchBtn = CCMenuItemSpriteExtra::create(
|
||||||
|
m_searchBtnSpr, this, menu_selector(ModsLayer::onSearch)
|
||||||
|
);
|
||||||
|
listActionsMenu->addChild(searchBtn);
|
||||||
|
|
||||||
|
listActionsMenu->setLayout(ColumnLayout::create());
|
||||||
|
m_frame->addChildAtPosition(listActionsMenu, Anchor::Left, ccp(-5, 25));
|
||||||
|
|
||||||
|
m_pageMenu = CCMenu::create();
|
||||||
|
m_pageMenu->setContentWidth(200.f);
|
||||||
|
m_pageMenu->setAnchorPoint({ 1.f, 1.f });
|
||||||
|
m_pageMenu->setScale(.65f);
|
||||||
|
|
||||||
|
m_pageLabel = CCLabelBMFont::create("", "goldFont.fnt");
|
||||||
|
m_pageLabel->setAnchorPoint({ .5f, 1.f });
|
||||||
|
m_pageMenu->addChild(m_pageLabel);
|
||||||
|
|
||||||
|
m_goToPageBtn = CCMenuItemSpriteExtra::create(
|
||||||
|
CCSprite::createWithSpriteFrameName("gj_navDotBtn_on_001.png"),
|
||||||
|
this, menu_selector(ModsLayer::onGoToPage)
|
||||||
|
);
|
||||||
|
m_pageMenu->addChild(m_goToPageBtn);
|
||||||
|
|
||||||
|
m_pageMenu->setLayout(
|
||||||
|
RowLayout::create()
|
||||||
|
->setAxisReverse(true)
|
||||||
|
->setAxisAlignment(AxisAlignment::End)
|
||||||
|
);
|
||||||
|
this->addChildAtPosition(m_pageMenu, Anchor::TopRight, ccp(-5, -5), false);
|
||||||
|
|
||||||
this->gotoTab(ModListSourceType::Installed);
|
this->gotoTab(ModListSourceType::Installed);
|
||||||
|
|
||||||
this->setKeypadEnabled(true);
|
this->setKeypadEnabled(true);
|
||||||
|
@ -157,7 +207,8 @@ void ModsLayer::gotoTab(ModListSourceType type) {
|
||||||
|
|
||||||
// Lazily create new list and add it to UI
|
// Lazily create new list and add it to UI
|
||||||
if (!m_lists.contains(src)) {
|
if (!m_lists.contains(src)) {
|
||||||
auto list = ModList::create(src, m_frame->getContentSize() - ccp(24, 0));
|
auto list = ModList::create(src, m_frame->getContentSize() - ccp(30, 0));
|
||||||
|
list->onPageUpdated(std::bind(&ModsLayer::updatePageNumber, this));
|
||||||
list->setPosition(m_frame->getPosition());
|
list->setPosition(m_frame->getPosition());
|
||||||
this->addChild(list);
|
this->addChild(list);
|
||||||
m_lists.emplace(src, list);
|
m_lists.emplace(src, list);
|
||||||
|
@ -166,16 +217,55 @@ void ModsLayer::gotoTab(ModListSourceType type) {
|
||||||
else {
|
else {
|
||||||
this->addChild(m_lists.at(src));
|
this->addChild(m_lists.at(src));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void ModsLayer::onTab(CCObject* sender) {
|
// Update the state of the current list
|
||||||
this->gotoTab(static_cast<ModListSourceType>(sender->getTag()));
|
m_lists.at(m_currentSource)->updateSize(m_bigView);
|
||||||
|
m_lists.at(m_currentSource)->activateSearch(m_showSearch);
|
||||||
|
m_lists.at(m_currentSource)->updatePageNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModsLayer::keyBackClicked() {
|
void ModsLayer::keyBackClicked() {
|
||||||
this->onBack(nullptr);
|
this->onBack(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModsLayer::setTextPopupClosed(SetTextPopup* popup, gd::string value) {
|
||||||
|
if (popup->getID() == "go-to-page"_spr) {
|
||||||
|
if (auto res = numFromString<size_t>(value)) {
|
||||||
|
size_t num = res.unwrap();
|
||||||
|
// The page indices are 0-based but people think in 1-based
|
||||||
|
if (num > 0) num -= 1;
|
||||||
|
if (m_currentSource) {
|
||||||
|
m_lists.at(m_currentSource)->gotoPage(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModsLayer::updatePageNumber() {
|
||||||
|
// Show current page number if the current source has total page count loaded
|
||||||
|
if (m_currentSource && m_currentSource->getPageCount()) {
|
||||||
|
auto page = m_lists.at(m_currentSource)->getPage() + 1;
|
||||||
|
auto count = m_currentSource->getPageCount().value();
|
||||||
|
auto total = m_currentSource->getItemCount().value();
|
||||||
|
|
||||||
|
// Set the page count string
|
||||||
|
auto fmt = fmt::format("Page {}/{} (Total {})", page, count, total);
|
||||||
|
m_pageLabel->setString(fmt.c_str());
|
||||||
|
|
||||||
|
// Make page menu visible
|
||||||
|
m_pageMenu->setVisible(true);
|
||||||
|
m_pageMenu->updateLayout();
|
||||||
|
}
|
||||||
|
// Hide page menu otherwise
|
||||||
|
else {
|
||||||
|
m_pageMenu->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModsLayer::onTab(CCObject* sender) {
|
||||||
|
this->gotoTab(static_cast<ModListSourceType>(sender->getTag()));
|
||||||
|
}
|
||||||
|
|
||||||
void ModsLayer::onRefreshList(CCObject*) {
|
void ModsLayer::onRefreshList(CCObject*) {
|
||||||
m_lists.at(m_currentSource)->reloadPage();
|
m_lists.at(m_currentSource)->reloadPage();
|
||||||
}
|
}
|
||||||
|
@ -184,6 +274,41 @@ void ModsLayer::onBack(CCObject*) {
|
||||||
CCDirector::get()->replaceScene(CCTransitionFade::create(.5f, MenuLayer::scene(false)));
|
CCDirector::get()->replaceScene(CCTransitionFade::create(.5f, MenuLayer::scene(false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModsLayer::onGoToPage(CCObject*) {
|
||||||
|
auto popup = SetTextPopup::create("", "Page", 5, "Go to Page", "OK", true, 60.f);
|
||||||
|
popup->m_delegate = this;
|
||||||
|
popup->m_input->m_allowedChars = getCommonFilterAllowedChars(CommonFilter::Uint);
|
||||||
|
popup->setID("go-to-page"_spr);
|
||||||
|
popup->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModsLayer::onBigView(CCObject*) {
|
||||||
|
m_bigView = !m_bigView;
|
||||||
|
|
||||||
|
// Make sure to avoid a crash
|
||||||
|
if (m_currentSource) {
|
||||||
|
m_lists.at(m_currentSource)->updateSize(m_bigView);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the background on the size button
|
||||||
|
m_bigSizeBtnSpr->setTexture(CCTextureCache::get()->addImage(
|
||||||
|
(m_bigView ? "GJ_button_02.png" : "GE_button_05.png"_spr), true
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModsLayer::onSearch(CCObject*) {
|
||||||
|
m_showSearch = !m_showSearch;
|
||||||
|
|
||||||
|
// Make sure to avoid a crash
|
||||||
|
if (m_currentSource) {
|
||||||
|
m_lists.at(m_currentSource)->activateSearch(m_showSearch);
|
||||||
|
}
|
||||||
|
// Update the background on the search button
|
||||||
|
m_searchBtnSpr->setTexture(CCTextureCache::get()->addImage(
|
||||||
|
(m_showSearch ? "GJ_button_02.png" : "GE_button_05.png"_spr), true
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
ModsLayer* ModsLayer::create() {
|
ModsLayer* ModsLayer::create() {
|
||||||
auto ret = new ModsLayer();
|
auto ret = new ModsLayer();
|
||||||
if (ret && ret->init()) {
|
if (ret && ret->init()) {
|
||||||
|
|
|
@ -9,24 +9,37 @@
|
||||||
|
|
||||||
using namespace geode::prelude;
|
using namespace geode::prelude;
|
||||||
|
|
||||||
class ModsLayer : public CCLayer {
|
class ModsLayer : public CCLayer, public SetTextPopupDelegate {
|
||||||
protected:
|
protected:
|
||||||
CCNode* m_frame;
|
CCNode* m_frame;
|
||||||
std::vector<CCMenuItemSpriteExtra*> m_tabs;
|
std::vector<CCMenuItemSpriteExtra*> m_tabs;
|
||||||
ModListSource* m_currentSource = nullptr;
|
ModListSource* m_currentSource = nullptr;
|
||||||
std::unordered_map<ModListSource*, Ref<ModList>> m_lists;
|
std::unordered_map<ModListSource*, Ref<ModList>> m_lists;
|
||||||
|
CCSprite* m_bigSizeBtnSpr;
|
||||||
|
CCSprite* m_searchBtnSpr;
|
||||||
|
CCMenu* m_pageMenu;
|
||||||
|
CCLabelBMFont* m_pageLabel;
|
||||||
|
CCMenuItemSpriteExtra* m_goToPageBtn;
|
||||||
|
bool m_showSearch = false;
|
||||||
|
bool m_bigView = false;
|
||||||
|
|
||||||
bool init();
|
bool init();
|
||||||
|
|
||||||
void keyBackClicked() override;
|
void keyBackClicked() override;
|
||||||
|
void setTextPopupClosed(SetTextPopup*, gd::string value) override;
|
||||||
|
|
||||||
void onTab(CCObject* sender);
|
void onTab(CCObject* sender);
|
||||||
|
void onBigView(CCObject*);
|
||||||
|
void onSearch(CCObject*);
|
||||||
|
void onGoToPage(CCObject*);
|
||||||
|
void onBack(CCObject*);
|
||||||
|
void onRefreshList(CCObject*);
|
||||||
|
|
||||||
|
void updatePageNumber();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ModsLayer* create();
|
static ModsLayer* create();
|
||||||
static ModsLayer* scene();
|
static ModsLayer* scene();
|
||||||
|
|
||||||
void onBack(CCObject*);
|
|
||||||
void onRefreshList(CCObject*);
|
|
||||||
|
|
||||||
void gotoTab(ModListSourceType type);
|
void gotoTab(ModListSourceType type);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue