打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
cocos2d-x 2.0.4 封装组合框 ComboBox

cocos2d-x 2.0.4尚未包含组合框组件,在很多需要选择时间、道具等应用场合非常不方便,故而自己封装了一个。基本上跟android标准组件的组合框功能和体验都一模一样了,而且功能更加强大, 完全可以自定义组合框的按钮图片,字体大小,背景图片,按钮高亮图片,以及选择列表的背景等。大小可根据设置的字体大小随意收缩,非常方便。

先说说使用方法:

在CCLayer中要使用这个组合框,简单的代码如下:

    ComboBox* comboBox = ComboBox::create("1985", "control/buttonBackground.png", "control/cbobtn_normal.png", "control/cbobtn_hightlight.png", "control/cellbackground.png",  60, 3);        comboBox->setComboBoxDataFromContinuousInt(1900,2100); // 设置内容为1900-2100的所有数字,需要设置字符串之类的可以参考其他设置内容的接口        comboBox->setPosition(winSize.width/2, winSize.height/2);        addChild(comboBox);

create()函数说明:

ComboBox::create(const char* text, const char* bgImg, const char* btnImg, const char* hightLightBtnImg, const char* cellBackGround, int fontSize, float borderPix, const char* font="Marker Felt");

text => 默认显示的文本内容

bgImg=> 组合框背景图片

btnImg=>组合框右边按钮普通状态下的图片

hightLightBtnImg =>组合框右边按钮按下状态下的图片

cellBackGround => 选择列表单元格的背景图片

fontSize => 字体大小,决定组合框的大小

borderPix => 图片边界尺寸,因为图片需要随着组合框缩放,故需要边界尺寸,这个具体可以看看CCScale9Sprite的原理,相当于rectInsets的内容

font => 字体样式

 

附上截图:

组合框样子:                                                                                        点击按钮弹出选择列表

     

 

附上源代码:

注意,源代码中,MyTableView的实现在我的另外一篇文章中,主要就是修复了CCTableView中不能点击的bug,文章见这里:cocos2d-x 2.0.4 CCTableView 点击无响应问题.

ComboBox.h

#ifndef __COMBOBOX_H__#define __COMBOBOX_H__#include "cocos2d.h"#include "cocos-ext.h"#include "MyTableView.h"#include <vector>USING_NS_CC;USING_NS_CC_EXT;typedef std::vector<std::string> ComboBoxDataList;class ComboBoxTableViewLayer;class ComboBox : public CCLayer{public:    ComboBox();    virtual ~ComboBox();    bool init(const char* text, const char* bgImg, const char* btnImg, const char* hightLightBtnImg, const char* cellBackGround, int fontSize, float borderPix, const char* font);    static ComboBox* create(const char* text, const char* bgImg, const char* btnImg, const char* hightLightBtnImg, const char* cellBackGround, int fontSize, float borderPix, const char* font="Marker Felt");    bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);     void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);    void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);    void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);    void touchUpInside(CCObject* pSender, CCControlEvent event);    void setComboBoxDataList(const ComboBoxDataList& dataList) ;    void setComboBoxDataFromContinuousInt(int start, int end, int step=1);    void setComboBoxDataFromContinuousFloat(float start, float end, float step=1.0);    void clearDataList();    const char* getLabel();    void setLabel(const char* label);protected:    void setContentSize(const CCSize& s);protected:    CCLabelTTF* m_label;    CCControlButton* m_button;    CCScale9Sprite* m_backGround;    ComboBoxTableViewLayer* m_tableViewLayer;    ComboBoxDataList m_dataList;    const char* m_cellBackGround;    const char* m_font;    float m_borderPix;    float m_fontSize;};class ComboBoxTableViewLayer : public CCLayer, public CCTableViewDataSource, public CCTableViewDelegate{public:    ComboBoxTableViewLayer();    ~ComboBoxTableViewLayer();    virtual bool init(ComboBoxDataList* dataList, const char* cellBackGround, float borderPix, float fontSize, const char* font);      static ComboBoxTableViewLayer* create(ComboBox* frame, ComboBoxDataList* dataList, const char* cellBackGround, float borderPix, float fontSize, const char* font);    void reloadDataList();    MyTableView* getTableView() { return m_tableView; }        virtual void scrollViewDidScroll(CCScrollView* view) {};    virtual void scrollViewDidZoom(CCScrollView* view) {}    virtual void tableCellTouched(CCTableView* table, CCTableViewCell* cell);    virtual CCSize cellSizeForTable(CCTableView *table);    virtual CCTableViewCell* tableCellAtIndex(CCTableView *table, unsigned int idx);    virtual unsigned int numberOfCellsInTableView(CCTableView *table);    void setFrame(ComboBox* frame) { m_frame = frame;}    bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);    void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);    void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);    void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);    void onEnter();    void onExit();protected:    const char* m_cellBackGround;    float m_borderPix;    float m_fontSize;    const char* m_font;    CCRect m_backGroundRect;    CCRect m_backGroundRectInsets;    ComboBoxDataList* m_dataList;    MyTableView* m_tableView;    ComboBox* m_frame;};#endif

 

