国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

cocos2dx學(xué)習(xí)之UIListView.cpp

這篇具有很好參考價(jià)值的文章主要介紹了cocos2dx學(xué)習(xí)之UIListView.cpp。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

/****************************************************************************

Copyright (c) 2013-2017 Chukong Technologies Inc.

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 "ui/UIListView.h"

#include "ui/UIHelper.h"

NS_CC_BEGIN

static const float DEFAULT_TIME_IN_SEC_FOR_SCROLL_TO_ITEM = 1.0f;

namespace ui {

IMPLEMENT_CLASS_GUI_INFO(ListView)

ListView::ListView():

_model(nullptr),

_gravity(Gravity::CENTER_VERTICAL),

_magneticType(MagneticType::NONE),

_magneticAllowedOutOfBoundary(true),

_itemsMargin(0.0f),

_leftPadding(0.0f),

_topPadding(0.0f),

_rightPadding(0.0f),

_bottomPadding(0.0f),

_scrollTime(DEFAULT_TIME_IN_SEC_FOR_SCROLL_TO_ITEM),

_curSelectedIndex(-1),

_innerContainerDoLayoutDirty(true),

_listViewEventListener(nullptr),

_listViewEventSelector(nullptr),

_eventCallback(nullptr)

{

this->setTouchEnabled(true);

}

ListView::~ListView()

{

_listViewEventListener = nullptr;

_listViewEventSelector = nullptr;

_items.clear();

CC_SAFE_RELEASE(_model);

}

ListView* ListView::create()

{

ListView* widget = new (std::nothrow) ListView();

if (widget && widget->init())

{

widget->autorelease();

return widget;

}

CC_SAFE_DELETE(widget);

return nullptr;

}

bool ListView::init()

{

if (ScrollView::init())

{

setDirection(Direction::VERTICAL);

return true;

}

return false;

}

void ListView::setItemModel(Widget *model)

{

if (nullptr == model)

{

CCLOG("Can't set a nullptr to item model!");

return;

}

CC_SAFE_RELEASE_NULL(_model);

_model = model;

CC_SAFE_RETAIN(_model);

}

void ListView::handleReleaseLogic(Touch *touch)

{

ScrollView::handleReleaseLogic(touch);

if(!_autoScrolling)

{

startMagneticScroll();

}

}

void ListView::onItemListChanged()

{

_outOfBoundaryAmountDirty = true;

}

void ListView::updateInnerContainerSize()

{

switch (_direction)

{

case Direction::VERTICAL:

{

size_t length = _items.size();

float totalHeight = (length - 1) * _itemsMargin + (_topPadding + _bottomPadding);

for (auto& item : _items)

{

totalHeight += item->getContentSize().height;

}

float finalWidth = _contentSize.width;

float finalHeight = totalHeight;

setInnerContainerSize(Size(finalWidth, finalHeight));

break;

}

case Direction::HORIZONTAL:

{

size_t length = _items.size();

float totalWidth = (length - 1) * _itemsMargin + (_leftPadding + _rightPadding);

for (auto& item : _items)

{

totalWidth += item->getContentSize().width;

}

float finalWidth = totalWidth;

float finalHeight = _contentSize.height;

setInnerContainerSize(Size(finalWidth, finalHeight));

break;

}

default:

break;

}

}

void ListView::remedyVerticalLayoutParameter(LinearLayoutParameter* layoutParameter, ssize_t itemIndex)

{

CCASSERT(nullptr != layoutParameter, "Layout parameter can't be nullptr!");

switch (_gravity)

{

case Gravity::LEFT:

layoutParameter->setGravity(LinearLayoutParameter::LinearGravity::LEFT);

break;

case Gravity::RIGHT:

layoutParameter->setGravity(LinearLayoutParameter::LinearGravity::RIGHT);

break;

case Gravity::CENTER_HORIZONTAL:

layoutParameter->setGravity(LinearLayoutParameter::LinearGravity::CENTER_HORIZONTAL);

break;

default:

break;

}

if (0 == itemIndex)

{

layoutParameter->setMargin(Margin(_leftPadding, _topPadding, _rightPadding, 0.f));

}

else if (_items.size() - 1 == itemIndex)

{

layoutParameter->setMargin(Margin(_leftPadding, _itemsMargin, _rightPadding, _bottomPadding));

}

else

{

layoutParameter->setMargin(Margin(_leftPadding, _itemsMargin, _rightPadding, 0.0f));

}

}

void ListView::remedyHorizontalLayoutParameter(LinearLayoutParameter* layoutParameter, ssize_t itemIndex)

{

CCASSERT(nullptr != layoutParameter, "Layout parameter can't be nullptr!");

switch (_gravity)

{

case Gravity::TOP:

layoutParameter->setGravity(LinearLayoutParameter::LinearGravity::TOP);

break;

case Gravity::BOTTOM:

layoutParameter->setGravity(LinearLayoutParameter::LinearGravity::BOTTOM);

break;

case Gravity::CENTER_VERTICAL:

layoutParameter->setGravity(LinearLayoutParameter::LinearGravity::CENTER_VERTICAL);

break;

default:

break;

}

if (0 == itemIndex)

{

layoutParameter->setMargin(Margin(_leftPadding, _topPadding, 0.f, _bottomPadding));

}

else if (_items.size() == itemIndex)

{

layoutParameter->setMargin(Margin(_itemsMargin, _topPadding, _rightPadding, _bottomPadding));

}

else

{

layoutParameter->setMargin(Margin(_itemsMargin, _topPadding, 0.f, _bottomPadding));

}

}

void ListView::remedyLayoutParameter(Widget *item)

{

CCASSERT(nullptr != item, "ListView Item can't be nullptr!");

LinearLayoutParameter* linearLayoutParameter = (LinearLayoutParameter*)(item->getLayoutParameter());

bool isLayoutParameterExists = true;

if (!linearLayoutParameter)

{

linearLayoutParameter = LinearLayoutParameter::create();

isLayoutParameterExists = false;

}

ssize_t itemIndex = getIndex(item);

switch (_direction)

{

case Direction::VERTICAL:

{

this->remedyVerticalLayoutParameter(linearLayoutParameter, itemIndex);

break;

}

case Direction::HORIZONTAL:

{

this->remedyHorizontalLayoutParameter(linearLayoutParameter, itemIndex);

break;

}

default:

break;

}

if (!isLayoutParameterExists)

{

item->setLayoutParameter(linearLayoutParameter);

}

}

void ListView::pushBackDefaultItem()

{

if (nullptr == _model)

{

return;

}

Widget* newItem = _model->clone();

remedyLayoutParameter(newItem);

addChild(newItem);

requestDoLayout();

}

void ListView::insertDefaultItem(ssize_t index)

{

if (nullptr == _model)

{

return;

}

insertCustomItem(_model->clone(), index);

}


?

void ListView::pushBackCustomItem(Widget* item)

{

remedyLayoutParameter(item);

addChild(item);

requestDoLayout();

}

void ListView::addChild(cocos2d::Node *child, int zOrder, int tag)

{

ScrollView::addChild(child, zOrder, tag);

Widget* widget = dynamic_cast<Widget*>(child);

if (nullptr != widget)

{

_items.pushBack(widget);

onItemListChanged();

}

}

void ListView::addChild(cocos2d::Node *child)

{

ListView::addChild(child, child->getLocalZOrder(), child->getName());

}

void ListView::addChild(cocos2d::Node *child, int zOrder)

{

ListView::addChild(child, zOrder, child->getName());

}

void ListView::addChild(Node* child, int zOrder, const std::string &name)

{

ScrollView::addChild(child, zOrder, name);

Widget* widget = dynamic_cast<Widget*>(child);

if (nullptr != widget)

{

_items.pushBack(widget);

onItemListChanged();

}

}

void ListView::removeChild(cocos2d::Node *child, bool cleanup)

{

Widget* widget = dynamic_cast<Widget*>(child);

if (nullptr != widget)

{

if (-1 != _curSelectedIndex)

{

auto removedIndex = getIndex(widget);

if (_curSelectedIndex > removedIndex)

{

_curSelectedIndex -= 1;

}

else if (_curSelectedIndex == removedIndex)

{

_curSelectedIndex = -1;

}

}

_items.eraseObject(widget);

onItemListChanged();

}

ScrollView::removeChild(child, cleanup);

requestDoLayout();

}

void ListView::removeAllChildren()

{

this->removeAllChildrenWithCleanup(true);

}

void ListView::removeAllChildrenWithCleanup(bool cleanup)

{

ScrollView::removeAllChildrenWithCleanup(cleanup);

_curSelectedIndex = -1;

_items.clear();

onItemListChanged();

}

void ListView::insertCustomItem(Widget* item, ssize_t index)

{

if (-1 != _curSelectedIndex)

{

if (_curSelectedIndex >= index)

{

_curSelectedIndex += 1;

}

}

_items.insert(index, item);

onItemListChanged();

ScrollView::addChild(item);

remedyLayoutParameter(item);

requestDoLayout();

}

void ListView::removeItem(ssize_t index)

{

Widget* item = getItem(index);

if (nullptr == item)

{

return;

}

removeChild(item, true);

}

void ListView::removeLastItem()

{

removeItem(_items.size() -1);

}

void ListView::removeAllItems()

{

removeAllChildren();

}

Widget* ListView::getItem(ssize_t index) const

{

if (index < 0 || index >= _items.size())

{

return nullptr;

}

return _items.at(index);

}

Vector<Widget*>& ListView::getItems()

{

return _items;

}

ssize_t ListView::getIndex(Widget *item) const

{

if (nullptr == item)

{

return -1;

}

return _items.getIndex(item);

}

void ListView::setGravity(Gravity gravity)

{

if (_gravity == gravity)

{

return;

}

_gravity = gravity;

requestDoLayout();

}

void ListView::setMagneticType(MagneticType magneticType)

{

_magneticType = magneticType;

_outOfBoundaryAmountDirty = true;

startMagneticScroll();

}

ListView::MagneticType ListView::getMagneticType() const

{

return _magneticType;

}

void ListView::setMagneticAllowedOutOfBoundary(bool magneticAllowedOutOfBoundary)

{

_magneticAllowedOutOfBoundary = magneticAllowedOutOfBoundary;

}

bool ListView::getMagneticAllowedOutOfBoundary() const

{

return _magneticAllowedOutOfBoundary;

}

void ListView::setItemsMargin(float margin)

{

if (_itemsMargin == margin)

{

return;

}

_itemsMargin = margin;

requestDoLayout();

}

float ListView::getItemsMargin()const

{

return _itemsMargin;

}

void ListView::setPadding(float l, float t, float r, float b)

{

if (l == _leftPadding && t == _topPadding && r == _rightPadding && b == _bottomPadding)

{

return;

}

_leftPadding = l;

_topPadding = t;

_rightPadding = r;

_bottomPadding = b;

requestDoLayout();

}

void ListView::setLeftPadding(float l)

{

if (l == _leftPadding)

{

return;

}

_leftPadding = l;

requestDoLayout();

}

void ListView::setTopPadding(float t)

{

if (t == _topPadding)

{

return;

}

_topPadding = t;

requestDoLayout();

}

void ListView::setRightPadding(float r)

{

if (r == _rightPadding)

{

return;

}

_rightPadding = r;

requestDoLayout();

}

void ListView::setBottomPadding(float b)

{

if (b == _bottomPadding)

{

return;

}

_bottomPadding = b;

requestDoLayout();

}

float ListView::getLeftPadding() const

{

return _leftPadding;

}

float ListView::getTopPadding() const

{

return _topPadding;

}

float ListView::getRightPadding() const

{

return _rightPadding;

}

float ListView::getBottomPadding() const

{

return _bottomPadding;

}

void ListView::setScrollDuration(float time)

{

if (time >= 0)

_scrollTime = time;

}

float ListView::getScrollDuration() const

{

return _scrollTime;

}

void ListView::setDirection(Direction dir)

{

switch (dir)

{

case Direction::NONE:

case Direction::BOTH:

break;

case Direction::VERTICAL:

setLayoutType(Type::VERTICAL);

break;

case Direction::HORIZONTAL:

setLayoutType(Type::HORIZONTAL);

break;

default:

return;

break;

}

ScrollView::setDirection(dir);

}

void ListView::refreshView()

{

forceDoLayout();

}

void ListView::requestDoLayout()

{

_innerContainerDoLayoutDirty = true;

}

void ListView::doLayout()

{

if(!_innerContainerDoLayoutDirty)

{

return;

}

ssize_t length = _items.size();

for (int i = 0; i < length; ++i)

{

Widget* item = _items.at(i);

item->setLocalZOrder(i);

remedyLayoutParameter(item);

}

updateInnerContainerSize();

_innerContainer->forceDoLayout();

_innerContainerDoLayoutDirty = false;

}

void ListView::addEventListenerListView(Ref *target, SEL_ListViewEvent selector)

{

_listViewEventListener = target;

_listViewEventSelector = selector;

}

void ListView::addEventListener(const ccListViewCallback& callback)

{

_eventCallback = callback;

}

void ListView::selectedItemEvent(TouchEventType event)

{

this->retain();

switch (event)

{

case TouchEventType::BEGAN:

{

if (_listViewEventListener && _listViewEventSelector)

{

(_listViewEventListener->*_listViewEventSelector)(this, LISTVIEW_ONSELECTEDITEM_START);

}

if (_eventCallback) {

_eventCallback(this,EventType::ON_SELECTED_ITEM_START);

}

if (_ccEventCallback)

{

_ccEventCallback(this, static_cast<int>(EventType::ON_SELECTED_ITEM_START));

}

}

break;

default:

{

if (_listViewEventListener && _listViewEventSelector)

{

(_listViewEventListener->*_listViewEventSelector)(this, LISTVIEW_ONSELECTEDITEM_END);

}

if (_eventCallback) {

_eventCallback(this, EventType::ON_SELECTED_ITEM_END);

}

if (_ccEventCallback)

{

_ccEventCallback(this, static_cast<int>(EventType::ON_SELECTED_ITEM_END));

}

}

break;

}

this->release();

}

void ListView::interceptTouchEvent(TouchEventType event, Widget *sender, Touch* touch)

{

ScrollView::interceptTouchEvent(event, sender, touch);

if (!_touchEnabled)

{

return;

}

if (event != TouchEventType::MOVED)

{

Widget* parent = sender;

while (parent)

{

if (parent && (parent->getParent() == _innerContainer))

{

_curSelectedIndex = getIndex(parent);

break;

}

parent = dynamic_cast<Widget*>(parent->getParent());

}

if (sender->isHighlighted()) {

selectedItemEvent(event);

}

}

}

static Vec2 calculateItemPositionWithAnchor(Widget* item, const Vec2& itemAnchorPoint)

{

Vec2 origin(item->getLeftBoundary(), item->getBottomBoundary());

Size size = item->getContentSize();

return origin + Vec2(size.width * itemAnchorPoint.x, size.height * itemAnchorPoint.y);

}

static Widget* findClosestItem(const Vec2& targetPosition, const Vector<Widget*>& items, const Vec2& itemAnchorPoint, ssize_t firstIndex, float distanceFromFirst, ssize_t lastIndex, float distanceFromLast)

{

CCASSERT(firstIndex >= 0 && lastIndex < items.size() && firstIndex <= lastIndex, "");

if (firstIndex == lastIndex)

{

return items.at(firstIndex);

}

if (lastIndex - firstIndex == 1)

{

if (distanceFromFirst <= distanceFromLast)

{

return items.at(firstIndex);

}

else

{

return items.at(lastIndex);

}

}

// Binary search

ssize_t midIndex = (firstIndex + lastIndex) / 2;

Vec2 itemPosition = calculateItemPositionWithAnchor(items.at(midIndex), itemAnchorPoint);

float distanceFromMid = (targetPosition - itemPosition).length();

if (distanceFromFirst <= distanceFromLast)

{

// Left half

return findClosestItem(targetPosition, items, itemAnchorPoint, firstIndex, distanceFromFirst, midIndex, distanceFromMid);

}

else

{

// Right half

return findClosestItem(targetPosition, items, itemAnchorPoint, midIndex, distanceFromMid, lastIndex, distanceFromLast);

}

}

Widget* ListView::getClosestItemToPosition(const Vec2& targetPosition, const Vec2& itemAnchorPoint) const

{

if (_items.empty())

{

return nullptr;

}

// Find the closest item through binary search

ssize_t firstIndex = 0;

Vec2 firstPosition = calculateItemPositionWithAnchor(_items.at(firstIndex), itemAnchorPoint);

float distanceFromFirst = (targetPosition - firstPosition).length();

ssize_t lastIndex = _items.size() - 1;

Vec2 lastPosition = calculateItemPositionWithAnchor(_items.at(lastIndex), itemAnchorPoint);

float distanceFromLast = (targetPosition - lastPosition).length();

return findClosestItem(targetPosition, _items, itemAnchorPoint, firstIndex, distanceFromFirst, lastIndex, distanceFromLast);

}

Widget* ListView::getClosestItemToPositionInCurrentView(const Vec2& positionRatioInView, const Vec2& itemAnchorPoint) const

{

// Calculate the target position

Size contentSize = getContentSize();

Vec2 targetPosition = -_innerContainer->getPosition();

targetPosition.x += contentSize.width * positionRatioInView.x;

targetPosition.y += contentSize.height * positionRatioInView.y;

return getClosestItemToPosition(targetPosition, itemAnchorPoint);

}

Widget* ListView::getCenterItemInCurrentView() const

{

return getClosestItemToPositionInCurrentView(Vec2::ANCHOR_MIDDLE, Vec2::ANCHOR_MIDDLE);

}

Widget* ListView::getLeftmostItemInCurrentView() const

{

if (_direction == Direction::HORIZONTAL)

{

return getClosestItemToPositionInCurrentView(Vec2::ANCHOR_MIDDLE_LEFT, Vec2::ANCHOR_MIDDLE);

}

return nullptr;

}

Widget* ListView::getRightmostItemInCurrentView() const

{

if (_direction == Direction::HORIZONTAL)

{

return getClosestItemToPositionInCurrentView(Vec2::ANCHOR_MIDDLE_RIGHT, Vec2::ANCHOR_MIDDLE);

}

return nullptr;

}

Widget* ListView::getTopmostItemInCurrentView() const

{

if (_direction == Direction::VERTICAL)

{

return getClosestItemToPositionInCurrentView(Vec2::ANCHOR_MIDDLE_TOP, Vec2::ANCHOR_MIDDLE);

}

return nullptr;

}

Widget* ListView::getBottommostItemInCurrentView() const

{

if (_direction == Direction::VERTICAL)

{

return getClosestItemToPositionInCurrentView(Vec2::ANCHOR_MIDDLE_BOTTOM, Vec2::ANCHOR_MIDDLE);

}

return nullptr;

}

void ListView::jumpToBottom()

{

doLayout();

ScrollView::jumpToBottom();

}

void ListView::jumpToTop()

{

doLayout();

ScrollView::jumpToTop();

}

void ListView::jumpToLeft()

{

doLayout();

ScrollView::jumpToLeft();

}

void ListView::jumpToRight()

{

doLayout();

ScrollView::jumpToRight();

}

void ListView::jumpToTopLeft()

{

doLayout();

ScrollView::jumpToTopLeft();

}

void ListView::jumpToTopRight()

{

doLayout();

ScrollView::jumpToTopRight();

}

void ListView::jumpToBottomLeft()

{

doLayout();

ScrollView::jumpToBottomLeft();

}

void ListView::jumpToBottomRight()

{

doLayout();

ScrollView::jumpToBottomRight();

}

void ListView::jumpToPercentVertical(float percent)

{

doLayout();

ScrollView::jumpToPercentVertical(percent);

}

void ListView::jumpToPercentHorizontal(float percent)

{

doLayout();

ScrollView::jumpToPercentHorizontal(percent);

}

void ListView::jumpToPercentBothDirection(const Vec2& percent)

{

doLayout();

ScrollView::jumpToPercentBothDirection(percent);

}

Vec2 ListView::calculateItemDestination(const Vec2& positionRatioInView, Widget* item, const Vec2& itemAnchorPoint)

{

const Size& contentSize = getContentSize();

Vec2 positionInView;

positionInView.x += contentSize.width * positionRatioInView.x;

positionInView.y += contentSize.height * positionRatioInView.y;

Vec2 itemPosition = calculateItemPositionWithAnchor(item, itemAnchorPoint);

return -(itemPosition - positionInView);

}

void ListView::jumpToItem(ssize_t itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint)

{

Widget* item = getItem(itemIndex);

if (item == nullptr)

{

return;

}

doLayout();

Vec2 destination = calculateItemDestination(positionRatioInView, item, itemAnchorPoint);

if(!_bounceEnabled)

{

Vec2 delta = destination - getInnerContainerPosition();

Vec2 outOfBoundary = getHowMuchOutOfBoundary(delta);

destination += outOfBoundary;

}

jumpToDestination(destination);

}

void ListView::scrollToItem(ssize_t itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint)

{

scrollToItem(itemIndex, positionRatioInView, itemAnchorPoint, _scrollTime);

}

void ListView::scrollToItem(ssize_t itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint, float timeInSec)

{

Widget* item = getItem(itemIndex);

if (item == nullptr)

{

return;

}

Vec2 destination = calculateItemDestination(positionRatioInView, item, itemAnchorPoint);

startAutoScrollToDestination(destination, timeInSec, true);

}

ssize_t ListView::getCurSelectedIndex() const

{

return _curSelectedIndex;

}

void ListView::setCurSelectedIndex(int itemIndex)

{

Widget* item = getItem(itemIndex);

if (item == nullptr)

{

return;

}

_curSelectedIndex = itemIndex;

this->selectedItemEvent(cocos2d::ui::Widget::TouchEventType::ENDED);

}

void ListView::onSizeChanged()

{

ScrollView::onSizeChanged();

requestDoLayout();

}

std::string ListView::getDescription() const

{

return "ListView";

}

Widget* ListView::createCloneInstance()

{

return ListView::create();

}

void ListView::copyClonedWidgetChildren(Widget* model)

{

auto& arrayItems = static_cast<ListView*>(model)->getItems();

for (auto& item : arrayItems)

{

pushBackCustomItem(item->clone());

}

}

void ListView::copySpecialProperties(Widget *widget)

{

ListView* listViewEx = dynamic_cast<ListView*>(widget);

if (listViewEx)

{

ScrollView::copySpecialProperties(widget);

setItemModel(listViewEx->_model);

setItemsMargin(listViewEx->_itemsMargin);

setGravity(listViewEx->_gravity);

_listViewEventListener = listViewEx->_listViewEventListener;

_listViewEventSelector = listViewEx->_listViewEventSelector;

_eventCallback = listViewEx->_eventCallback;

}

}

Vec2 ListView::getHowMuchOutOfBoundary(const Vec2& addition)

{

if(!_magneticAllowedOutOfBoundary || _items.empty())

{

return ScrollView::getHowMuchOutOfBoundary(addition);

}

else if(_magneticType == MagneticType::NONE || _magneticType == MagneticType::BOTH_END)

{

return ScrollView::getHowMuchOutOfBoundary(addition);

}

else if(addition == Vec2::ZERO && !_outOfBoundaryAmountDirty)

{

return _outOfBoundaryAmount;

}

// If it is allowed to be out of boundary by magnetic, adjust the boundaries according to the magnetic type.

float leftBoundary = _leftBoundary;

float rightBoundary = _rightBoundary;

float topBoundary = _topBoundary;

float bottomBoundary = _bottomBoundary;

{

ssize_t lastItemIndex = _items.size() - 1;

Size contentSize = getContentSize();

Vec2 firstItemAdjustment, lastItemAdjustment;

if(_magneticType == MagneticType::CENTER)

{

firstItemAdjustment = (contentSize - _items.at(0)->getContentSize()) / 2;

lastItemAdjustment = (contentSize - _items.at(lastItemIndex)->getContentSize()) / 2;

}

else if(_magneticType == MagneticType::LEFT)

{

lastItemAdjustment = contentSize - _items.at(lastItemIndex)->getContentSize();

}

else if(_magneticType == MagneticType::RIGHT)

{

firstItemAdjustment = contentSize - _items.at(0)->getContentSize();

}

else if(_magneticType == MagneticType::TOP)

{

lastItemAdjustment = contentSize - _items.at(lastItemIndex)->getContentSize();

}

else if(_magneticType == MagneticType::BOTTOM)

{

firstItemAdjustment = contentSize - _items.at(0)->getContentSize();

}

leftBoundary += firstItemAdjustment.x;

rightBoundary -= lastItemAdjustment.x;

topBoundary -= firstItemAdjustment.y;

bottomBoundary += lastItemAdjustment.y;

}

// Calculate the actual amount

Vec2 outOfBoundaryAmount;

if(_innerContainer->getLeftBoundary() + addition.x > leftBoundary)

{

outOfBoundaryAmount.x = leftBoundary - (_innerContainer->getLeftBoundary() + addition.x);

}

else if(_innerContainer->getRightBoundary() + addition.x < rightBoundary)

{

outOfBoundaryAmount.x = rightBoundary - (_innerContainer->getRightBoundary() + addition.x);

}

if(_innerContainer->getTopBoundary() + addition.y < topBoundary)

{

outOfBoundaryAmount.y = topBoundary - (_innerContainer->getTopBoundary() + addition.y);

}

else if(_innerContainer->getBottomBoundary() + addition.y > bottomBoundary)

{

outOfBoundaryAmount.y = bottomBoundary - (_innerContainer->getBottomBoundary() + addition.y);

}

if(addition == Vec2::ZERO)

{

_outOfBoundaryAmount = outOfBoundaryAmount;

_outOfBoundaryAmountDirty = false;

}

return outOfBoundaryAmount;

}

static Vec2 getAnchorPointByMagneticType(ListView::MagneticType magneticType)

{

switch(magneticType)

{

case ListView::MagneticType::NONE: return Vec2::ZERO;

case ListView::MagneticType::BOTH_END: return Vec2::ANCHOR_TOP_LEFT;

case ListView::MagneticType::CENTER: return Vec2::ANCHOR_MIDDLE;

case ListView::MagneticType::LEFT: return Vec2::ANCHOR_MIDDLE_LEFT;

case ListView::MagneticType::RIGHT: return Vec2::ANCHOR_MIDDLE_RIGHT;

case ListView::MagneticType::TOP: return Vec2::ANCHOR_MIDDLE_TOP;

case ListView::MagneticType::BOTTOM: return Vec2::ANCHOR_MIDDLE_BOTTOM;

}

return Vec2::ZERO;

}

void ListView::startAttenuatingAutoScroll(const Vec2& deltaMove, const Vec2& initialVelocity)

{

Vec2 adjustedDeltaMove = deltaMove;

if(!_items.empty() && _magneticType != MagneticType::NONE)

{

adjustedDeltaMove = flattenVectorByDirection(adjustedDeltaMove);

// If the destination is out of boundary, do nothing here. Because it will be handled by bouncing back.

if(getHowMuchOutOfBoundary(adjustedDeltaMove) == Vec2::ZERO)

{

MagneticType magType = _magneticType;

if(magType == MagneticType::BOTH_END)

{

if(_direction == Direction::HORIZONTAL)

{

magType = (adjustedDeltaMove.x > 0 ? MagneticType::LEFT : MagneticType::RIGHT);

}

else if(_direction == Direction::VERTICAL)

{

magType = (adjustedDeltaMove.y > 0 ? MagneticType::BOTTOM : MagneticType::TOP);

}

}

// Adjust the delta move amount according to the magnetic type

Vec2 magneticAnchorPoint = getAnchorPointByMagneticType(magType);

Vec2 magneticPosition = -_innerContainer->getPosition();

magneticPosition.x += getContentSize().width * magneticAnchorPoint.x;

magneticPosition.y += getContentSize().height * magneticAnchorPoint.y;

Widget* pTargetItem = getClosestItemToPosition(magneticPosition - adjustedDeltaMove, magneticAnchorPoint);

Vec2 itemPosition = calculateItemPositionWithAnchor(pTargetItem, magneticAnchorPoint);

adjustedDeltaMove = magneticPosition - itemPosition;

}

}

ScrollView::startAttenuatingAutoScroll(adjustedDeltaMove, initialVelocity);

}

void ListView::startMagneticScroll()

{

if(_items.empty() || _magneticType == MagneticType::NONE)

{

return;

}

// Find the closest item

Vec2 magneticAnchorPoint = getAnchorPointByMagneticType(_magneticType);

Vec2 magneticPosition = -_innerContainer->getPosition();

magneticPosition.x += getContentSize().width * magneticAnchorPoint.x;

magneticPosition.y += getContentSize().height * magneticAnchorPoint.y;

Widget* pTargetItem = getClosestItemToPosition(magneticPosition, magneticAnchorPoint);

scrollToItem(getIndex(pTargetItem), magneticAnchorPoint, magneticAnchorPoint);

}

}

NS_CC_END文章來源地址http://www.zghlxwxcb.cn/news/detail-674847.html

到了這里,關(guān)于cocos2dx學(xué)習(xí)之UIListView.cpp的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 《入門級(jí)-Cocos2dx4.0 塔防游戲開發(fā)》---第六課:歡迎界面開發(fā)(四、自定義精靈)

    《入門級(jí)-Cocos2dx4.0 塔防游戲開發(fā)》---第六課:歡迎界面開發(fā)(四、自定義精靈)

    目錄 ?一、開發(fā)環(huán)境 二、開發(fā)內(nèi)容 2. 1 新建自定義精靈 2.2 在welcome中創(chuàng)建新的menu 2.3 消息綁定以及消息響應(yīng) 三、演示效果 四、知識(shí)點(diǎn) 4.1 內(nèi)部消息響應(yīng) 4.2 字體精靈說明 4.3?CC_SYNTHESIZE宏 操作系統(tǒng):UOS1060專業(yè)版本。 cocos2dx:版本4.0 環(huán)境搭建教程:統(tǒng)信UOS下配置安裝cocos2dx開發(fā)

    2024年02月11日
    瀏覽(27)
  • Pygame和Cocos2d

    Pygame和Cocos2d都是 Python 中常用的游戲引擎,但它們的設(shè)計(jì)目標(biāo)、特點(diǎn)和使用場(chǎng)景略有不同。 Pygame與Cocos2d,目前是使用人數(shù)最多的兩個(gè)Python游戲庫。根據(jù)某知名產(chǎn)品點(diǎn)評(píng)網(wǎng)站的數(shù)據(jù)顯示,Cocos2d排名第一,Pygame排名第二。 Pygame是一種基于SDL(Simple DirectMedia Layer)的Python庫,主要

    2024年01月21日
    瀏覽(30)
  • cocos2D插件轉(zhuǎn)3D插件

    cocos2D插件轉(zhuǎn)3D插件

    2024年02月16日
    瀏覽(23)
  • Cocos2d-x實(shí)現(xiàn)文字顏色漸變

    Cocos2d-x實(shí)現(xiàn)文字顏色漸變

    更改CCLabel文件的updateColor()函數(shù)中的頂點(diǎn)顏色即可,代碼如下: 效果圖: ?

    2024年02月12日
    瀏覽(29)
  • cocos2d-x C++與Lua交互

    cocos2d-x C++與Lua交互

    Cocos版本: 3.10 Lua版本: 5.1.4 環(huán)境: window Visual Studio 2013 Lua 作為一種腳本語言, 它的運(yùn)行需要有 宿主 的存在,通過 Lua虛擬棧 進(jìn)行數(shù)據(jù)交互。 它的底層實(shí)現(xiàn)是 C 語言,C語言封裝了很多的API接口,使得C/C++與Lua之間可以很方便的通信交互。 Lua的官網(wǎng): https://www.lua.org/ 在coc

    2024年02月08日
    瀏覽(19)
  • 使用“Cocos引擎”創(chuàng)建的cpp工程如何在VS中調(diào)試Cocos2d-x源碼

    使用“Cocos引擎”創(chuàng)建的cpp工程如何在VS中調(diào)試Cocos2d-x源碼

    前段時(shí)間Cocos2d-x更新了一個(gè)Cocos引擎,這是一個(gè)集合源碼,IDE,Studio這一家老小的整合包,我們可以使用這個(gè)Cocos引擎來創(chuàng)建我們的項(xiàng)目。 在Cocos2d-x被整合到Cocos引擎之前,我們可以不那么方便地在我們創(chuàng)建的工程里調(diào)試Cocos2d-x的代碼,當(dāng)我們使用了整合后的Cocos引擎,調(diào)試

    2024年02月12日
    瀏覽(23)
  • cocos2d-x Android原生平臺(tái)與Lua交互

    版本: cocos2d-x 語言: C++/Java/Lua cocos2d-x原生平臺(tái)Android 接入第三方SDK, 需要了解 LuaJavaBridge 的使用。 它封裝了用于 Java 和 Lua 的相互調(diào)用, 其調(diào)用通過 C++ 為中介,簡(jiǎn)要的流程: Lua調(diào)用Java: Lua - C++ - Java Java調(diào)用Lua: Java - C++ - Lua 以此方式來實(shí)現(xiàn)數(shù)據(jù)的交互, 接下來我們分別說下

    2024年02月08日
    瀏覽(34)
  • cocos2d-x 3.17 推箱子 0.1

    cocos2d-x 3.17 推箱子 0.1

    此版本為推箱子游戲的基礎(chǔ)版本, 后續(xù)添加如下功能 人物動(dòng)畫 TiledMap 解析 射線碰撞檢測(cè) 下一步提示, C++算法解析 道具, 可以回退一步 通過 cocos 命令新建一個(gè)項(xiàng)目, 將本項(xiàng)目的 Reources 目錄和 Classes 目錄復(fù)制過去即可 使用圖集繪制 Sprite , 然后手動(dòng)處理碰撞檢測(cè) 游戲?qū)W論著翻譯

    2024年02月08日
    瀏覽(25)
  • 綁定證書的cocos2d程序如何對(duì)wss長(zhǎng)連接抓包

    綁定證書的cocos2d程序如何對(duì)wss長(zhǎng)連接抓包

    點(diǎn)擊上方 ↑ ↑ ↑ 藍(lán)字[ 協(xié)議分析與還原 ]關(guān)注我們 “ ?解決在應(yīng)用內(nèi)綁定了證書的cocos2d應(yīng)用wss長(zhǎng)連接抓包的問題。 ” 在分析應(yīng)用的過程中,不可避免地需要抓包。 沒加密的還好說,隨便找個(gè)工具抓下就可以分析了,有些應(yīng)用數(shù)據(jù)使用tls加密了,但用的是系統(tǒng)內(nèi)置的證書,

    2024年02月05日
    瀏覽(26)
  • 《入門級(jí)-Cocos2d 4.0塔防游戲開發(fā)》---第二課:游戲加載界面開發(fā)

    《入門級(jí)-Cocos2d 4.0塔防游戲開發(fā)》---第二課:游戲加載界面開發(fā)

    目錄 一、開發(fā)環(huán)境介紹 二、開發(fā)內(nèi)容 2.1 修改窗口的大小。 2.2 添加加載場(chǎng)景相關(guān)代碼 2.3 添加資源 三、顯示效果 四、知識(shí)點(diǎn) ?4.1?Sprite 4.2 定時(shí)器 操作系統(tǒng):UOS1060專業(yè)版本。 cocos2dx:版本 環(huán)境搭建教程: 統(tǒng)信UOS下配置安裝cocos2dx開發(fā)環(huán)境_三雷科技的博客-CSDN博客 ? ? ? ?游

    2024年02月15日
    瀏覽(38)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包