axmol/cocos2dx/extensions/CCListView/CCListView.cpp

2157 lines
49 KiB
C++
Raw Normal View History

#include "CCListView.h"
//#include "../cocos2dx_support/LuaEngineImpl.h"
#include "cocos2d.h"
using namespace std;
NS_CC_EXT_BEGIN
#define ND_LISTVIEW_ACTION_INTERVAL 0.6666
/******************************************
**************Public Functions*************
*******************************************/
CCListView* CCListView::viewWithMode(CCListViewMode mode)
{
CCListView *pRet = new CCListView();
if (pRet && pRet->initWithMode(mode))
{
pRet->autorelease();
return pRet;
}
else
{
CC_SAFE_DELETE(pRet);
return NULL;
}
}
bool CCListView::initWithMode(CCListViewMode mode)
{
bool bRet = false;
m_nMode = mode;
m_layerPanel = CCLayer::node();
this->addChild(m_layerPanel);
bRet = CCLayerColor::initWithColor(ccc4(255, 255, 255, 0), 0, 0);
setIsTouchEnabled(true);
return bRet;
}
CCListView::CCListView(void)
:m_nMode(CCListViewModeVertical)
,m_nState(CCListViewStateWatting)
,m_nSlideDir(CCListViewSlideDirNone)
,m_layerPanel(NULL)
,m_nSeparatorStyle(CCListViewCellSeparatorStyleSingleLine)
,m_nSelectedRow(-1)
,m_nCurrentRow(-1)
,m_fActionDuration(ND_LISTVIEW_ACTION_INTERVAL)
,m_pListViewParent(NULL)
,m_bIsEnabled(true)
,m_pDelegate(NULL)
,m_nNumberOfRows(0)
,m_bIsOnTouch(false)
{
m_drawedRows = CCRangeMake(0, 0);
m_visibleRows = CCRangeMake(0, 0);
m_bIsTouchEnabled = true;
}
CCListView::~CCListView(void)
{
}
void CCListView::setDelegateName(const char* pszName)
{
if (pszName)
{
this->m_strDeletegate = string(pszName) + ".";
}
else
{
this->m_strDeletegate.clear();
}
}
void CCListView::selectCellAtRow(unsigned int nRow)
{
CCListViewCell *cell = cellAtRow(nRow);
if (cell)
{
cell->selected();
}
}
void CCListView::unselectCellAtRow(unsigned int nRow)
{
if (nRow == m_nSelectedRow)
{
m_nSelectedRow = -1;
}
CCListViewCell *cell = cellAtRow(nRow);
if (cell)
{
cell->unselected();
}
}
void CCListView::reload(void)
{
m_layerPanel->removeAllChildrenWithCleanup(true);
m_layerPanel->setPosition(CCPointZero);
m_visibleRows = CCRangeMake(0, 0);
m_drawedRows = CCRangeMake(0, 0);
m_nNumberOfRows = triggerNumberOfCells();
this->displayVisibleRows();
}
void CCListView::insertCellsAtRow(unsigned int nRow, unsigned int nCount)
{
if (nRow >= m_nNumberOfRows)
{
if (m_nNumberOfRows > 0)
{
nRow = m_nNumberOfRows - 1;
}
else
{
nRow = 0;
}
}
m_layerPanel->pauseSchedulerAndActions();
if (m_nNumberOfRows == 0)
{
m_nNumberOfRows = this->triggerNumberOfCells();
this->displayVisibleRows();
}
else
{
m_nNumberOfRows = this->triggerNumberOfCells();
if (!this->isFullFill())
{
this->displayVisibleRows();
}
}
m_layerPanel->resumeSchedulerAndActions();
}
void CCListView::deleteCellsAtRow(unsigned int nRow, unsigned int nCount)
{
if (m_nNumberOfRows == 0)
{
return;
}
if (nRow >= m_nNumberOfRows)
{
if (m_nNumberOfRows > 0)
{
nRow = m_nNumberOfRows - 1;
}
else
{
nRow = 0;
}
}
m_layerPanel->pauseSchedulerAndActions();
m_nNumberOfRows = this->triggerNumberOfCells();
for (unsigned int n = nRow;n < nRow + nCount; n++)
{
if (n >= m_drawedRows.location && n <= CCRange::CCMaxRange(m_drawedRows))
{
CCListViewCell *cell = this->cellAtRow(n);
if (cell)
{
CCPoint pos = cell->getPosition();
pos.y += cell->getContentSize().height;
m_layerPanel->removeChild(cell, true);
for (unsigned int i = n +1; i <= CCRange::CCMaxRange(m_drawedRows); i++)
{
cell = this->cellAtRow(i);
if (cell)
{
int tag = cell->getTag();
cell->setTag(tag - 1);
if (CCListViewModeHorizontal == m_nMode)
{
cell->setPosition(pos);
pos.x += cell->getContentSize().width;
}
else if (CCListViewModeVertical == m_nMode)
{
pos.y -= cell->getContentSize().height;
cell->setPosition(pos);
}
}
}
if (m_drawedRows.length > 0)
{
m_drawedRows.length--;
unsigned int nLastRow = CCRange::CCMaxRange(m_drawedRows);
this->appendRowToBack(nLastRow + 1);
}
}
}
else
{
for (unsigned int i = m_drawedRows.location; i <= CCRange::CCMaxRange(m_drawedRows); i++)
{
CCListViewCell *cell = this->cellAtRow(i);
if (cell)
{
int tag = cell->getTag();
cell->setTag(tag - 1);
}
}
if (m_drawedRows.location > 0)
{
m_drawedRows.location--;
}
}
}
m_layerPanel->resumeSchedulerAndActions();
}
void CCListView::scrollCellToFront(unsigned int nRow, bool bAnimated)
{
if (!isFullFill())
{
return;
}
if (m_nNumberOfRows == 0)
{
return;
}
if (CCListViewStateWatting != m_nState)
{
this->stopActionImmediately();
}
if (nRow >= m_nNumberOfRows)
{
nRow = m_nNumberOfRows - 1;
}
float disX = 0;
float disY = 0;
m_nSlideDir = CCListViewSlideDirNone;
if (CCListViewModeHorizontal == m_nMode)
{
float dis = 0;
unsigned int nCount = 0;
CCListViewCell *cell = NULL;
if (nRow > m_visibleRows.location)
{
m_nSlideDir = CCListViewSlideDirLeft;
}
else
{
m_nSlideDir = CCListViewSlideDirRight;
}
while(1)
{
if (dis >= this->getContentSize().width || nRow + nCount >= m_nNumberOfRows)
{
break;
}
if (CCListViewSlideDirRight == m_nSlideDir)
{
cell = appendRowToFront(nRow + nCount);
}
else if (CCListViewSlideDirLeft == m_nSlideDir)
{
cell = appendRowToBack(nRow + nCount);
}
if (cell)
{
nCount++;
dis += cell->getContentSize().width;
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
if (CCListViewSlideDirLeft == m_nSlideDir && dis < this->getContentSize().width)
{
// at last
while(1)
{
if (dis >= this->getContentSize().width)
{
break;
}
cell = appendRowToBack(nRow - 1);
if (cell)
{
nRow--;
dis += cell->getContentSize().width;
nCount++;
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
}
if (CCListViewSlideDirRight == m_nSlideDir)
{
CCListViewCell* cell = NULL;
unsigned nLast = 0;
if (CCRange::CCLocationInRange(nRow + nCount - 1, m_visibleRows))
{
cell = cellAtRow(nRow + nCount - 1);
nLast = nRow + nCount - 2;
}
else
{
cell = cellAtRow(m_visibleRows.location);
nLast = nRow + nCount - 1;
}
if (cell)
{
CCPoint pos = cell->getPosition();
for (int i = nLast; i >= (int)nRow; i--)
{
cell = cellAtRow(i);
if (cell)
{
pos.x -= cell->getContentSize().width;
cell->setPosition(pos);
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
else if (CCListViewSlideDirLeft == m_nSlideDir)
{
CCListViewCell* cell = NULL;
unsigned nFirst = 0;
if (CCRange::CCLocationInRange(nRow, m_visibleRows))
{
cell = cellAtRow(nRow);
nFirst = nRow + 1;
}
else
{
cell = cellAtRow(CCRange::CCMaxRange(m_visibleRows));
nFirst = nRow;
}
if (cell)
{
CCPoint pos = cell->getPosition();
pos.x += cell->getContentSize().width;
for (unsigned int i = nFirst; i < nRow + nCount; i++)
{
cell = cellAtRow(i);
if (cell)
{
cell->setPosition(pos);
pos.x += cell->getContentSize().width;
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
cell = cellAtRow(nRow);
CCPoint ptCell = cell->convertToWorldSpace(CCPointZero);
CCPoint ptView = this->convertToWorldSpace(CCPointZero);
disX = ptView.x - ptCell.x;
}
else if (CCListViewModeVertical == m_nMode)
{
float dis = 0;
unsigned int nCount = 0;
CCListViewCell *cell = NULL;
if (nRow > m_visibleRows.location)
{
m_nSlideDir = CCListViewSlideDirUp;
}
else
{
m_nSlideDir = CCListViewSlideDirDown;
}
while(1)
{
if (dis >= this->getContentSize().height || nRow + nCount >= m_nNumberOfRows)
{
break;
}
if (CCListViewSlideDirDown == m_nSlideDir)
{
cell = appendRowToFront(nRow + nCount);
}
else if (CCListViewSlideDirUp == m_nSlideDir)
{
cell = appendRowToBack(nRow + nCount);
}
if (cell)
{
nCount++;
dis += cell->getContentSize().height;
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
if (CCListViewSlideDirUp == m_nSlideDir && dis < this->getContentSize().height)
{
// at last
while(1)
{
if (dis >= this->getContentSize().height)
{
break;
}
cell = appendRowToBack(nRow - 1);
if (cell)
{
nRow--;
dis += cell->getContentSize().height;
nCount++;
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
}
if (CCListViewSlideDirDown == m_nSlideDir)
{
CCListViewCell* cell = NULL;
unsigned nLast = 0;
if (CCRange::CCLocationInRange(nRow + nCount - 1, m_visibleRows))
{
cell = cellAtRow(nRow + nCount - 1);
nLast = nRow + nCount - 2;
}
else
{
cell = cellAtRow(m_visibleRows.location);
nLast = nRow + nCount - 1;
}
if (cell)
{
CCPoint pos = cell->getPosition();
pos.y += cell->getContentSize().height;
for (int i = nLast; i >= (int)nRow; i--)
{
cell = cellAtRow(i);
if (cell)
{
cell->setPosition(pos);
pos.y += cell->getContentSize().height;
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
else if (CCListViewSlideDirUp == m_nSlideDir)
{
CCListViewCell* cell = NULL;
unsigned nFirst = 0;
if (CCRange::CCLocationInRange(nRow, m_visibleRows))
{
cell = cellAtRow(nRow);
nFirst = nRow + 1;
}
else
{
cell = cellAtRow(CCRange::CCMaxRange(m_visibleRows));
nFirst = nRow;
}
if (cell)
{
CCPoint pos = cell->getPosition();
for (unsigned int i = nFirst; i < nRow + nCount; i++)
{
cell = cellAtRow(i);
if (cell)
{
pos.y -= cell->getContentSize().height;
cell->setPosition(pos);
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
cell = cellAtRow(nRow);
CCPoint ptCell = cell->convertToWorldSpace(CCPointZero);
CCPoint ptView = this->convertToWorldSpace(CCPointZero);
disY = ptView.y + this->getContentSize().height - (ptCell.y + cell->getContentSize().height);
}
m_ptDestination = m_layerPanel->getPosition();
m_ptDestination.x += disX;
m_ptDestination.y += disY;
m_nState = CCListViewStateScroll;
if (bAnimated)
{
CCMoveBy *moveBy = CCMoveBy::actionWithDuration(m_fActionDuration, CCPointMake(disX, disY));
CCEaseOut *ease = CCEaseOut::actionWithAction(moveBy, 3);
CCFiniteTimeAction *actions = CCSequence::actions(ease, CCCallFunc::actionWithTarget(this, callfunc_selector(CCListView::finishScroll)), NULL);
m_layerPanel->runAction(actions);
}
else
{
stopActionImmediately();
}
}
void CCListView::scrollCellToBack(unsigned int nRow, bool bAnimated)
{
if (!isFullFill())
{
return;
}
if (m_nNumberOfRows == 0)
{
return;
}
if (CCListViewStateWatting != m_nState)
{
this->stopActionImmediately();
}
if (nRow >= m_nNumberOfRows)
{
nRow = m_nNumberOfRows - 1;
}
float disX = 0;
float disY = 0;
m_nSlideDir = CCListViewSlideDirNone;
if (CCListViewModeHorizontal == m_nMode)
{
float dis = 0;
int nCount = 0;
CCListViewCell *cell = NULL;
if (nRow > CCRange::CCMaxRange(m_visibleRows))
{
m_nSlideDir = CCListViewSlideDirLeft;
}
else
{
m_nSlideDir = CCListViewSlideDirRight;
}
while(1)
{
if (dis >= this->getContentSize().width || (int)nRow - nCount < 0)
{
break;
}
if (CCListViewSlideDirRight == m_nSlideDir)
{
cell = appendRowToFront(nRow - nCount);
}
else if (CCListViewSlideDirLeft == m_nSlideDir)
{
cell = appendRowToBack(nRow - nCount);
}
if (cell)
{
nCount++;
dis += cell->getContentSize().width;
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
if (CCListViewSlideDirRight == m_nSlideDir && dis < this->getContentSize().width)
{
// at first
while(1)
{
if (dis >= this->getContentSize().width)
{
break;
}
cell = appendRowToBack(nRow + 1);
if (cell)
{
nRow++;
dis += cell->getContentSize().width;
nCount++;
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
}
if (CCListViewSlideDirRight == m_nSlideDir)
{
CCListViewCell* cell = NULL;
unsigned nLast = 0;
if (CCRange::CCLocationInRange(nRow, m_visibleRows))
{
cell = cellAtRow(nRow);
nLast = nRow - 1;
}
else
{
cell = cellAtRow(m_visibleRows.location);
nLast = nRow;
}
if (cell)
{
CCPoint pos = cell->getPosition();
for (int i = nLast; i >= (int)(nRow - nCount + 1); i--)
{
cell = cellAtRow(i);
if (cell)
{
pos.x -= cell->getContentSize().width;
cell->setPosition(pos);
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
else if (CCListViewSlideDirLeft == m_nSlideDir)
{
CCListViewCell* cell = NULL;
unsigned nFirst = 0;
if (CCRange::CCLocationInRange(nRow - nCount + 1, m_visibleRows))
{
cell = cellAtRow(nRow - nCount + 1);
nFirst = nRow - nCount + 2;
nCount--;
}
else
{
cell = cellAtRow(CCRange::CCMaxRange(m_visibleRows));
nFirst = nRow - nCount + 1;
}
if (cell)
{
CCPoint pos = cell->getPosition();
pos.x += cell->getContentSize().width;
for (unsigned int i = nFirst; i < nFirst + nCount; i++)
{
cell = cellAtRow(i);
if (cell)
{
cell->setPosition(pos);
pos.x += cell->getContentSize().width;
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
cell = cellAtRow(nRow);
CCPoint ptCell = cell->convertToWorldSpace(CCPointZero);
CCPoint ptView = this->convertToWorldSpace(CCPointZero);
disX = ptView.x + this->getContentSize().width - (ptCell.x + cell->getContentSize().width);
}
else if (CCListViewModeVertical == m_nMode)
{
float dis = 0;
int nCount = 0;
CCListViewCell *cell = NULL;
if (nRow > CCRange::CCMaxRange(m_visibleRows))
{
m_nSlideDir = CCListViewSlideDirUp;
}
else
{
m_nSlideDir = CCListViewSlideDirDown;
}
while(1)
{
if (dis >= this->getContentSize().height || (int)nRow - nCount < 0)
{
break;
}
if (CCListViewSlideDirDown == m_nSlideDir)
{
cell = appendRowToFront(nRow - nCount);
}
else if (CCListViewSlideDirUp == m_nSlideDir)
{
cell = appendRowToBack(nRow - nCount);
}
if (cell)
{
nCount++;
dis += cell->getContentSize().height;
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
if (CCListViewSlideDirDown == m_nSlideDir && dis < this->getContentSize().height)
{
// at first
while(1)
{
if (dis >= this->getContentSize().height)
{
break;
}
cell = appendRowToBack(nRow + 1);
if (cell)
{
nRow++;
dis += cell->getContentSize().height;
nCount++;
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
}
if (CCListViewSlideDirDown == m_nSlideDir)
{
CCListViewCell* cell = NULL;
unsigned nLast = 0;
if (CCRange::CCLocationInRange(nRow, m_visibleRows))
{
cell = cellAtRow(nRow);
nLast = nRow - 1;
}
else
{
cell = cellAtRow(m_visibleRows.location);
nLast = nRow;
}
if (cell)
{
CCPoint pos = cell->getPosition();
pos.y += cell->getContentSize().height;
for (int i = nLast; i >= (int)(nRow - nCount + 1); i--)
{
cell = cellAtRow(i);
if (cell)
{
cell->setPosition(pos);
pos.y += cell->getContentSize().height;
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
else if (CCListViewSlideDirUp == m_nSlideDir)
{
CCListViewCell* cell = NULL;
unsigned nFirst = 0;
if (CCRange::CCLocationInRange(nRow - nCount + 1, m_visibleRows))
{
cell = cellAtRow(nRow - nCount + 1);
nFirst = nRow - nCount + 2;
nCount--;
}
else
{
cell = cellAtRow(CCRange::CCMaxRange(m_visibleRows));
nFirst = nRow - nCount + 1;
}
if (cell)
{
CCPoint pos = cell->getPosition();
for (unsigned int i = nFirst; i < nFirst + nCount; i++)
{
cell = cellAtRow(i);
if (cell)
{
pos.y -= cell->getContentSize().height;
cell->setPosition(pos);
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
cell = cellAtRow(nRow);
CCPoint ptCell = cell->convertToWorldSpace(CCPointZero);
CCPoint ptView = this->convertToWorldSpace(CCPointZero);
disY = ptView.y - ptCell.y;
}
m_ptDestination = m_layerPanel->getPosition();
m_ptDestination.x += disX;
m_ptDestination.y += disY;
m_nState = CCListViewStateScroll;
if (bAnimated)
{
CCMoveBy *moveBy = CCMoveBy::actionWithDuration(m_fActionDuration, CCPointMake(disX, disY));
CCEaseOut *ease = CCEaseOut::actionWithAction(moveBy, 3);
CCFiniteTimeAction *actions = CCSequence::actions(ease, CCCallFunc::actionWithTarget(this, callfunc_selector(CCListView::finishScroll)), NULL);
m_layerPanel->runAction(actions);
}
else
{
stopActionImmediately();
}
}
CCListViewSlideDir CCListView::getSlideDir(CCPoint ptTouchBegan, CCPoint ptTouchEnd)
{
CCListViewSlideDir nSlideDir = CCListViewSlideDirNone;
int nOffsetX = ptTouchEnd.x - ptTouchBegan.x;
int nOffsetY = ptTouchEnd.y - ptTouchBegan.y;
int disMin = CCDirector::sharedDirector()->getWinSize().height / 100;
if(CCListViewModeHorizontal == m_nMode)
{
if(nOffsetX >= disMin)
{
nSlideDir = CCListViewSlideDirRight;
}
else if (nOffsetX <= -disMin)
{
nSlideDir = CCListViewSlideDirLeft;
}
}
else if (CCListViewModeVertical == m_nMode)
{
if(nOffsetY >= disMin)
{
nSlideDir = CCListViewSlideDirUp;
}
else if (nOffsetY <= -disMin)
{
nSlideDir = CCListViewSlideDirDown;
}
}
return nSlideDir;
}
/******************************************
**************Private Functions************
*******************************************/
int CCListView::rowForTouch(cocos2d::CCTouch *touch)
{
CCPoint touchLocation = touch->locationInView();
touchLocation = CCDirector::sharedDirector()->convertToGL(touchLocation);
CCArray *pChildren = m_layerPanel->getChildren();
if (pChildren && pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
if (pChild && pChild->getIsVisible())
{
CCPoint local = pChild->convertToNodeSpace(touchLocation);
CCRect r = CCRectZero;
r.size = pChild->getContentSize();
if (CCRect::CCRectContainsPoint(r, local))
{
return pChild->getTag();
}
}
}
}
return -1;
}
void CCListView::finishFix(void)
{
if(m_pListViewParent)
{
m_pListViewParent->setIsEnabled(true);
}
m_nState = CCListViewStateWatting;
m_nSlideDir = CCListViewSlideDirNone;
clearUnvisibleRows();
triggerDidScrollToRow(m_visibleRows.location);
CCArray *children = m_layerPanel->getChildren();
int nCount = 0;
if (children)
{
nCount = children->count();
}
//CCLog("row num left:%d [%d, %d]", nCount, m_drawedRows.location, CCRange::CCMaxRange(m_drawedRows));
}
void CCListView::finishScroll(void)
{
finishFix();
}
void CCListView::finishEaseOut(void)
{
bool bNeedFix = false;
if (CCListViewModeHorizontal == m_nMode)
{
bool bFullFill = isFullFill();
if (CCListViewSlideDirLeft == m_nSlideDir && bFullFill)
{
CCListViewCell *cell = cellAtRow(m_nNumberOfRows - 1);
if (cell)
{
CCPoint ptCell = cell->convertToWorldSpace(CCPointZero);
CCPoint ptView = this->convertToWorldSpace(CCPointZero);
if (ptCell.x + cell->getContentSize().width < ptView.x + this->getContentSize().width)
{
bNeedFix = true;
fixLastRow();
}
}
}
else
{
CCListViewCell *cell = cellAtRow(0);
if (cell)
{
CCPoint ptCell = cell->convertToWorldSpace(CCPointZero);
CCPoint ptView = this->convertToWorldSpace(CCPointZero);
if (ptCell.x > ptView.x || !bFullFill)
{
bNeedFix = true;
fixFirstRow();
}
}
}
}
else if (CCListViewModeVertical == m_nMode)
{
bool bFullFill = this->isFullFill();
if (CCListViewSlideDirUp == m_nSlideDir && bFullFill)
{
CCListViewCell *cell = cellAtRow(m_nNumberOfRows - 1);
if (cell)
{
CCPoint ptCell = cell->convertToWorldSpace(CCPointZero);
CCPoint ptView = this->convertToWorldSpace(CCPointZero);
if (ptCell.y > ptView.y)
{
bNeedFix = true;
fixLastRow();
}
}
}
else
{
CCListViewCell *cell = cellAtRow(0);
if (cell)
{
CCPoint ptCell = cell->convertToWorldSpace(CCPointZero);
CCPoint ptView = this->convertToWorldSpace(CCPointZero);
if (ptCell.y + cell->getContentSize().height < ptView.y + this->getContentSize().height || !bFullFill)
{
bNeedFix = true;
fixFirstRow();
}
}
}
}
if (!bNeedFix)
{
finishFix();
}
}
bool CCListView::isTouchInside(CCTouch *touch)
{
CCPoint point;
if (m_pListViewParent)
{
point = m_pListViewParent->convertTouchToNodeSpace(touch);
}
else
{
point = this->convertTouchToNodeSpace(touch);
}
CCRect bounds = CCRectMake(0, 0, this->getContentSize().width, this->getContentSize().height);
bool bIn = CCRect::CCRectContainsPoint(bounds, point);
return bIn;
}
bool CCListView::isFullFill(void)
{
bool bRet = false;
float length = 0;
for (unsigned int i = m_drawedRows.location; i <= CCRange::CCMaxRange(m_drawedRows); i++)
{
CCListViewCell *cell = cellAtRow(i);
if (cell)
{
if (CCListViewModeHorizontal == m_nMode)
{
length += cell->getContentSize().width;
if (length >= this->getContentSize().width)
{
bRet = true;
break;
}
}
else if (CCListViewModeVertical == m_nMode)
{
length += cell->getContentSize().height;
if (length >= this->getContentSize().height)
{
bRet = true;
break;
}
}
}
}
return bRet;
}
CCListViewCell *CCListView::cellAtRow(unsigned int nRow)
{
CCListViewCell *cell = (CCListViewCell*)m_layerPanel->getChildByTag(nRow);
return cell;
}
void CCListView::stopActionImmediately(void)
{
m_layerPanel->stopAllActions();
if (CCListViewStateScroll == m_nState)
{
m_layerPanel->setPosition(m_ptDestination);
finishScroll();
}
}
unsigned int CCListView::triggerNumberOfCells(void)
{
unsigned int nRow = 0;
CCListViewProtrolData data;
if (m_strDeletegate.size() > 0)
{
CCScriptEngineProtocol* scriptEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
if (scriptEngine)
{
std::string script;
script = m_strDeletegate + "CCListView_numberOfCells";
//TODO: scriptEngine->executeCallFuncNTDT(script.c_str(), this, "NdCxControl::CCListView", &data, "NdCxControl::CCListViewProtrolData");
nRow = data.nNumberOfRows;
}
}
if (m_pDelegate)
{
m_pDelegate->CCListView_numberOfCells(this, &data);
nRow = data.nNumberOfRows;
}
return nRow;
}
CCListViewCell *CCListView::triggerCellForRow(unsigned int nRow)
{
CCListViewCell *cell = NULL;
CCListViewProtrolData data;
data.nRow = nRow;
data.cell = NULL;
if (m_strDeletegate.size() > 0)
{
CCScriptEngineProtocol* scriptEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
if (scriptEngine)
{
std::string script;
script = m_strDeletegate + "CCListView_cellForRow";
//TODO: scriptEngine->executeCallFuncNTDT(script.c_str(), this, "NdCxControl::CCListView", &data, "NdCxControl::CCListViewProtrolData");
cell = data.cell;
}
}
if (m_pDelegate)
{
m_pDelegate->CCListView_cellForRow(this, &data);
cell = data.cell;
}
return cell;
}
void CCListView::triggerDidClickCellAtRow(unsigned int nRow)
{
CCListViewProtrolData data;
data.nRow = nRow;
if (m_strDeletegate.size() > 0)
{
CCScriptEngineProtocol* scriptEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
if (scriptEngine)
{
std::string script;
script = m_strDeletegate + "CCListView_didClickCellAtRow";
//TODO: scriptEngine->executeCallFuncNTDT(script.c_str(), this, "NdCxControl::CCListView", &data, "NdCxControl::CCListViewProtrolData");
}
}
if (m_pDelegate)
{
m_pDelegate->CCListView_didClickCellAtRow(this, &data);
}
}
void CCListView::triggerDidScrollToRow(unsigned int nRow)
{
CCListViewProtrolData data;
data.nRow = nRow;
if (m_strDeletegate.size() > 0)
{
CCScriptEngineProtocol* scriptEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
if (scriptEngine)
{
std::string script;
script = m_strDeletegate + "CCListView_didScrollToRow";
//TODO: scriptEngine->executeCallFuncNTDT(script.c_str(), this, "NdCxControl::CCListView", &data, "NdCxControl::CCListViewProtrolData");
}
}
if (m_pDelegate)
{
m_pDelegate->CCListView_didScrollToRow(this, &data);
}
}
void CCListView::displayVisibleRows(void)
{
CCSize size = getContentSize();
float posPannel, boundPannel;
unsigned int rowCount = m_drawedRows.location;
CCListViewCell *cell = cellAtRow(rowCount);
if (m_nMode == CCListViewModeHorizontal)
{
if (cell)
{
posPannel = cell->getPosition().x;
}
else
{
posPannel = m_layerPanel->getPosition().x;
}
boundPannel = posPannel + size.width;
}
else if (m_nMode == CCListViewModeVertical)
{
if (cell)
{
posPannel = cell->getPosition().y + cell->getContentSize().height;
}
else
{
posPannel = size.height - m_layerPanel->getPosition().y;
}
boundPannel = posPannel - size.height;
}
CCListViewCell *lastCell = NULL;
while(1)
{
// row condition
if (rowCount >= m_nNumberOfRows)
break;
// size condition
if (m_nMode == CCListViewModeHorizontal)
{
if (posPannel >= boundPannel)
break;
}
else if (m_nMode == CCListViewModeVertical)
{
if (posPannel <= boundPannel)
break;
}
// get cell
CCListViewCell *cell = cellAtRow(rowCount);
if (NULL == cell)
{
cell = triggerCellForRow(rowCount);
if (cell)
{
CCSize cellSize = cell->getContentSize();
if (m_nMode == CCListViewModeHorizontal)
{
cell->setPosition(CCPointMake(posPannel, 0));
cell->setContentSize(CCSizeMake(cellSize.width, size.height));
}
else if (m_nMode == CCListViewModeVertical)
{
cell->setPosition(CCPointMake(0, posPannel - cellSize.height));
cell->setContentSize(CCSizeMake(size.width, cellSize.height));
}
m_layerPanel->addChild(cell, rowCount, rowCount);
}
}
if (cell)
{
if (m_nMode == CCListViewModeHorizontal)
{
posPannel += cell->getContentSize().width;
}
else if (m_nMode == CCListViewModeVertical)
{
posPannel -= cell->getContentSize().height;
}
cell->setSeparatorStyle(m_nSeparatorStyle);
lastCell = cell;
}
++rowCount;
}
m_drawedRows.length = rowCount - m_drawedRows.location;
// <20><><EFBFBD>ÿ<EFBFBD><C3BF>ӷ<EFBFBD>Χ
m_visibleRows = m_drawedRows;
if (lastCell)
{
lastCell->setSeparatorStyle(CCListViewCellSeparatorStyleNone);
}
}
CCListViewCell* CCListView::appendRowToBack(unsigned int nRow)
{
if (nRow >= m_nNumberOfRows)
{
return NULL;
}
CCListViewCell *cell = cellAtRow(nRow);
if (cell == NULL)
{
cell = triggerCellForRow(nRow);
if (cell)
{
CCSize size = this->getContentSize();
CCSize cellSize = cell->getContentSize();
float pos;
unsigned int nLastRow = CCRange::CCMaxRange(m_drawedRows);
CCListViewCell *lastCell = cellAtRow(nLastRow);
if (lastCell)
{
if (m_nMode == CCListViewModeHorizontal)
{
pos = lastCell->getPosition().x + lastCell->getContentSize().width;
cell->setPosition(CCPointMake(pos, 0));
cell->setContentSize(CCSizeMake(cellSize.width, size.height));
}
else if (m_nMode == CCListViewModeVertical)
{
pos = lastCell->getPosition().y - cell->getContentSize().height;
cell->setPosition(CCPointMake(0, pos));
cell->setContentSize(CCSizeMake(size.width, cellSize.height));
}
if (nRow == m_nSelectedRow)
{
cell->selected();
}
m_layerPanel->addChild(cell, nRow, nRow);
if (nRow > CCRange::CCMaxRange(m_drawedRows))
{
cell->setSeparatorStyle(CCListViewCellSeparatorStyleNone);
lastCell->setSeparatorStyle(m_nSeparatorStyle);
m_drawedRows.length += nRow - CCRange::CCMaxRange(m_drawedRows);
}
else
{
cell->setSeparatorStyle(m_nSeparatorStyle);
}
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
return cell;
}
CCListViewCell* CCListView::appendRowToFront(unsigned int nRow)
{
CCListViewCell *cell = cellAtRow(nRow);
if (cell == NULL)
{
cell = triggerCellForRow(nRow);
if (cell)
{
CCSize size = this->getContentSize();
CCSize cellSize = cell->getContentSize();
float pos;
unsigned int nFirstRow = m_drawedRows.location;
CCListViewCell *firstCell = cellAtRow(nFirstRow);
if (firstCell)
{
if (m_nMode == CCListViewModeHorizontal)
{
pos = firstCell->getPosition().x - cell->getContentSize().width;
cell->setPosition(CCPointMake(pos, 0));
cell->setContentSize(CCSizeMake(cellSize.width, size.height));
}
else if (m_nMode == CCListViewModeVertical)
{
pos = firstCell->getPosition().y + firstCell->getContentSize().height;
cell->setPosition(CCPointMake(0, pos));
cell->setContentSize(CCSizeMake(size.width, cellSize.height));
}
cell->setSeparatorStyle(m_nSeparatorStyle);
if (nRow == m_nSelectedRow)
{
cell->selected();
}
m_layerPanel->addChild(cell, nRow, nRow);
if (nRow < m_drawedRows.location)
{
m_drawedRows.length += m_drawedRows.location - nRow;
m_drawedRows.location = nRow;
}
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
else
{
CCLog("CCListView cell == NULL at line %d", __LINE__);
}
}
return cell;
}
// <20><><EFBFBD><EFBFBD>ĩ<EFBFBD><C4A9>
void CCListView::fixFirstRow(void)
{
unsigned int location = m_drawedRows.location;
CCListViewCell *cell = cellAtRow(location);
if (cell)
{
float disX = 0;
float disY = 0;
CCPoint posCell = cell->convertToWorldSpace(CCPointZero);
CCPoint posView = this->convertToWorldSpace(CCPointZero);
if (CCListViewModeHorizontal == m_nMode)
{
float dis = posCell.x - posView.x;
dis = -dis;
disX = dis;
disY = 0;
}
else if (CCListViewModeVertical == m_nMode)
{
float dis = posCell.y + cell->getContentSize().height - (posView.y + this->getContentSize().height);
dis = -dis;
disX = 0;
disY = dis;
}
m_nState = CCListViewStateFix;
CCMoveBy *moveBy = CCMoveBy::actionWithDuration(m_fActionDuration, CCPointMake(disX, disY));
CCEaseInOut *ease = CCEaseInOut::actionWithAction(moveBy, 2);
CCFiniteTimeAction *actions = CCSequence::actions(ease, CCCallFunc::actionWithTarget(this, callfunc_selector(CCListView::finishFix)), NULL);
m_layerPanel->runAction(actions);
}
else
{
this->finishFix();
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void CCListView::fixLastRow(void)
{
unsigned int nLastRow = CCRange::CCMaxRange(m_drawedRows);
CCListViewCell *cell = cellAtRow(nLastRow);
if (cell)
{
float disX = 0;
float disY = 0;
CCPoint posCell = cell->convertToWorldSpace(CCPointZero);
CCPoint posView = this->convertToWorldSpace(CCPointZero);
if (CCListViewModeHorizontal == m_nMode)
{
float dis = posCell.x + cell->getContentSize().width - (posView.x + this->getContentSize().width);
dis = -dis;
disX = dis;
disY = 0;
}
else if (CCListViewModeVertical == m_nMode)
{
float dis = posCell.y - posView.y;
dis = -dis;
disX = 0;
disY = dis;
}
m_nState = CCListViewStateFix;
CCMoveBy *moveBy = CCMoveBy::actionWithDuration(m_fActionDuration, CCPointMake(disX, disY));
CCEaseInOut *ease = CCEaseInOut::actionWithAction(moveBy, 2);
CCFiniteTimeAction *actions = CCSequence::actions(ease, CCCallFunc::actionWithTarget(this, callfunc_selector(CCListView::finishFix)), NULL);
m_layerPanel->runAction(actions);
}
else
{
finishFix();
}
}
// <20><><EFBFBD>ƻ<EFBFBD><C6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6A3AC><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>
void CCListView::easeOutWithDistance(float dis)
{
float disX = 0;
float disY = 0;
if (CCListViewModeHorizontal == m_nMode)
{
if (CCListViewSlideDirLeft == m_nSlideDir)
{
// drag Left
while(1)
{
unsigned int nLastRow = CCRange::CCMaxRange(m_drawedRows);
CCListViewCell *cell = cellAtRow(nLastRow);
if (cell)
{
CCPoint ptCell = cell->convertToWorldSpace(CCPointZero);
CCPoint ptView = this->convertToWorldSpace(CCPointZero);
if (nLastRow < m_nNumberOfRows - 1)
{
float offset = ptView.x + this->getContentSize().width - (ptCell.x + cell->getContentSize().width);
if (offset > dis)
{
appendRowToBack(nLastRow + 1);
}
else
{
dis = offset;
break;
}
}
else
{
// already is the last row
float leftMin = cell->getContentSize().width / 5;
float offset = ptCell.x + cell->getContentSize().width + dis - ptView.x;
if (offset < -leftMin)
{
dis = ptView.x + leftMin - (ptCell.x + cell->getContentSize().width);
}
offset = ptCell.x + cell->getContentSize().width + dis - (ptView.x + this->getContentSize().width) ;
if (offset > 0)
{
dis = ptView.x + this->getContentSize().width - (ptCell.x + cell->getContentSize().width);
}
break;
}
}
else
{
break;
}
}
}
else
{
// drag right
while(1)
{
unsigned int nFirstRow = m_drawedRows.location;
CCListViewCell *cell = cellAtRow(nFirstRow);
if (cell)
{
CCPoint ptCell = cell->convertToWorldSpace(CCPointZero);
CCPoint ptView = this->convertToWorldSpace(CCPointZero);
if (nFirstRow > 0)
{
float offset = ptView.x - ptCell.x;
if (offset < dis)
{
appendRowToFront(nFirstRow - 1);
}
else
{
dis = offset;
break;
}
}
else
{
// already is the first row
float leftMin = cell->getContentSize().width / 5;
float offset = ptCell.x + dis - (ptView.x + this->getContentSize().width);
if (offset > leftMin)
{
dis = ptView.x + this->getContentSize().width - leftMin - ptCell.x;
}
offset = ptView.x - ptCell.x;
if (offset > 0)
{
dis = offset;
}
break;
}
}
else
{
}
}
}
disX = dis;
disY = 0;
}
else if (CCListViewModeVertical == m_nMode)
{
if (CCListViewSlideDirUp == m_nSlideDir)
{
// drag up
while(1)
{
unsigned int nLastRow = CCRange::CCMaxRange(m_drawedRows);
CCListViewCell *cell = cellAtRow(nLastRow);
if (cell)
{
CCPoint ptCell = cell->convertToWorldSpace(CCPointZero);
CCPoint ptView = this->convertToWorldSpace(CCPointZero);
if (nLastRow < m_nNumberOfRows - 1)
{
float offset = ptView.y - ptCell.y;
if (offset < dis)
{
appendRowToBack(nLastRow + 1);
}
else
{
dis = offset;
break;
}
}
else
{
// already is the last row
m_fActionDuration *= 0.5;
float leftMin = cell->getContentSize().height / 5;
float offset = ptCell.y + dis - (ptView.y + this->getContentSize().height);
if (offset > -leftMin)
{
dis = ptView.y + this->getContentSize().height - leftMin - ptCell.y;
}
break;
}
}
else
{
break;
}
}
}
else
{
// drag down
while(1)
{
unsigned int nFirstRow = m_drawedRows.location;
CCListViewCell *cell = cellAtRow(nFirstRow);
if (cell)
{
CCPoint ptCell = cell->convertToWorldSpace(CCPointZero);
CCPoint ptView = this->convertToWorldSpace(CCPointZero);
if (nFirstRow > 0)
{
float offset = ptView.y + this->getContentSize().height - (ptCell.y + cell->getContentSize().height);
if (offset > dis)
{
appendRowToFront(nFirstRow - 1);
}
else
{
dis = offset;
break;
}
}
else
{
// already is the first row
m_fActionDuration *= 0.5;
float leftMin = cell->getContentSize().height / 5;
float offset = ptCell.y + cell->getContentSize().height + dis - ptView.y;
if (offset < leftMin)
{
dis = ptView.y + leftMin - (ptCell.y + cell->getContentSize().height);
}
break;
}
}
else
{
}
}
}
disX = 0;
disY = dis;
}
m_nState = CCListViewStateEaseOut;
CCMoveBy *moveBy = CCMoveBy::actionWithDuration(m_fActionDuration, CCPointMake(disX, disY));
CCEaseOut *ease = CCEaseOut::actionWithAction(moveBy, 3);
CCFiniteTimeAction *actions = CCSequence::actions(ease, CCCallFunc::actionWithTarget(this, callfunc_selector(CCListView::finishEaseOut)), NULL);
m_layerPanel->runAction(actions);
}
void CCListView::clearUnvisibleRows(void)
{
CCRange oldRange = m_drawedRows;
for (unsigned int i = oldRange.location; i < oldRange.location + oldRange.length; i++)
{
CCListViewCell *cell = cellAtRow(i);
if (cell)
{
CCPoint posCell = cell->convertToWorldSpace(CCPointZero);
CCPoint posView = this->convertToWorldSpace(CCPointZero);
if (CCListViewModeHorizontal == m_nMode)
{
if (posCell.x + cell->getContentSize().width <= posView.x)
{
m_layerPanel->removeChild(cell, true);
}
else
{
break;
}
}
else if (CCListViewModeVertical == m_nMode)
{
if (posCell.y >= posView.y + this->getContentSize().height)
{
m_layerPanel->removeChild(cell, true);
}
else
{
break;
}
}
}
m_drawedRows.location++;
m_drawedRows.length--;
}
oldRange = m_drawedRows;
for (int i = oldRange.location + oldRange.length - 1; i >= (int)oldRange.location; i--)
{
CCListViewCell *cell = cellAtRow(i);
if (cell)
{
CCPoint posCell = cell->convertToWorldSpace(CCPointZero);
CCPoint posView = this->convertToWorldSpace(CCPointZero);
if (CCListViewModeHorizontal == m_nMode)
{
if (posCell.x >= posView.x + this->getContentSize().width)
{
m_layerPanel->removeChild(cell, true);
}
else
{
break;
}
}
else if (CCListViewModeVertical == m_nMode)
{
if (posCell.y + cell->getContentSize().height <= posView.y)
{
m_layerPanel->removeChild(cell, true);
}
else
{
break;
}
}
}
m_drawedRows.length--;
}
m_visibleRows = m_drawedRows;
}
/******************************************
**************Virturl Functions************
*******************************************/
void CCListView::registerWithTouchDispatcher()
{
CCDirector* pDirector = CCDirector::sharedDirector();
if (m_pListViewParent)
{
pDirector->getTouchDispatcher()->addTargetedDelegate(this, kCCMenuHandlerPriority - 1, false);
}
else
{
pDirector->getTouchDispatcher()->addTargetedDelegate(this, kCCMenuHandlerPriority - 2, false);
}
}
void CCListView::onEnter(void)
{
if (0 == m_nNumberOfRows)
{
m_layerPanel->setPosition(CCPointZero);
m_layerPanel->setContentSize(this->getContentSize());
// get number of rows
m_nNumberOfRows = triggerNumberOfCells();
displayVisibleRows();
}
CCLayerColor::onEnter();
}
void CCListView::onExit(void)
{
CCLayerColor::onExit();
}
void CCListView::visit(void)
{
if (!m_pListViewParent)
{
CCRect rectSelf;
float factor = CC_CONTENT_SCALE_FACTOR();
rectSelf.origin = convertToWorldSpace(CCPoint(0,0));
rectSelf.origin.x *= factor;
rectSelf.origin.y *= factor;
rectSelf.size = this->getContentSize();
rectSelf.size.width *= factor;
rectSelf.size.height *= factor;
glScissor((GLsizei)rectSelf.origin.x, (GLsizei)rectSelf.origin.y, (GLsizei)rectSelf.size.width , (GLsizei)rectSelf.size.height);
glEnable(GL_SCISSOR_TEST);
}
CCLayerColor::visit();
if (!m_pListViewParent)
{
glDisable(GL_SCISSOR_TEST);
}
}
bool CCListView::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
CC_UNUSED_PARAM(event);
if (!isTouchInside(touch) || !getIsVisible() || !m_bIsEnabled)
{
return false;
}
if (m_pListViewParent && CCListViewSlideDirNone != m_pListViewParent->getSlideDir())
{
return false;
}
CCArray *children = this->getChildren();
if (!m_bIsVisible || !children || children->count() == 0)
{
return false;
}
if (m_bIsOnTouch)
{
return false;
}
CCPoint touchPoint = touch->locationInView();
m_ptTouchBegan = m_ptTouchEnd = CCDirector::sharedDirector()->convertToGL(touchPoint);
m_ptPanelOffset = m_layerPanel->getPosition();
m_timeTouchBegan = clock();
m_nCurrentRow = this->rowForTouch(touch);
if (m_nCurrentRow != -1)
{
if (CCListViewStateWatting != m_nState)
{
stopActionImmediately();
}
m_nState = CCListViewStateTrackingTouch;
if (CCListViewSlideDirNone == m_nSlideDir)
{
this->selectCellAtRow(m_nCurrentRow);
}
else
{
m_nCurrentRow = -1;
}
m_bIsOnTouch = true;
return true;
}
return false;
}
void CCListView::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
CC_UNUSED_PARAM(event);
if (CCListViewStateTrackingTouch != m_nState || !isTouchInside(touch) || !m_bIsEnabled)
{
return;
}
CCPoint touchPoint = touch->locationInView();
m_ptTouchEnd = CCDirector::sharedDirector()->convertToGL(touchPoint);
CCListViewSlideDir nsliderDir = CCListViewSlideDirNone;
if (m_pListViewParent && CCListViewSlideDirNone != m_pListViewParent->getSlideDir(m_ptTouchBegan, m_ptTouchEnd))
{
return;
}
else
{
nsliderDir = getSlideDir(m_ptTouchBegan, m_ptTouchEnd);
}
if(CCListViewModeHorizontal == m_nMode && CCListViewSlideDirNone != nsliderDir)
{
m_nSlideDir = nsliderDir;
m_layerPanel->setPosition(CCPointMake(m_ptPanelOffset.x + (m_ptTouchEnd.x - m_ptTouchBegan.x),m_ptPanelOffset.y));
if (CCListViewSlideDirLeft == m_nSlideDir)
{
// drag left
unsigned int nLastRow = CCRange::CCMaxRange(m_drawedRows);
if (nLastRow < m_nNumberOfRows - 1)
{
CCListViewCell *cell = cellAtRow(nLastRow);
if (cell)
{
CCPoint posCell = cell->convertToWorldSpace(CCPointZero);
CCPoint posView = this->convertToWorldSpace(CCPointZero);
if (posCell.x + cell->getContentSize().width <= posView.x + this->getContentSize().width)
{
appendRowToBack(nLastRow + 1);
}
}
}
}
else
{
// drag right
unsigned int nFirstRow = m_drawedRows.location;
if (nFirstRow > 0)
{
CCListViewCell *cell = cellAtRow(nFirstRow);
CCPoint posCell = cell->convertToWorldSpace(CCPointZero);
CCPoint posView = this->convertToWorldSpace(CCPointZero);
if (posCell.x >= posView.x)
{
appendRowToFront(nFirstRow - 1);
}
}
}
}
else if (CCListViewModeVertical == m_nMode && CCListViewSlideDirNone != nsliderDir)
{
m_nSlideDir = nsliderDir;
m_layerPanel->setPosition(CCPointMake(m_ptPanelOffset.x, m_ptPanelOffset.y + (m_ptTouchEnd.y - m_ptTouchBegan.y)));
if (CCListViewSlideDirUp == m_nSlideDir)
{
// drag up
unsigned int nLastRow = CCRange::CCMaxRange(m_drawedRows);
if (nLastRow < m_nNumberOfRows - 1)
{
CCListViewCell *cell = cellAtRow(nLastRow);
CCPoint posCell = cell->convertToWorldSpace(CCPointZero);
CCPoint posView = this->convertToWorldSpace(CCPointZero);
if (posCell.y >= posView.y)
{
appendRowToBack(nLastRow + 1);
}
}
}
else
{
// drag down
unsigned int nFirstRow = m_drawedRows.location;
if (nFirstRow > 0)
{
CCListViewCell *cell = cellAtRow(nFirstRow);
CCPoint posCell = cell->convertToWorldSpace(CCPointZero);
CCPoint posView = this->convertToWorldSpace(CCPointZero);
if (posCell.y + cell->getContentSize().height <= posView.y + this->getContentSize().height)
{
appendRowToFront(nFirstRow - 1);
}
}
}
}
if (CCListViewSlideDirNone != m_nSlideDir && m_nCurrentRow != -1 && m_nCurrentRow != m_nSelectedRow)
{
this->unselectCellAtRow(m_nCurrentRow);
}
if (CCListViewSlideDirNone != m_nSlideDir && m_pListViewParent)
{
m_pListViewParent->setIsEnabled(false);
}
}
void CCListView::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
CC_UNUSED_PARAM(touch);
CC_UNUSED_PARAM(event);
if(m_nState != CCListViewStateTrackingTouch || !m_bIsEnabled)
{
m_bIsOnTouch = false;
return;
}
m_fActionDuration = ND_LISTVIEW_ACTION_INTERVAL;
clock_t timeElapse = clock() - m_timeTouchBegan;
#if CC_TARGET_PLATFORM != CC_PLATFORM_WIN32 && CC_TARGET_PLATFORM != CC_PLATFORM_MAC
// <20>ֻ<EFBFBD>ƽ̨<C6BD><CCA8>ʱ<EFBFBD>ϳ<EFBFBD><CFB3><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>ݲ<EFBFBD>ͬƽ̨<C6BD><CCA8><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
timeElapse /= 200;
#endif
if(CCListViewSlideDirLeft == m_nSlideDir || CCListViewSlideDirRight == m_nSlideDir)
{
float dis = m_ptTouchEnd.x - m_ptTouchBegan.x;
float speed = dis / timeElapse;
if (fabs(speed) > 0.1 && timeElapse < 300)
{
easeOutWithDistance(dis * 3);
}
else
{
if (CCListViewSlideDirLeft == m_nSlideDir && isFullFill())
{
// drag up
fixLastRow();
}
else
{
// drag down
fixFirstRow();
}
}
}
else if (CCListViewSlideDirUp == m_nSlideDir || CCListViewSlideDirDown == m_nSlideDir)
{
float dis = m_ptTouchEnd.y - m_ptTouchBegan.y;
float speed = dis / timeElapse;
if (fabs(speed) > 0.1 && timeElapse < 300)
{
easeOutWithDistance(dis * 3);
}
else
{
if (CCListViewSlideDirUp == m_nSlideDir && isFullFill())
{
// drag up
fixLastRow();
}
else
{
// drag down
fixFirstRow();
}
}
}
else
{
finishFix();
}
int currentRow = this->rowForTouch(touch);
if (currentRow != -1 && isTouchInside(touch))
{
if (currentRow == m_nCurrentRow)
{
if (CCListViewSlideDirNone == m_nSlideDir)
{
if (m_pListViewParent == NULL || (m_pListViewParent && CCListViewSlideDirNone == m_pListViewParent->getSlideDir()))
{
if (m_nSelectedRow != -1 && m_nSelectedRow != m_nCurrentRow)
{
this->unselectCellAtRow(m_nSelectedRow);
}
m_nSelectedRow = m_nCurrentRow;
if (!this->isMenuTouch(touch, this->cellAtRow(m_nSelectedRow)))
{
triggerDidClickCellAtRow(m_nSelectedRow);
}
}
}
else
{
if (m_nSelectedRow != m_nCurrentRow)
{
this->unselectCellAtRow(m_nCurrentRow);
}
}
}
else
{
if (-1 != m_nCurrentRow)
{
this->unselectCellAtRow(m_nCurrentRow);
}
}
}
else
{
if (-1 != m_nCurrentRow)
{
this->unselectCellAtRow(m_nCurrentRow);
m_nCurrentRow = -1;
}
}
m_bIsOnTouch = false;
}
bool CCListView::isMenuTouch(CCTouch *touch, CCNode *parent)
{
if (dynamic_cast<CCMenuItem*>(parent))
{
CCPoint touchPoint = touch->locationInView();
touchPoint.y = cocos2d::CCDirector::sharedDirector()->getWinSize().height - touchPoint.y;
touchPoint = parent->convertToNodeSpace(touchPoint);
CCRect rect = CCRectZero;
rect.size = parent->getContentSize();
return CCRect::CCRectContainsPoint(rect, touchPoint);
}
else
{
CCArray *pChildrens = parent->getChildren();
if (pChildrens && pChildrens->count() > 0)
{
for (int i = 0; i < pChildrens->count(); i++)
{
CCNode *pChildren = (CCNode*)pChildrens->objectAtIndex(i);
if (this->isMenuTouch(touch, pChildren))
{
return true;
}
}
}
}
return false;
}
void CCListView::ccTouchCancelled(CCTouch *touch, CCEvent *event)
{
CC_UNUSED_PARAM(touch);
CC_UNUSED_PARAM(event);
CCAssert(m_nState == CCListViewStateTrackingTouch, "[NdListview ccTouchCancelled] -- invalid state");
finishFix();
m_bIsOnTouch = false;
}
NS_CC_EXT_END