ComboBox.cpp:

#include "ComboBox.h"ComboBox::ComboBox()    :m_label(NULL), m_button(NULL), m_backGround(NULL), m_tableViewLayer(NULL){}ComboBox::~ComboBox(){    if (m_label) {        m_label->release();    }    if (m_button) {        m_button->release();    }    if (m_backGround) {        m_backGround->release();    }    if (m_tableViewLayer) {        m_tableViewLayer->release();    }}ComboBox* ComboBox::create(const char* text, const char* bgImg, const char* btnImg, const char* hightLightBtnImg, const char* cellBackGround, int fontSize, float border, const char* font ){    ComboBox* comboBox = new ComboBox();    if (comboBox && comboBox->init(text, bgImg, btnImg, hightLightBtnImg, cellBackGround, fontSize, border, font)) {        comboBox->autorelease();        return comboBox;    } else {        delete comboBox;        return NULL;    }}const char* ComboBox::getLabel(){    return m_label->getString();}void ComboBox::setLabel(const char* label) {    m_label->setString(label);}bool ComboBox::init(const char* text, const char* bgImg, const char* btnImg, const char* hightLightBtnImg, const char* cellBackGround, int fontSize, float borderPix,  const char* font) {    m_cellBackGround = cellBackGround;    m_borderPix = borderPix;    m_fontSize = (float)fontSize;    m_font = font;    if (!CCLayer::init()) {        return false;    }    // 支持AnchorPoint定位, 默认情况下Layer不支持    ignoreAnchorPointForPosition(false);    // 支持触屏    setTouchEnabled(true);    // 创建Label    CCSize size;    m_label = CCLabelTTF::create(text, font, fontSize);    if (!m_label) return false;    m_label->setPosition(ccp(m_label->getContentSize().width/2, m_label->getContentSize().height/2));    m_label->retain();    addChild(m_label, 1);    size = m_label->getContentSize();    // 创建按钮    float space = 3;    /// 由于按钮图片可能是大图片,需要收缩,所以采用三个参数的create,需要先获取图片大小    CCSprite* tsp = CCSprite::create(btnImg);    CCSize s = tsp->getContentSize();    CCRect imgRect = CCRectMake(0,0, s.width, s.height);    CCRect imgRectInsets = CCRectMake(borderPix, borderPix, s.width-2*borderPix, s.height-2*borderPix);    tsp->release();    CCScale9Sprite *backgroundButton = CCScale9Sprite::create(btnImg, imgRect, imgRectInsets);    CCScale9Sprite *backgroundHighlightedButton = CCScale9Sprite::create(hightLightBtnImg, imgRect, imgRectInsets);    m_button = CCControlButton::create(backgroundButton);    m_button->setZoomOnTouchDown(false);    m_button->setBackgroundSpriteForState(backgroundHighlightedButton, CCControlStateHighlighted);    m_button->setPreferredSize(CCSizeMake(size.height, size.height));    m_button->setPosition(m_label->getContentSize().width + m_button->getContentSize().width/2 + space, m_button->getContentSize().height/2);    m_button->addTargetWithActionForControlEvents(this, cccontrol_selector(ComboBox::touchUpInside), CCControlEventTouchUpInside);    m_button->retain();    addChild(m_button, 1);        size.width += m_button->getContentSize().width + space;    if (m_button->getContentSize().height > size.height) {        size.height = m_button->getContentSize().height;    }    // 创建背景, 背景图片正常都是拉伸,用一个参数的create够了,如果背景还搞大图片,那就不能怪我了。。。    m_backGround = CCScale9Sprite::create(bgImg);    m_backGround->setPreferredSize(size);    m_backGround->setPosition(ccp(m_backGround->getContentSize().width/2, m_backGround->getContentSize().height/2));    m_backGround->retain();    addChild(m_backGround, 0);    this->setContentSize(size);    //m_tableViewLayer = ComboBoxTableViewLayer::create(&m_dataList, cellBackGround, borderPix, (float)fontSize, font);     //m_tableViewLayer->retain();}void ComboBox::setComboBoxDataList(const ComboBoxDataList& dataList){    m_dataList = dataList;}void ComboBox::setComboBoxDataFromContinuousInt(int start, int end, int step){    char buf[50];    for (int i=start; i <= end; i+=step)    {        sprintf(buf, "%d", i);        m_dataList.push_back(buf);    }}void ComboBox::setComboBoxDataFromContinuousFloat(float start, float end, float step){    char buf[50];    for (float i=start; i <= end; i+=step)    {        sprintf(buf, "%f", i);        m_dataList.push_back(buf);    }}void ComboBox::clearDataList(){    m_dataList.clear();}void ComboBox::setContentSize(const CCSize& s){    CCLayer::setContentSize(s);}bool ComboBox::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) {    CCPoint p = m_button->getPosition();    p.x+=1;    p.y+=1;    pTouch->setTouchInfo(pTouch->getID(), p.x, p.y);    m_button->ccTouchBegan(pTouch, pEvent);    return true;    // 屏蔽该消息不往下传递}void ComboBox::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) {    CCPoint p = m_button->getPosition();    p.x+=1;    p.y+=1;    pTouch->setTouchInfo(pTouch->getID(), p.x, p.y);    m_button->ccTouchMoved(pTouch, pEvent);}void ComboBox::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) {    CCPoint p = m_button->getPosition();    p.x+=1;    p.y+=1;    pTouch->setTouchInfo(pTouch->getID(), p.x, p.y);    m_button->ccTouchEnded(pTouch, pEvent);}void ComboBox::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent) {    CCPoint p = m_button->getPosition();    p.x+=1;    p.y+=1;    pTouch->setTouchInfo(pTouch->getID(), p.x, p.y);    m_button->ccTouchEnded(pTouch, pEvent);}void ComboBox::touchUpInside(CCObject* pSender, CCControlEvent event){    CCLog("touchUpInside");    CCSize winSize = CCDirector::sharedDirector()->getWinSize();    float fontSize = (float)m_fontSize/2;    if (fontSize < 20) {        fontSize = 20;    }    ComboBoxTableViewLayer* layer = ComboBoxTableViewLayer::create(this, &m_dataList, m_cellBackGround, m_borderPix, fontSize, m_font);     layer->setAnchorPoint(ccp(0.5,0.5));    layer->setPosition(ccp(winSize.width/2, winSize.height/2));    CCScene* curScene = CCDirector::sharedDirector()->getRunningScene();    int cnt = curScene->getChildrenCount();    CCLog("cnt=%d", cnt);    curScene->addChild(layer, cnt+15);}ComboBoxTableViewLayer::ComboBoxTableViewLayer()     :m_tableView(NULL){}ComboBoxTableViewLayer::~ComboBoxTableViewLayer(){    CC_SAFE_RELEASE(m_tableView);}ComboBoxTableViewLayer* ComboBoxTableViewLayer::create(ComboBox* frame, ComboBoxDataList* dataList, const char* cellBackGround, float borderPix, float fontSize, const char* font){    ComboBoxTableViewLayer* layer = new ComboBoxTableViewLayer();    if (layer && layer->init(dataList, cellBackGround, borderPix, fontSize, font)) {        layer->setFrame(frame);        layer->autorelease();        return layer;    }else {        CC_SAFE_DELETE(layer);        return NULL;    }}bool ComboBoxTableViewLayer::init(ComboBoxDataList* dataList, const char* cellBackGround, float borderPix, float fontSize, const char* font){    m_dataList = dataList;    m_cellBackGround = cellBackGround;    m_borderPix = borderPix;    m_fontSize = fontSize;    m_font = font;    CCLog("ComboBoxTableViewLayer, cellBackGround=%s, borderPix=%f, fontSize=%f, font=%s", m_cellBackGround, m_borderPix, m_fontSize, m_font);    if ( !CCLayer::init() )    {        return false;    }    /// 支持锚点    ignoreAnchorPointForPosition(false);    // 先保存图片的大小    CCSprite* tps = CCSprite::create(cellBackGround);    CCSize s = tps->getContentSize();    m_backGroundRect = CCRectMake(0,0, s.width, s.height);    m_backGroundRectInsets = CCRectMake(m_borderPix, m_borderPix, s.width-2*m_borderPix, s.height-2*m_borderPix);    tps->release();    CCSize winSize = CCDirector::sharedDirector()->getWinSize();    CCSize contentSize = CCSizeMake(winSize.width*0.9, winSize.height*0.9);    m_tableView = MyTableView::create(this, contentSize);    m_tableView->setDirection(kCCScrollViewDirectionVertical);    m_tableView->setDelegate(this);    m_tableView->setVerticalFillOrder(kCCTableViewFillTopDown);    m_tableView->reloadData();    m_tableView->retain();    this->addChild(m_tableView);    setContentSize(contentSize);    CCSize sx = getContentSize();    CCLog("cctt.w,h:%f,%f", sx.width, sx.height);    return true;}void ComboBoxTableViewLayer::tableCellTouched(CCTableView* table, CCTableViewCell* cell){    CCLog("cell touched at index: %i", cell->getIdx());    const char* name = ((CCLabelTTF*)(cell->getChildByTag(123)))->getString();    m_frame->setLabel(name);    this->removeFromParentAndCleanup(true);}CCSize ComboBoxTableViewLayer::cellSizeForTable(CCTableView *table){    CCSize contentSize = getContentSize();    return CCSizeMake(contentSize.width, m_fontSize+15);}CCTableViewCell* ComboBoxTableViewLayer::tableCellAtIndex(CCTableView *table, unsigned int idx){    std::string str = (*m_dataList)[idx];    CCTableViewCell *cell = table->dequeueCell();    if (!cell) {        CCLog("add str:%s", str.c_str());        CCSize s = cellSizeForTable(NULL);        cell = new CCTableViewCell();        cell->autorelease();        CCScale9Sprite* backGround = CCScale9Sprite::create(m_cellBackGround, m_backGroundRect, m_backGroundRectInsets);         backGround->setContentSize(s);        backGround->setPosition(CCPointZero);        backGround->setAnchorPoint(CCPointZero);        cell->addChild(backGround, 0);        CCLabelTTF *label = CCLabelTTF::create(str.c_str(), m_font, m_fontSize);        label->setPosition(CCPointZero);        label->setAnchorPoint(CCPointZero);        label->setTag(123);        cell->addChild(label, 1);    }    else    {        CCLabelTTF *label = (CCLabelTTF*)cell->getChildByTag(123);        label->setString(str.c_str());    }    return cell;}unsigned int ComboBoxTableViewLayer::numberOfCellsInTableView(CCTableView *table){    return m_dataList->size();}void ComboBoxTableViewLayer::reloadDataList(){    m_tableView->reloadData();}bool ComboBoxTableViewLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent){    m_tableView->ccTouchBegan(pTouch, pEvent);    return true;}void ComboBoxTableViewLayer::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent){    m_tableView->ccTouchMoved(pTouch, pEvent);}void ComboBoxTableViewLayer::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent){    m_tableView->ccTouchEnded(pTouch, pEvent);}void ComboBoxTableViewLayer::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent){    m_tableView->ccTouchEnded(pTouch, pEvent);}void ComboBoxTableViewLayer::onEnter(){    CCLayer::onEnter();    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -129, true);}void ComboBoxTableViewLayer::onExit(){    CCLayer::onExit();    CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);}

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
QT中常用的输入控件
gstreamer使用opencv在视频中写入中文
const char *,char const *,char * const
124 f0408
const char*, char const* and char *const 等的区别
cocos2d-x 关卡选择界面(CCScrollView的使用)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服