#pragma once #include namespace geode { template T do_nothing(T t) { return t; } template > class SelectList : public cocos2d::CCMenu { protected: std::vector m_list; size_t m_index = 0; std::function m_onChange; cocos2d::CCLabelBMFont* m_label; CCMenuItemSpriteExtra* m_prevBtn; CCMenuItemSpriteExtra* m_nextBtn; bool init( float width, std::vector const& list, std::function onChange ) { if (!cocos2d::CCMenu::init()) return false; 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); m_prevBtn = CCMenuItemSpriteExtra::create(prevSpr, this, menu_selector(SelectList::onPrev)); m_prevBtn->setPosition(-width / 2 + 10.f, 0.f); this->addChild(m_prevBtn); auto nextSpr = cocos2d::CCSprite::createWithSpriteFrameName("navArrowBtn_001.png"); nextSpr->setScale(.3f); m_nextBtn = CCMenuItemSpriteExtra::create(nextSpr, this, menu_selector(SelectList::onNext)); 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(); this->setTouchEnabled(true); 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); } else { 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; } else { 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; } else { m_index++; } this->updateLabel(); m_onChange(m_list.at(m_index), m_index); } public: static SelectList* create( float width, std::vector const& list, std::function onChange ) { auto ret = new SelectList(); if (ret->init(width, list, onChange)) { ret->autorelease(); return ret; } delete ret; return nullptr; } void setItems(std::vector const& list) { m_index = 0; m_list = list; this->updateLabel(); } }; }