geode/loader/include/Geode/ui/SelectList.hpp

117 lines
3.6 KiB
C++
Raw Normal View History

2022-09-02 05:22:59 -04:00
#pragma once
#include <Geode/binding/CCMenuItemSpriteExtra.hpp>
2022-09-02 05:22:59 -04:00
namespace geode {
2022-10-30 14:59:20 -04:00
template <class T>
2022-09-02 05:22:59 -04:00
T do_nothing(T t) {
return t;
}
2022-10-30 14:59:20 -04:00
template <class T = std::string, auto Stringify = do_nothing<std::string>>
2022-09-02 05:22:59 -04:00
class SelectList : public cocos2d::CCMenu {
protected:
std::vector<T> m_list;
size_t m_index = 0;
2023-02-08 10:25:07 -05:00
utils::MiniFunction<void(T const&, size_t)> m_onChange;
2022-09-02 05:22:59 -04:00
cocos2d::CCLabelBMFont* m_label;
CCMenuItemSpriteExtra* m_prevBtn;
CCMenuItemSpriteExtra* m_nextBtn;
2022-10-30 14:59:20 -04:00
2022-09-02 05:22:59 -04:00
bool init(
2023-02-08 10:25:07 -05:00
float width, std::vector<T> const& list, utils::MiniFunction<void(T const&, size_t)> onChange
2022-09-02 05:22:59 -04:00
) {
2022-10-30 14:59:20 -04:00
if (!cocos2d::CCMenu::init()) return false;
2022-09-02 05:22:59 -04:00
m_list = list;
m_onChange = onChange;
this->setContentSize({ width, 30.f });
auto prevSpr = cocos2d::CCSprite::createWithSpriteFrameName("navArrowBtn_001.png");
prevSpr->setFlipX(true);
prevSpr->setScale(.3f);
2022-10-30 14:59:20 -04:00
m_prevBtn =
CCMenuItemSpriteExtra::create(prevSpr, this, menu_selector(SelectList<T>::onPrev));
2022-09-02 05:22:59 -04:00
m_prevBtn->setPosition(-width / 2 + 10.f, 0.f);
this->addChild(m_prevBtn);
auto nextSpr = cocos2d::CCSprite::createWithSpriteFrameName("navArrowBtn_001.png");
nextSpr->setScale(.3f);
2022-10-30 14:59:20 -04:00
m_nextBtn =
CCMenuItemSpriteExtra::create(nextSpr, this, menu_selector(SelectList<T>::onNext));
2022-09-02 05:22:59 -04:00
m_nextBtn->setPosition(width / 2 - 10.f, 0.f);
this->addChild(m_nextBtn);
m_label = cocos2d::CCLabelBMFont::create("", "bigFont.fnt");
this->addChild(m_label);
this->updateLabel();
cocos2d::CCDirector::sharedDirector()->getTouchDispatcher()->incrementForcePrio(2);
this->registerWithTouchDispatcher();
return true;
}
void updateLabel() {
if (m_list.size()) {
m_label->setString(Stringify(m_list.at(m_index)).c_str());
m_prevBtn->setEnabled(true);
m_nextBtn->setEnabled(true);
2022-10-30 14:59:20 -04:00
}
else {
2022-09-02 05:22:59 -04:00
m_label->setString("-");
m_prevBtn->setEnabled(false);
m_nextBtn->setEnabled(false);
}
m_label->limitLabelWidth(m_obContentSize.width - 40.f, .6f, .1f);
}
void onPrev(CCObject* sender) {
if (m_index == 0) {
m_index = m_list.size() - 1;
2022-10-30 14:59:20 -04:00
}
else {
2022-09-02 05:22:59 -04:00
m_index--;
}
this->updateLabel();
m_onChange(m_list.at(m_index), m_index);
}
void onNext(CCObject* sender) {
if (m_index == m_list.size() - 1) {
m_index = 0;
2022-10-30 14:59:20 -04:00
}
else {
2022-09-02 05:22:59 -04:00
m_index++;
}
this->updateLabel();
m_onChange(m_list.at(m_index), m_index);
}
public:
static SelectList* create(
2023-02-08 10:25:07 -05:00
float width, std::vector<T> const& list, utils::MiniFunction<void(T const&, size_t)> onChange
2022-09-02 05:22:59 -04:00
) {
auto ret = new SelectList();
if (ret && ret->init(width, list, onChange)) {
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
void setItems(std::vector<T> const& list) {
m_index = 0;
m_list = list;
this->updateLabel();
}
};
}