diff --git a/cocos/ui/UIListView.cpp b/cocos/ui/UIListView.cpp index 53cf8c5fdc..ff2a972732 100644 --- a/cocos/ui/UIListView.cpp +++ b/cocos/ui/UIListView.cpp @@ -716,5 +716,58 @@ void ListView::copySpecialProperties(Widget *widget) } } +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 == ScrollView::Direction::HORIZONTAL) + { + magType = (adjustedDeltaMove.x > 0 ? MagneticType::LEFT : MagneticType::RIGHT); + } + else if(_direction == ScrollView::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); +} + } NS_CC_END diff --git a/cocos/ui/UIListView.h b/cocos/ui/UIListView.h index 5890f45ae9..22127d1e53 100644 --- a/cocos/ui/UIListView.h +++ b/cocos/ui/UIListView.h @@ -364,6 +364,9 @@ protected: virtual void copyClonedWidgetChildren(Widget* model) override; void selectedItemEvent(TouchEventType event); virtual void interceptTouchEvent(Widget::TouchEventType event,Widget* sender,Touch* touch) override; + + virtual void startAttenuatingAutoScroll(const Vec2& deltaMove, const Vec2& initialVelocity) override; + protected: Widget* _model; diff --git a/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIListViewTest/UIListViewTest.cpp b/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIListViewTest/UIListViewTest.cpp index f9d3e9478b..57e38bc913 100644 --- a/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIListViewTest/UIListViewTest.cpp +++ b/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIListViewTest/UIListViewTest.cpp @@ -742,8 +742,8 @@ bool UIListViewTest_Magnetic::init() } // Initial magnetic type - _listView->setMagneticType(ListView::MagneticType::CENTER); - _titleLabel->setString("MagneticType - CENTER"); + _listView->setMagneticType(ListView::MagneticType::NONE); + _titleLabel->setString("MagneticType - NONE"); // Magnetic change button auto pButton = Button::create("cocosui/backtotoppressed.png", "cocosui/backtotopnormal.png"); @@ -756,16 +756,44 @@ bool UIListViewTest_Magnetic::init() ListView::MagneticType eNextType; std::string sString; if(eCurrentType == ListView::MagneticType::NONE) + { + eNextType = ListView::MagneticType::CENTER; + sString = "CENTER"; + } + else if(eCurrentType == ListView::MagneticType::CENTER) { eNextType = ListView::MagneticType::BOTH_END; sString = "BOTH_END"; } else if(eCurrentType == ListView::MagneticType::BOTH_END) { - eNextType = ListView::MagneticType::CENTER; - sString = "CENTER"; + if(getListViewDirection() == ScrollView::Direction::HORIZONTAL) + { + eNextType = ListView::MagneticType::LEFT; + sString = "LEFT"; + } + else + { + eNextType = ListView::MagneticType::TOP; + sString = "TOP"; + } } - else if(eCurrentType == ListView::MagneticType::CENTER) + else if(eCurrentType == ListView::MagneticType::LEFT) + { + eNextType = ListView::MagneticType::RIGHT; + sString = "RIGHT"; + } + else if(eCurrentType == ListView::MagneticType::RIGHT) + { + eNextType = ListView::MagneticType::NONE; + sString = "NONE"; + } + else if(eCurrentType == ListView::MagneticType::TOP) + { + eNextType = ListView::MagneticType::BOTTOM; + sString = "BOTTOM"; + } + else if(eCurrentType == ListView::MagneticType::BOTTOM) { eNextType = ListView::MagneticType::NONE; sString = "NONE"; @@ -776,8 +804,8 @@ bool UIListViewTest_Magnetic::init() _uiLayer->addChild(pButton); // Add list items - static const Size BUTTON_SIZE(50, 40); - for (int i = 0; i < 20; ++i) + static const Size BUTTON_SIZE(100, 70); + for (int i = 0; i < 40; ++i) { auto pButton = Button::create("cocosui/button.png", "cocosui/buttonHighlighted.png"); pButton->setContentSize(BUTTON_SIZE);