mirror of https://github.com/axmolengine/axmol.git
1458 lines
45 KiB
C++
1458 lines
45 KiB
C++
/****************************************************************************
|
|
Copyright (c) 2013 cocos2d-x.org
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
****************************************************************************/
|
|
|
|
#include "UIListView.h"
|
|
|
|
NS_CC_EXT_BEGIN
|
|
|
|
UIListView::UIListView()
|
|
: _direction(LISTVIEW_DIR_VERTICAL)
|
|
, _moveDirection(LISTVIEW_MOVE_DIR_NONE)
|
|
, _touchStartLocation(0.0f)
|
|
, _touchEndLocation(0.0f)
|
|
, _touchMoveStartLocation(0.0f)
|
|
, _topBoundary(0.0f)
|
|
, _bottomBoundary(0.0f)
|
|
, _leftBoundary(0.0f)
|
|
, _rightBoundary(0.0f)
|
|
, _autoScroll(false)
|
|
, _autoScrollOriginalSpeed(0.0f)
|
|
, _autoScrollAcceleration(600.0f)
|
|
, _bePressed(false)
|
|
, _slidTime(0.0f)
|
|
, _childFocusCancelOffset(5.0f)
|
|
, _eventListener(NULL)
|
|
, _eventSelector(NULL)
|
|
, _childPool(NULL)
|
|
, _updatePool(NULL)
|
|
, _dataLength(0)
|
|
, _begin(0)
|
|
, _end(0)
|
|
, _updateChild(NULL)
|
|
, _updateDataIndex(-1)
|
|
, _updateSuccess(false)
|
|
, _overTopArray(NULL)
|
|
, _overBottomArray(NULL)
|
|
, _overLeftArray(NULL)
|
|
, _overRightArray(NULL)
|
|
, _disBoundaryToChild_0(0.0f)
|
|
, _disBetweenChild(0.0f)
|
|
, _scrollDegreeRange(45.0f)
|
|
{
|
|
}
|
|
|
|
UIListView::~UIListView()
|
|
{
|
|
CC_SAFE_RELEASE_NULL(_childPool);
|
|
CC_SAFE_RELEASE_NULL(_updatePool);
|
|
CC_SAFE_RELEASE_NULL(_overTopArray);
|
|
CC_SAFE_RELEASE_NULL(_overBottomArray);
|
|
CC_SAFE_RELEASE_NULL(_overLeftArray);
|
|
CC_SAFE_RELEASE_NULL(_overRightArray);
|
|
}
|
|
|
|
UIListView* UIListView::create()
|
|
{
|
|
UIListView* widget = new UIListView();
|
|
if (widget && widget->init())
|
|
{
|
|
widget->autorelease();
|
|
return widget;
|
|
}
|
|
CC_SAFE_DELETE(widget);
|
|
return NULL;
|
|
}
|
|
|
|
bool UIListView::init()
|
|
{
|
|
if (Layout::init())
|
|
{
|
|
setUpdateEnabled(true);
|
|
setTouchEnabled(true);
|
|
setClippingEnabled(true);
|
|
|
|
_childPool = CCArray::create();
|
|
_updatePool = CCArray::create();
|
|
CC_SAFE_RETAIN(_childPool);
|
|
CC_SAFE_RETAIN(_updatePool);
|
|
_overTopArray = cocos2d::CCArray::create();
|
|
_overBottomArray = cocos2d::CCArray::create();
|
|
_overLeftArray = cocos2d::CCArray::create();
|
|
_overRightArray = cocos2d::CCArray::create();
|
|
CC_SAFE_RETAIN(_overTopArray);
|
|
CC_SAFE_RETAIN(_overBottomArray);
|
|
CC_SAFE_RETAIN(_overLeftArray);
|
|
CC_SAFE_RETAIN(_overRightArray);
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void UIListView::onSizeChanged()
|
|
{
|
|
Layout::onSizeChanged();
|
|
_topBoundary = _size.height;
|
|
_rightBoundary = _size.width;
|
|
}
|
|
|
|
bool UIListView::addChild(UIWidget* widget)
|
|
{
|
|
Layout::addChild(widget);
|
|
resetProperty();
|
|
return true;
|
|
}
|
|
|
|
void UIListView::removeAllChildren()
|
|
{
|
|
_updatePool->removeAllObjects();
|
|
_childPool->removeAllObjects();
|
|
Layout::removeAllChildren();
|
|
}
|
|
|
|
bool UIListView::removeChild(UIWidget* child)
|
|
{
|
|
bool value = false;
|
|
|
|
if (Layout::removeChild(child))
|
|
{
|
|
value = true;
|
|
resetProperty();
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
bool UIListView::onTouchBegan(const Point &touchPoint)
|
|
{
|
|
bool pass = Layout::onTouchBegan(touchPoint);
|
|
handlePressLogic(touchPoint);
|
|
return pass;
|
|
}
|
|
|
|
void UIListView::onTouchMoved(const Point &touchPoint)
|
|
{
|
|
Layout::onTouchMoved(touchPoint);
|
|
handleMoveLogic(touchPoint);
|
|
}
|
|
|
|
void UIListView::onTouchEnded(const Point &touchPoint)
|
|
{
|
|
Layout::onTouchEnded(touchPoint);
|
|
handleReleaseLogic(touchPoint);
|
|
}
|
|
|
|
void UIListView::onTouchCancelled(const Point &touchPoint)
|
|
{
|
|
Layout::onTouchCancelled(touchPoint);
|
|
}
|
|
|
|
void UIListView::onTouchLongClicked(const Point &touchPoint)
|
|
{
|
|
|
|
}
|
|
|
|
void UIListView::update(float dt)
|
|
{
|
|
if (_autoScroll)
|
|
{
|
|
autoScrollChildren(dt);
|
|
}
|
|
recordSlidTime(dt);
|
|
}
|
|
|
|
void UIListView::setDirection(ListViewDirection dir)
|
|
{
|
|
_direction = dir;
|
|
}
|
|
|
|
ListViewDirection UIListView::getDirection()
|
|
{
|
|
return _direction;
|
|
}
|
|
|
|
void UIListView::resetProperty()
|
|
{
|
|
ccArray* arrayChildren = _children->data;
|
|
|
|
if (arrayChildren->num <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
if (_topBoundary == 0)
|
|
{
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
if (_rightBoundary == 0)
|
|
{
|
|
return;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
float scroll_top = _topBoundary;
|
|
float scroll_left = _leftBoundary;
|
|
|
|
switch (_children->count())
|
|
{
|
|
case 1:
|
|
{
|
|
UIWidget* child_0 = dynamic_cast<UIWidget*>(arrayChildren->arr[0]);
|
|
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
{
|
|
float child_0_top = child_0->getTopInParent();
|
|
_disBoundaryToChild_0 = scroll_top - child_0_top;
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
{
|
|
float child_0_left = child_0->getLeftInParent();
|
|
_disBoundaryToChild_0 = child_0_left - scroll_left;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
UIWidget* child_0 = dynamic_cast<UIWidget*>(arrayChildren->arr[0]);
|
|
UIWidget* child_1 = dynamic_cast<UIWidget*>(arrayChildren->arr[1]);
|
|
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
{
|
|
float child_0_top = child_0->getTopInParent();
|
|
_disBoundaryToChild_0 = scroll_top - child_0_top;
|
|
_disBetweenChild = child_0->getPosition().y - child_1->getPosition().y;
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
{
|
|
float child_0_left = child_0->getLeftInParent();
|
|
_disBoundaryToChild_0 = child_0_left - scroll_left;
|
|
_disBetweenChild = child_1->getPosition().x - child_0->getPosition().x;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void UIListView::handlePressLogic(const Point &touchPoint)
|
|
{
|
|
Point nsp = _renderer->convertToNodeSpace(touchPoint);
|
|
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
_touchMoveStartLocation = nsp.y;
|
|
_touchStartLocation = nsp.y;
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
_touchMoveStartLocation = nsp.x;
|
|
_touchStartLocation = nsp.x;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
startRecordSlidAction();
|
|
clearCollectOverArray();
|
|
}
|
|
|
|
void UIListView::handleMoveLogic(const Point &touchPoint)
|
|
{
|
|
Point nsp = _renderer->convertToNodeSpace(touchPoint);
|
|
float offset = 0.0f;
|
|
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
{
|
|
float moveY = nsp.y;
|
|
offset = moveY - _touchMoveStartLocation;
|
|
_touchMoveStartLocation = moveY;
|
|
|
|
if (offset < 0.0f)
|
|
{
|
|
_moveDirection = LISTVIEW_MOVE_DIR_DOWN; // down
|
|
}
|
|
else if (offset > 0.0f)
|
|
{
|
|
_moveDirection = LISTVIEW_MOVE_DIR_UP; // up
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
{
|
|
float moveX = nsp.x;
|
|
offset = moveX - _touchMoveStartLocation;
|
|
_touchMoveStartLocation = moveX;
|
|
|
|
if (offset < 0)
|
|
{
|
|
_moveDirection = LISTVIEW_MOVE_DIR_LEFT; // left
|
|
}
|
|
else if (offset > 0)
|
|
{
|
|
_moveDirection = LISTVIEW_MOVE_DIR_RIGHT; // right
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
scrollChildren(offset);
|
|
}
|
|
|
|
void UIListView::handleReleaseLogic(const Point &touchPoint)
|
|
{
|
|
Point nsp = _renderer->convertToNodeSpace(touchPoint);
|
|
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
_touchEndLocation = nsp.y;
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
_touchEndLocation = nsp.x;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
endRecordSlidAction();
|
|
}
|
|
|
|
void UIListView::interceptTouchEvent(int handleState, UIWidget *sender, const Point &touchPoint)
|
|
{
|
|
switch (handleState)
|
|
{
|
|
case 0:
|
|
handlePressLogic(touchPoint);
|
|
break;
|
|
|
|
case 1:
|
|
{
|
|
float offset = 0;
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
offset = fabs(sender->getTouchStartPos().y - touchPoint.y);
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
offset = fabs(sender->getTouchStartPos().x - touchPoint.x);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
if (offset > _childFocusCancelOffset)
|
|
{
|
|
sender->setFocused(false);
|
|
handleMoveLogic(touchPoint);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
handleReleaseLogic(touchPoint);
|
|
break;
|
|
|
|
case 3:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void UIListView::checkChildInfo(int handleState,UIWidget* sender,const Point &touchPoint)
|
|
{
|
|
interceptTouchEvent(handleState, sender, touchPoint);
|
|
}
|
|
|
|
void UIListView::moveChildren(float offset)
|
|
{
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
{
|
|
ccArray* arrayChildren = _children->data;
|
|
int childrenCount = arrayChildren->num;
|
|
for (int i = 0; i < childrenCount; i++)
|
|
{
|
|
UIWidget* child = (UIWidget*)(arrayChildren->arr[i]);
|
|
_moveChildPoint.x = child->getPosition().x;
|
|
_moveChildPoint.y = child->getPosition().y + offset;
|
|
child->setPosition(_moveChildPoint);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
{
|
|
ccArray* arrayChildren = _children->data;
|
|
int childrenCount = arrayChildren->num;
|
|
for (int i=0;i<childrenCount;i++)
|
|
{
|
|
UIWidget* child = (UIWidget*)(arrayChildren->arr[i]);
|
|
_moveChildPoint.x = child->getPosition().x + offset;
|
|
_moveChildPoint.y = child->getPosition().y;
|
|
child->setPosition(_moveChildPoint);
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool UIListView::scrollChildren(float touchOffset)
|
|
{
|
|
float realOffset = touchOffset;
|
|
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_UP: // up
|
|
{
|
|
realOffset = MIN(realOffset, _disBetweenChild);
|
|
|
|
UIWidget* child_last = dynamic_cast<UIWidget*>(_childPool->getLastObject());
|
|
float child_last_bottom = child_last->getBottomInParent();
|
|
float scroll_bottom = _bottomBoundary;
|
|
|
|
if (_end == _dataLength - 1)
|
|
{
|
|
if (realOffset > scroll_bottom + _disBoundaryToChild_0 - child_last_bottom)
|
|
{
|
|
realOffset = scroll_bottom + _disBoundaryToChild_0 - child_last_bottom;
|
|
}
|
|
moveChildren(realOffset);
|
|
return false;
|
|
}
|
|
moveChildren(realOffset);
|
|
|
|
if (_end < _dataLength - 1)
|
|
{
|
|
collectOverTopChild();
|
|
unsigned int count = _overTopArray->count();
|
|
if (count > 0)
|
|
{
|
|
updateChild();
|
|
setLoopPosition();
|
|
_overTopArray->removeAllObjects();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_DOWN: // down
|
|
{
|
|
realOffset = MAX(realOffset, -_disBetweenChild);
|
|
|
|
UIWidget* child_0 = dynamic_cast<UIWidget*>(_childPool->getObjectAtIndex(0));
|
|
float child_0_top = child_0->getTopInParent();
|
|
float scroll_top = _topBoundary;
|
|
|
|
if (_begin == 0)
|
|
{
|
|
if (realOffset < scroll_top - _disBoundaryToChild_0 - child_0_top)
|
|
{
|
|
realOffset = scroll_top - _disBoundaryToChild_0 - child_0_top;
|
|
}
|
|
moveChildren(realOffset);
|
|
return false;
|
|
}
|
|
moveChildren(realOffset);
|
|
|
|
if (_begin > 0)
|
|
{
|
|
collectOverBottomChild();
|
|
int count = _overBottomArray->count();
|
|
if (count > 0)
|
|
{
|
|
updateChild();
|
|
setLoopPosition();
|
|
_overBottomArray->removeAllObjects();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return true;
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_LEFT: // left
|
|
{
|
|
realOffset = MAX(realOffset, -_disBetweenChild);
|
|
|
|
UIWidget* child_last = dynamic_cast<UIWidget*>(_childPool->getLastObject());
|
|
float child_last_right = child_last->getRightInParent();
|
|
float scroll_right = _rightBoundary;
|
|
|
|
if (_end == _dataLength - 1)
|
|
{
|
|
if (realOffset < scroll_right - _disBoundaryToChild_0 - child_last_right)
|
|
{
|
|
realOffset = scroll_right - _disBoundaryToChild_0 - child_last_right;
|
|
}
|
|
moveChildren(realOffset);
|
|
return false;
|
|
}
|
|
moveChildren(realOffset);
|
|
|
|
if (_end < _dataLength - 1)
|
|
{
|
|
collectOverLeftChild();
|
|
int count = _overLeftArray->count();
|
|
if (count > 0)
|
|
{
|
|
updateChild();
|
|
setLoopPosition();
|
|
_overLeftArray->removeAllObjects();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_RIGHT: // right
|
|
{
|
|
realOffset = MIN(realOffset, _disBetweenChild);
|
|
|
|
UIWidget* child_0 = dynamic_cast<UIWidget*>(_childPool->getObjectAtIndex(0));
|
|
float child_0_left = child_0->getLeftInParent();
|
|
float scroll_left = _leftBoundary;
|
|
|
|
if (_begin == 0)
|
|
{
|
|
if (realOffset > scroll_left + _disBoundaryToChild_0 - child_0_left)
|
|
{
|
|
realOffset = scroll_left + _disBoundaryToChild_0 - child_0_left;
|
|
}
|
|
moveChildren(realOffset);
|
|
return false;
|
|
}
|
|
moveChildren(realOffset);
|
|
|
|
collectOverRightChild();
|
|
int count = _overRightArray->count();
|
|
if (count > 0)
|
|
{
|
|
updateChild();
|
|
setLoopPosition();
|
|
_overRightArray->removeAllObjects();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return true;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void UIListView::autoScrollChildren(float dt)
|
|
{
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_UP: // up
|
|
{
|
|
float curDis = getCurAutoScrollDistance(dt);
|
|
if (curDis <= 0)
|
|
{
|
|
curDis = 0;
|
|
stopAutoScrollChildren();
|
|
}
|
|
if (!scrollChildren(curDis))
|
|
{
|
|
stopAutoScrollChildren();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_DOWN: // down
|
|
{
|
|
float curDis = getCurAutoScrollDistance(dt);
|
|
if (curDis <= 0)
|
|
{
|
|
curDis = 0;
|
|
stopAutoScrollChildren();
|
|
}
|
|
if (!scrollChildren(-curDis))
|
|
{
|
|
stopAutoScrollChildren();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_LEFT: // left
|
|
{
|
|
float curDis = getCurAutoScrollDistance(dt);
|
|
if (curDis <= 0)
|
|
{
|
|
curDis = 0;
|
|
stopAutoScrollChildren();
|
|
}
|
|
if (!scrollChildren(-curDis))
|
|
{
|
|
stopAutoScrollChildren();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_RIGHT: // right
|
|
{
|
|
float curDis = getCurAutoScrollDistance(dt);
|
|
if (curDis <= 0)
|
|
{
|
|
curDis = 0;
|
|
stopAutoScrollChildren();
|
|
}
|
|
if (!scrollChildren(curDis))
|
|
{
|
|
stopAutoScrollChildren();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
float UIListView::getCurAutoScrollDistance(float time)
|
|
{
|
|
float dt = time;
|
|
_autoScrollOriginalSpeed -= _autoScrollAcceleration*dt;
|
|
return _autoScrollOriginalSpeed*dt;
|
|
}
|
|
|
|
void UIListView::startAutoScrollChildren(float v)
|
|
{
|
|
_autoScrollOriginalSpeed = v;
|
|
_autoScroll = true;
|
|
}
|
|
|
|
void UIListView::stopAutoScrollChildren()
|
|
{
|
|
_autoScroll = false;
|
|
_autoScrollOriginalSpeed = 0.0f;
|
|
}
|
|
|
|
void UIListView::recordSlidTime(float dt)
|
|
{
|
|
if (_bePressed)
|
|
{
|
|
_slidTime += dt;
|
|
}
|
|
}
|
|
|
|
void UIListView::startRecordSlidAction()
|
|
{
|
|
if (_children->count() <= 0)
|
|
{
|
|
return;
|
|
}
|
|
if (_autoScroll)
|
|
{
|
|
stopAutoScrollChildren();
|
|
}
|
|
_bePressed = true;
|
|
_slidTime = 0.0;
|
|
}
|
|
|
|
void UIListView::endRecordSlidAction()
|
|
{
|
|
if (_children->count() <= 0)
|
|
{
|
|
return;
|
|
}
|
|
if (_slidTime <= 0.016f)
|
|
{
|
|
return;
|
|
}
|
|
float totalDis = 0;
|
|
totalDis = _touchEndLocation-_touchStartLocation;
|
|
float orSpeed = fabs(totalDis)/(_slidTime);
|
|
startAutoScrollChildren(orSpeed / 4);
|
|
|
|
_bePressed = false;
|
|
_slidTime = 0.0;
|
|
}
|
|
|
|
UIWidget* UIListView::getCheckPositionChild()
|
|
{
|
|
UIWidget* child = NULL;
|
|
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_UP: // up
|
|
child = dynamic_cast<UIWidget*>(_childPool->getLastObject());
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_DOWN: // down
|
|
child = dynamic_cast<UIWidget*>(_childPool->getObjectAtIndex(0));
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_LEFT: // left
|
|
child = dynamic_cast<UIWidget*>(_childPool->getLastObject());
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_RIGHT: // right
|
|
child = dynamic_cast<UIWidget*>(_childPool->getObjectAtIndex(0));
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return child;
|
|
}
|
|
|
|
void UIListView::initChildWithDataLength(int length)
|
|
{
|
|
_dataLength = length;
|
|
_begin = 0;
|
|
_end = 0;
|
|
|
|
// init child pool
|
|
ccArray* arrayChildren = _children->data;
|
|
int times = arrayChildren->num;
|
|
for (int i = 0; i < times; ++i)
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]);
|
|
setUpdateChild(child);
|
|
setUpdateDataIndex(i);
|
|
initChildEvent();
|
|
_childPool->addObject(child);
|
|
_end = i;
|
|
}
|
|
}
|
|
|
|
UIWidget* UIListView::getChildFromUpdatePool()
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(_updatePool->getLastObject());
|
|
_updatePool->removeLastObject();
|
|
return child;
|
|
}
|
|
|
|
void UIListView::pushChildToPool()
|
|
{
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_UP: // up
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(_childPool->getObjectAtIndex(0));
|
|
_updatePool->insertObject(child, 0);
|
|
_childPool->removeObjectAtIndex(0);
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_DOWN: // down
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(_childPool->getLastObject());
|
|
_updatePool->insertObject(child, 0);
|
|
_childPool->removeLastObject();
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_LEFT: // left
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(_childPool->getObjectAtIndex(0));
|
|
_updatePool->insertObject(child, 0);
|
|
_childPool->removeObjectAtIndex(0);
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_RIGHT: // right
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(_childPool->getLastObject());
|
|
_updatePool->insertObject(child, 0);
|
|
_childPool->removeLastObject();
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void UIListView::getAndCallback()
|
|
{
|
|
UIWidget* child = getChildFromUpdatePool();
|
|
|
|
if (child == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_UP: // up
|
|
++_end;
|
|
setUpdateChild(child);
|
|
setUpdateDataIndex(_end);
|
|
updateChildEvent();
|
|
|
|
if (_updateSuccess == false)
|
|
{
|
|
--_end;
|
|
_childPool->insertObject(child, 0);
|
|
return;
|
|
}
|
|
++_begin;
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_DOWN: // down
|
|
--_begin;
|
|
setUpdateChild(child);
|
|
setUpdateDataIndex(_begin);
|
|
updateChildEvent();
|
|
|
|
if (_updateSuccess == false)
|
|
{
|
|
++_begin;
|
|
_childPool->addObject(child);
|
|
return;
|
|
}
|
|
--_end;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_LEFT: // left
|
|
++_end;
|
|
setUpdateChild(child);
|
|
setUpdateDataIndex(_end);
|
|
updateChildEvent();
|
|
|
|
if (_updateSuccess == false)
|
|
{
|
|
--_end;
|
|
_childPool->insertObject(child, 0);
|
|
return;
|
|
}
|
|
++_begin;
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_RIGHT: // right
|
|
--_begin;
|
|
setUpdateChild(child);
|
|
setUpdateDataIndex(_begin);
|
|
updateChildEvent();
|
|
|
|
if (_updateSuccess == false)
|
|
{
|
|
++_begin;
|
|
_childPool->addObject(child);
|
|
return;
|
|
}
|
|
--_end;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_UP: // up
|
|
_childPool->addObject(child);
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_DOWN: // down
|
|
_childPool->insertObject(child, 0);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_LEFT: // left
|
|
_childPool->addObject(child);
|
|
break;
|
|
case LISTVIEW_MOVE_DIR_RIGHT: // right
|
|
_childPool->insertObject(child, 0);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
int UIListView::getDataLength()
|
|
{
|
|
return _dataLength;
|
|
}
|
|
|
|
UIWidget* UIListView::getUpdateChild()
|
|
{
|
|
return _updateChild;
|
|
}
|
|
|
|
void UIListView::setUpdateChild(UIWidget* child)
|
|
{
|
|
_updateChild = child;
|
|
}
|
|
|
|
int UIListView::getUpdateDataIndex()
|
|
{
|
|
return _updateDataIndex;
|
|
}
|
|
|
|
void UIListView::setUpdateDataIndex(int index)
|
|
{
|
|
_updateDataIndex = index;
|
|
}
|
|
|
|
bool UIListView::getUpdateSuccess()
|
|
{
|
|
return _updateSuccess;
|
|
}
|
|
|
|
void UIListView::setUpdateSuccess(bool sucess)
|
|
{
|
|
_updateSuccess = sucess;
|
|
}
|
|
|
|
void UIListView::clearCollectOverArray()
|
|
{
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL:
|
|
_overTopArray->removeAllObjects();
|
|
_overBottomArray->removeAllObjects();
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL:
|
|
_overLeftArray->removeAllObjects();
|
|
_overRightArray->removeAllObjects();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void UIListView::collectOverTopChild()
|
|
{
|
|
float scroll_top = _topBoundary;
|
|
|
|
ccArray* arrayChildren = _children->data;
|
|
int times = arrayChildren->num;
|
|
for (int i = 0; i < times; ++i)
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]);
|
|
float child_bottom = child->getBottomInParent();
|
|
|
|
if (child_bottom >= scroll_top)
|
|
{
|
|
_overTopArray->addObject(child);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UIListView::collectOverBottomChild()
|
|
{
|
|
float scroll_bottom = _bottomBoundary;
|
|
|
|
ccArray* arrayChildren = _children->data;
|
|
int times = arrayChildren->num;
|
|
for (int i = 0; i < times; ++i)
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]);
|
|
float child_top = child->getTopInParent();
|
|
|
|
if (child_top <= scroll_bottom)
|
|
{
|
|
_overBottomArray->addObject(child);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UIListView::collectOverLeftChild()
|
|
{
|
|
float scroll_left = _leftBoundary;
|
|
|
|
ccArray* arrayChildren = _children->data;
|
|
int times = arrayChildren->num;
|
|
for (int i = 0; i < times; ++i)
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]);
|
|
float child_right = child->getRightInParent();
|
|
|
|
if (child_right <= scroll_left)
|
|
{
|
|
_overLeftArray->addObject(child);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UIListView::collectOverRightChild()
|
|
{
|
|
float scroll_right = _rightBoundary;
|
|
|
|
ccArray* arrayChildren = _children->data;
|
|
int times = arrayChildren->num;
|
|
for (int i = 0; i < times; ++i)
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]);
|
|
float child_left = child->getLeftInParent();
|
|
if (child_left >= scroll_right)
|
|
{
|
|
_overRightArray->addObject(child);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UIListView::setLoopPosition()
|
|
{
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_UP: // up
|
|
{
|
|
ccArray* arrayChildren = _children->data;
|
|
unsigned int childrenCount = arrayChildren->num;
|
|
|
|
if (_overTopArray->count() == childrenCount)
|
|
{
|
|
unsigned int count = childrenCount;
|
|
for (unsigned int i = 0; i < count; ++i)
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(_overTopArray->getObjectAtIndex(i));
|
|
|
|
if (i == 0)
|
|
{
|
|
float height = child->getSize().height;
|
|
float offset = (child->getWidgetType() == WidgetTypeWidget) ? height / 2 : height;
|
|
float y = _topBoundary - _disBoundaryToChild_0 - offset;
|
|
child->setPosition(Point(child->getPosition().x, y));
|
|
}
|
|
else
|
|
{
|
|
UIWidget* prev_child = dynamic_cast<UIWidget*>(_overTopArray->getObjectAtIndex(i - 1));
|
|
child->setPosition(Point(child->getPosition().x, prev_child->getPosition().y - _disBetweenChild));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float scroll_top = _topBoundary;
|
|
|
|
ccArray* arrayChildren = _children->data;
|
|
int count = arrayChildren->num;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]);
|
|
float child_bottom = child->getBottomInParent();
|
|
|
|
if (child_bottom >= scroll_top)
|
|
{
|
|
int index = (i == 0) ? (count - 1) : (i - 1);
|
|
UIWidget* prev_child = dynamic_cast<UIWidget*>(arrayChildren->arr[index]);
|
|
child->setPosition(Point(child->getPosition().x, prev_child->getPosition().y - _disBetweenChild));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_DOWN: // down
|
|
{
|
|
ccArray* arrayChildren = _children->data;
|
|
unsigned int childrenCount = arrayChildren->num;
|
|
|
|
if (_overBottomArray->count() == childrenCount)
|
|
{
|
|
unsigned int count = childrenCount;
|
|
for (unsigned int i = 0; i < count; ++i)
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(_overBottomArray->getObjectAtIndex(i));
|
|
|
|
if (i == 0)
|
|
{
|
|
float y = _bottomBoundary + _disBoundaryToChild_0 - _disBetweenChild;
|
|
child->setPosition(Point(child->getPosition().x, y));
|
|
}
|
|
else
|
|
{
|
|
UIWidget* prev_child = dynamic_cast<UIWidget*>(_overBottomArray->getObjectAtIndex(i - 1));
|
|
child->setPosition(Point(child->getPosition().x, prev_child->getPosition().y + _disBetweenChild));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float scroll_bottom = _bottomBoundary;
|
|
|
|
ccArray* arrayChildren = _children->data;
|
|
int count = arrayChildren->num;
|
|
for (int i = count - 1; i >= 0; --i)
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]);
|
|
float child_top = child->getTopInParent();
|
|
|
|
if (child_top <= scroll_bottom)
|
|
{
|
|
int index = (i == count - 1) ? 0 : (i + 1);
|
|
UIWidget* next_child = dynamic_cast<UIWidget*>(arrayChildren->arr[index]);
|
|
child->setPosition(Point(child->getPosition().x, next_child->getPosition().y + _disBetweenChild));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_LEFT: // left
|
|
{
|
|
ccArray* arrayChildren = _children->data;
|
|
unsigned int childrenCount = arrayChildren->num;
|
|
|
|
if (_overLeftArray->count() == childrenCount)
|
|
{
|
|
unsigned int count = childrenCount;
|
|
for (unsigned int i = 0; i < count; ++i)
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(_overLeftArray->getObjectAtIndex(i));
|
|
|
|
if (i == 0)
|
|
{
|
|
float width = child->getSize().width;
|
|
float offset = (child->getWidgetType() == WidgetTypeWidget) ? (width / 2) : 0;
|
|
float x = _leftBoundary + _disBoundaryToChild_0 + width + offset;
|
|
child->setPosition(Point(x, child->getPosition().y));
|
|
}
|
|
else
|
|
{
|
|
UIWidget* prev_child = dynamic_cast<UIWidget*>(_overLeftArray->getObjectAtIndex(i - 1));
|
|
child->setPosition(Point(prev_child->getPosition().x + _disBetweenChild, child->getPosition().y));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float scroll_left = _leftBoundary;
|
|
|
|
ccArray* arrayChildren = _children->data;
|
|
int count = arrayChildren->num;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]);
|
|
float child_right = child->getRightInParent();
|
|
|
|
if (child_right <= scroll_left)
|
|
{
|
|
int index = (i == 0) ? (count - 1) : (i - 1);
|
|
UIWidget* prev_child = dynamic_cast<UIWidget*>(arrayChildren->arr[index]);
|
|
child->setPosition(Point(prev_child->getPosition().x + _disBetweenChild, child->getPosition().y));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_RIGHT: // right
|
|
{
|
|
ccArray* arrayChildren = _children->data;
|
|
unsigned int childrenCount = arrayChildren->num;
|
|
|
|
if (_overRightArray->count() == childrenCount)
|
|
{
|
|
unsigned int count = childrenCount;
|
|
for (unsigned int i = 0; i < count; ++i)
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(_overRightArray->getObjectAtIndex(i));
|
|
|
|
if (i == 0)
|
|
{
|
|
float x = _rightBoundary - _disBoundaryToChild_0 + _disBetweenChild;
|
|
child->setPosition(Point(x, child->getPosition().y));
|
|
}
|
|
else
|
|
{
|
|
UIWidget* prev_child = dynamic_cast<UIWidget*>(_overRightArray->getObjectAtIndex(i - 1));
|
|
child->setPosition(Point(prev_child->getPosition().x - _disBetweenChild, child->getPosition().y));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float scroll_right = _rightBoundary;
|
|
|
|
ccArray* arrayChildren = _children->data;
|
|
int count = arrayChildren->num;
|
|
for (int i = count - 1; i >= 0; --i)
|
|
{
|
|
UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]);
|
|
float child_left = child->getLeftInParent();
|
|
|
|
if (child_left >= scroll_right)
|
|
{
|
|
int index = (i == count - 1) ? 0 : (i + 1);
|
|
UIWidget* next_child = dynamic_cast<UIWidget*>(arrayChildren->arr[index]);
|
|
child->setPosition(Point(next_child->getPosition().x - _disBetweenChild, child->getPosition().y));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void UIListView::updateChild()
|
|
{
|
|
switch (_direction)
|
|
{
|
|
case LISTVIEW_DIR_VERTICAL: // vertical
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_UP: // up
|
|
{
|
|
int count = _overTopArray->count();
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
pushChildToPool();
|
|
getAndCallback();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_DOWN: // down
|
|
{
|
|
int count = _overBottomArray->count();
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
pushChildToPool();
|
|
getAndCallback();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_DIR_HORIZONTAL: // horizontal
|
|
switch (_moveDirection)
|
|
{
|
|
case LISTVIEW_MOVE_DIR_LEFT: // left
|
|
{
|
|
int count = _overLeftArray->count();
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
pushChildToPool();
|
|
getAndCallback();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LISTVIEW_MOVE_DIR_RIGHT: // right
|
|
{
|
|
int count = _overRightArray->count();
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
pushChildToPool();
|
|
getAndCallback();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void UIListView::initChildEvent()
|
|
{
|
|
if (_eventListener && _eventSelector)
|
|
{
|
|
(_eventListener->*_eventSelector)(this, LISTVIEW_EVENT_INIT_CHILD);
|
|
}
|
|
}
|
|
|
|
void UIListView::updateChildEvent()
|
|
{
|
|
if (_eventListener && _eventSelector)
|
|
{
|
|
(_eventListener->*_eventSelector)(this, LISTVIEW_EVENT_UPDATE_CHILD);
|
|
}
|
|
}
|
|
|
|
void UIListView::addEventListenter(Object *target, SEL_ListViewEvent selector)
|
|
{
|
|
_eventListener = target;
|
|
_eventSelector = selector;
|
|
}
|
|
|
|
const char* UIListView::getDescription() const
|
|
{
|
|
return "ListView";
|
|
}
|
|
|
|
|
|
NS_CC_EXT_END |