//WidgetSlideListView.h
class WidgetEaseInListView : public cocos2d::gui::UIListView { public: static WidgetEaseInListView* create(cocos2d::gui::UIListView* pAnthor=NULL); void doEaseIn(bool bRight2Left=true); protected: virtual void copySpecialProperties(cocos2d::gui::Widget* model); protected: virtual void onEaseInOver(); virtual void startEaseIn(bool bRight2Left); virtual void tick(float delta); protected: bool m_bRight2Left; }; class SlideListViewDataSource { public: virtual size_t getTotalItemNum() = 0; virtual size_t getEveryPageItemNum() = 0; virtual cocos2d::gui::UIWidget* getWidgetAt(size_t nIdx) = 0; virtual void onPageTurnOver(size_t nCurrentPage){} }; class WidgetSlideListView : public WidgetEaseInListView { enum SlideDir { eSlideDir_None = 0, eSlideDir_Horizon_Left, eSlideDir_Horizon_Right, eSlideDir_Virtical }; protected: WidgetSlideListView(); virtual ~WidgetSlideListView(); public: static WidgetSlideListView* create(SlideListViewDataSource* pDelegate,cocos2d::gui::UIListView* pAnthor=NULL); public: void setDelegate(SlideListViewDataSource* pDelegate){ m_pDelegate = pDelegate; } void reloadData(); size_t getCurrentPage()const{ return m_nCurrentPage; } void turnToPage(unsigned int nPage); protected: virtual bool init(); virtual void handleMoveLogic(const cocos2d::CCPoint &touchPoint); virtual void handleReleaseLogic(const cocos2d::CCPoint &touchPoint); void scheduleTurnPage(float t); protected: SlideListViewDataSource* m_pDelegate; size_t m_nCurrentPage; SlideDir m_eSlideDir; cocos2d::CCPoint m_BackPos; };
//WidgetSlideListView.cpp
#include "../include/WidgetSlideListView.h" USING_NS_CC; USING_NS_CC_EXT; using namespace cocos2d::gui; WidgetEaseInListView* WidgetEaseInListView::create(UIListView* pAnthor/*=NULL*/) { WidgetEaseInListView* pRet = new WidgetEaseInListView(); if (pRet && pRet->init()) { pRet->autorelease(); if (pAnthor) { pRet->copyProperties(pAnthor); } return pRet; } else { delete pRet; pRet = NULL; return NULL; } } void WidgetEaseInListView::copySpecialProperties(cocos2d::gui::Widget* model) { UIListView::copySpecialProperties(model); setDirection(SCROLLVIEW_DIR_VERTICAL); setBounceEnabled(true); setTouchEnabled(true); } void WidgetEaseInListView::tick(float delta) { startEaseIn(m_bRight2Left); } void WidgetEaseInListView::doEaseIn(bool bRight2Left) { stopAllActions(); for (unsigned int i=0; i<getItems()->count(); i++) { UIWidget* pWidget = getItem(i); pWidget->setVisible(false); } m_bRight2Left = bRight2Left; scheduleOnce(schedule_selector(WidgetEaseInListView::tick),0); } void WidgetEaseInListView::startEaseIn(bool bRight2Left) { setTouchEnabled(false); static const float fDelay = 0.1f; static const float fMoveTime = 0.4f; CCArray* pActSeq = CCArray::create(); float fVisibleHeight = 0.0f; float fTotalHeight = getSize().height; CCArray* pArr = getItems(); int nSlidCount =0; for (unsigned int i=0; i<pArr->count(); i++) { UIWidget* pWidget = getItem(i); pWidget->setVisible(true); fVisibleHeight+=pWidget->getSize().height; if (fVisibleHeight<fTotalHeight+pWidget->getSize().height) { float fOffset = (bRight2Left?1:-1)*pWidget->getContentSize().width; CCPoint startPos = ccpAdd(pWidget->getPosition(),ccp(fOffset,0)); //CCPoint startPos = ccp(pWidget->getContentSize().width/2+fOffset,pWidget->getPosition().y); pWidget->setPosition(startPos); CCSequence* pAct = CCSequence::createWithTwoActions(CCDelayTime::create(fDelay*i),CCEaseBackOut::create(CCMoveBy::create(fMoveTime,ccp(-fOffset,0)))); pActSeq->addObject(CCTargetedAction::create(pWidget,pAct) ); nSlidCount++; } } CCSequence* pAct = CCSequence::createWithTwoActions(CCDelayTime::create(fDelay*nSlidCount),CCCallFunc::create(this,callfunc_selector(WidgetEaseInListView::onEaseInOver))); pActSeq->addObject(pAct); runAction(CCSpawn::create(pActSeq)); } void WidgetEaseInListView::onEaseInOver() { setTouchEnabled(true); } WidgetSlideListView::WidgetSlideListView() :m_pDelegate(NULL) ,m_nCurrentPage(0) ,m_eSlideDir(eSlideDir_None) { } WidgetSlideListView::~WidgetSlideListView() { } WidgetSlideListView* WidgetSlideListView::create(SlideListViewDataSource* pDelegate,UIListView* pAnthor/*=NULL*/) { WidgetSlideListView* pRet = new WidgetSlideListView(); if (pRet && pRet->init()) { pRet->autorelease(); pRet->setDelegate(pDelegate); if (pAnthor) { pRet->copyProperties(pAnthor); } return pRet; } else { delete pRet; pRet = NULL; return NULL; } } bool WidgetSlideListView::init() { if (UIListView::init()) { setDirection(SCROLLVIEW_DIR_VERTICAL); setBounceEnabled(true); setTouchEnabled(true); return true; } return false; } void WidgetSlideListView::reloadData() { assert(m_pDelegate); assert(m_pDelegate->getEveryPageItemNum()>0); unsigned int nTotalPage = m_pDelegate->getTotalItemNum()/m_pDelegate->getEveryPageItemNum(); nTotalPage+= m_pDelegate->getTotalItemNum()%m_pDelegate->getEveryPageItemNum()>0 ? 1 : 0; assert(m_nCurrentPage>=0); removeAllItems(); if (m_pDelegate->getTotalItemNum()>0) { assert(m_nCurrentPage<nTotalPage); for (size_t i=0; i<m_pDelegate->getEveryPageItemNum(); i++) { if (m_pDelegate->getTotalItemNum()<(i+1)+m_nCurrentPage*m_pDelegate->getEveryPageItemNum()) { break; } UIWidget* pChild = m_pDelegate->getWidgetAt(m_nCurrentPage*m_pDelegate->getEveryPageItemNum()+i); if (!pChild) { break; } pushBackCustomItem(pChild); } } jumpToTop(); } void WidgetSlideListView::handleMoveLogic( const CCPoint &touchPoint ) { _touchMovedPoint = convertToNodeSpace(touchPoint); CCPoint delta = _touchMovedPoint - _touchBeganPoint; if (eSlideDir_None==m_eSlideDir) { m_eSlideDir = fabs(delta.x)>fabs(delta.y) ? eSlideDir_Horizon_Left : eSlideDir_Virtical; m_BackPos = _innerContainer->getPosition(); } if (eSlideDir_Virtical==m_eSlideDir) { UIListView::handleMoveLogic(touchPoint); } else if (eSlideDir_None!=m_eSlideDir) { if (isTouchEnabled()) { CCPoint pt = ccp(m_BackPos.x+delta.x,m_BackPos.y); _innerContainer->setPosition(pt); } } } void WidgetSlideListView::handleReleaseLogic( const CCPoint &touchPoint ) { if (eSlideDir_Virtical==m_eSlideDir) { UIListView::handleReleaseLogic(touchPoint); m_eSlideDir = eSlideDir_None; } else if (eSlideDir_None!=m_eSlideDir) { if (isTouchEnabled()) { CCPoint delta = _touchMovedPoint - _touchBeganPoint; static const float fDelatPosX = 30; if (delta.x<-fDelatPosX && m_pDelegate->getTotalItemNum()>(m_nCurrentPage+1)*m_pDelegate->getEveryPageItemNum()) { m_eSlideDir = eSlideDir_Horizon_Left; scheduleOnce( schedule_selector(WidgetSlideListView::scheduleTurnPage),0); } else if (delta.x>fDelatPosX && m_nCurrentPage>0) { m_eSlideDir = eSlideDir_Horizon_Right; scheduleOnce( schedule_selector(WidgetSlideListView::scheduleTurnPage),0); } else { m_eSlideDir = eSlideDir_None; _innerContainer->setPosition(m_BackPos); } } } } void WidgetSlideListView::turnToPage(unsigned int nPage) { bool bRight2Left = m_nCurrentPage<=nPage; m_nCurrentPage=nPage; reloadData(); doEaseIn(bRight2Left); m_pDelegate->onPageTurnOver(m_nCurrentPage); } void WidgetSlideListView::scheduleTurnPage(float t) { if (eSlideDir_Horizon_Left==m_eSlideDir) { turnToPage(m_nCurrentPage+1); } else if (eSlideDir_Horizon_Right==m_eSlideDir) { turnToPage(m_nCurrentPage-1); } m_eSlideDir = eSlideDir_None; }