ListView - Apply magnetic to inertia scroll.

This commit is contained in:
Neo Kim 2015-09-08 16:55:19 +09:00
parent ca3ea53ffd
commit e58c073186
3 changed files with 91 additions and 7 deletions

View File

@ -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 NS_CC_END

View File

@ -364,6 +364,9 @@ protected:
virtual void copyClonedWidgetChildren(Widget* model) override; virtual void copyClonedWidgetChildren(Widget* model) override;
void selectedItemEvent(TouchEventType event); void selectedItemEvent(TouchEventType event);
virtual void interceptTouchEvent(Widget::TouchEventType event,Widget* sender,Touch* touch) override; virtual void interceptTouchEvent(Widget::TouchEventType event,Widget* sender,Touch* touch) override;
virtual void startAttenuatingAutoScroll(const Vec2& deltaMove, const Vec2& initialVelocity) override;
protected: protected:
Widget* _model; Widget* _model;

View File

@ -742,8 +742,8 @@ bool UIListViewTest_Magnetic::init()
} }
// Initial magnetic type // Initial magnetic type
_listView->setMagneticType(ListView::MagneticType::CENTER); _listView->setMagneticType(ListView::MagneticType::NONE);
_titleLabel->setString("MagneticType - CENTER"); _titleLabel->setString("MagneticType - NONE");
// Magnetic change button // Magnetic change button
auto pButton = Button::create("cocosui/backtotoppressed.png", "cocosui/backtotopnormal.png"); auto pButton = Button::create("cocosui/backtotoppressed.png", "cocosui/backtotopnormal.png");
@ -756,16 +756,44 @@ bool UIListViewTest_Magnetic::init()
ListView::MagneticType eNextType; ListView::MagneticType eNextType;
std::string sString; std::string sString;
if(eCurrentType == ListView::MagneticType::NONE) if(eCurrentType == ListView::MagneticType::NONE)
{
eNextType = ListView::MagneticType::CENTER;
sString = "CENTER";
}
else if(eCurrentType == ListView::MagneticType::CENTER)
{ {
eNextType = ListView::MagneticType::BOTH_END; eNextType = ListView::MagneticType::BOTH_END;
sString = "BOTH_END"; sString = "BOTH_END";
} }
else if(eCurrentType == ListView::MagneticType::BOTH_END) else if(eCurrentType == ListView::MagneticType::BOTH_END)
{ {
eNextType = ListView::MagneticType::CENTER; if(getListViewDirection() == ScrollView::Direction::HORIZONTAL)
sString = "CENTER"; {
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; eNextType = ListView::MagneticType::NONE;
sString = "NONE"; sString = "NONE";
@ -776,8 +804,8 @@ bool UIListViewTest_Magnetic::init()
_uiLayer->addChild(pButton); _uiLayer->addChild(pButton);
// Add list items // Add list items
static const Size BUTTON_SIZE(50, 40); static const Size BUTTON_SIZE(100, 70);
for (int i = 0; i < 20; ++i) for (int i = 0; i < 40; ++i)
{ {
auto pButton = Button::create("cocosui/button.png", "cocosui/buttonHighlighted.png"); auto pButton = Button::create("cocosui/button.png", "cocosui/buttonHighlighted.png");
pButton->setContentSize(BUTTON_SIZE); pButton->setContentSize(BUTTON_SIZE);