//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;
}