-{
- ScrollTo(position, mSnapDuration );
-}
-
-void ScrollView::ScrollTo(const Vector2& position, float duration)
-{
- ScrollTo(position, duration, DirectionBiasNone, DirectionBiasNone);
-}
-
-void ScrollView::ScrollTo(const Vector2& position, float duration, AlphaFunction alpha)
-{
- ScrollTo(position, duration, alpha, DirectionBiasNone, DirectionBiasNone);
-}
-
-void ScrollView::ScrollTo(const Vector2& position, float duration,
- DirectionBias horizontalBias, DirectionBias verticalBias)
-{
- ScrollTo(position, duration, mSnapAlphaFunction, horizontalBias, verticalBias);
-}
-
-void ScrollView::ScrollTo(const Vector2& position, float duration, AlphaFunction alpha,
- DirectionBias horizontalBias, DirectionBias verticalBias)
-{
- DALI_LOG_SCROLL_STATE("[0x%X] position[%.2f, %.2f] duration[%.2f], bias[%d, %d]", this, position.x, position.y, duration, int(horizontalBias), int(verticalBias));
- TransformTo(position, duration, alpha, horizontalBias, verticalBias);
-}
-
-void ScrollView::ScrollTo(unsigned int page)
-{
- ScrollTo(page, mSnapDuration);
-}
-
-void ScrollView::ScrollTo(unsigned int page, float duration, DirectionBias bias)
-{
- Vector2 position;
- unsigned int volume;
- unsigned int libraries;
-
- // The position to scroll to is continuous and linear
- // unless a domain has been enabled on the X axis.
- // or if WrapMode has been enabled.
- bool carryX = mRulerX->GetDomain().enabled | mWrapMode;
- bool carryY = mRulerY->GetDomain().enabled | mWrapMode;
-
- position.x = mRulerX->GetPositionFromPage(page, volume, carryX);
- position.y = mRulerY->GetPositionFromPage(volume, libraries, carryY);
-
- ScrollTo(position, duration, bias, bias);
-}
-
-void ScrollView::ScrollTo(Actor &actor)
-{
- ScrollTo(actor, mSnapDuration);
-}
-
-void ScrollView::ScrollTo(Actor &actor, float duration)
-{
- DALI_ASSERT_ALWAYS(actor.GetParent() == Self());
-
- Actor self = Self();
- Vector3 size = self.GetCurrentSize();
- Vector3 position = actor.GetCurrentPosition();
- Vector2 prePosition = GetPropertyPrePosition();
- position.GetVectorXY() -= prePosition;
-
- ScrollTo(Vector2(position.x - size.width * 0.5f, position.y - size.height * 0.5f), duration);
-}
-
-Actor ScrollView::FindClosestActor()
-{
- Actor self = Self();
- Vector3 size = self.GetCurrentSize();
-
- return FindClosestActorToPosition(Vector3(size.width * 0.5f,size.height * 0.5f,0.0f));
-}
-
-Actor ScrollView::FindClosestActorToPosition(const Vector3& position, FindDirection dirX, FindDirection dirY, FindDirection dirZ)
-{
- Actor closestChild;
- float closestDistance2 = 0.0f;
- Vector3 actualPosition = position;
-
- unsigned int numChildren = Self().GetChildCount();
-
- for(unsigned int i = 0; i < numChildren; ++i)
- {
- Actor child = Self().GetChildAt(i);
-
- if(mInternalActor == child) // ignore internal actor.
- {
- continue;
- }
-
- Vector3 childPosition = GetPositionOfAnchor(child, AnchorPoint::CENTER);
-
- Vector3 delta = childPosition - actualPosition;
-
- // X-axis checking (only find Actors to the [dirX] of actualPosition)
- if(dirX > All) // != All,None
- {
- FindDirection deltaH = delta.x > 0 ? Right : Left;
- if(dirX != deltaH)
- {
- continue;
- }
- }
-
- // Y-axis checking (only find Actors to the [dirY] of actualPosition)
- if(dirY > All) // != All,None
- {
- FindDirection deltaV = delta.y > 0 ? Down : Up;
- if(dirY != deltaV)
- {
- continue;
- }
- }
-
- // Z-axis checking (only find Actors to the [dirZ] of actualPosition)
- if(dirZ > All) // != All,None
- {
- FindDirection deltaV = delta.y > 0 ? In : Out;
- if(dirZ != deltaV)
- {
- continue;
- }
- }
-
- // compare child to closest child in terms of distance.
- float distance2 = 0.0f;
-
- // distance2 = the Square of the relevant dimensions of delta
- if(dirX != None)
- {
- distance2 += delta.x * delta.x;
- }
-
- if(dirY != None)
- {
- distance2 += delta.y * delta.y;
- }
-
- if(dirZ != None)
- {
- distance2 += delta.z * delta.z;
- }
-
- if(closestChild) // Next time.
- {
- if(distance2 < closestDistance2)
- {
- closestChild = child;
- closestDistance2 = distance2;
- }
- }
- else // First time.
- {
- closestChild = child;
- closestDistance2 = distance2;
- }
- }
-
- return closestChild;
-}
-
-bool ScrollView::ScrollToSnapPoint()
-{
- DALI_LOG_SCROLL_STATE("[0x%X]", this );
- Vector2 stationaryVelocity = Vector2(0.0f, 0.0f);
- return SnapWithVelocity( stationaryVelocity );
-}
-
-// TODO: In situations where axes are different (X snap, Y free)
-// Each axis should really have their own independent animation (time and equation)
-// Consider, X axis snapping to nearest grid point (EaseOut over fixed time)
-// Consider, Y axis simulating physics to arrive at a point (Physics equation over variable time)
-// Currently, the axes have been split however, they both use the same EaseOut equation.
-bool ScrollView::SnapWithVelocity(Vector2 velocity)
-{
- // Animator takes over now, touches are assumed not to interfere.
- // And if touches do interfere, then we'll stop animation, update PrePosition
- // to current mScroll's properties, and then resume.
- // Note: For Flicking this may work a bit different...
-
- float angle = atan2(velocity.y, velocity.x);
- float speed2 = velocity.LengthSquared();
- AlphaFunction alphaFunction = mSnapAlphaFunction;
- Vector2 positionDuration = Vector2::ONE * mSnapDuration;
- float biasX = 0.5f;
- float biasY = 0.5f;
- FindDirection horizontal = None;
- FindDirection vertical = None;
-
- // orthoAngleRange = Angle tolerance within the Exact N,E,S,W direction
- // that will be accepted as a general N,E,S,W flick direction.
-
- const float orthoAngleRange = FLICK_ORTHO_ANGLE_RANGE * M_PI / 180.0f;
- const float flickSpeedThreshold2 = mFlickSpeedThreshold * mFlickSpeedThreshold;
-
- Vector2 positionSnap = mScrollPrePosition;
-
- // Flick logic X Axis
-
- if(mRulerX->IsEnabled() && mLockAxis != LockHorizontal)
- {
- horizontal = All;
-
- if( speed2 > flickSpeedThreshold2 || // exceeds flick threshold
- mInAccessibilityPan ) // With AccessibilityPan its easier to move between snap positions
- {
- if((angle >= -orthoAngleRange) && (angle < orthoAngleRange)) // Swiping East
- {
- biasX = 0.0f, horizontal = Left;
-
- // This guards against an error where no movement occurs, due to the flick finishing
- // before the update-thread has advanced mScrollPostPosition past the the previous snap point.
- positionSnap.x += 1.0f;
- }
- else if((angle >= M_PI-orthoAngleRange) || (angle < -M_PI+orthoAngleRange)) // Swiping West
- {
- biasX = 1.0f, horizontal = Right;
-
- // This guards against an error where no movement occurs, due to the flick finishing
- // before the update-thread has advanced mScrollPostPosition past the the previous snap point.
- positionSnap.x -= 1.0f;
- }
- }
- }
-
- // Flick logic Y Axis
-
- if(mRulerY->IsEnabled() && mLockAxis != LockVertical)
- {
- vertical = All;
-
- if( speed2 > flickSpeedThreshold2 || // exceeds flick threshold
- mInAccessibilityPan ) // With AccessibilityPan its easier to move between snap positions
- {
- if((angle >= M_PI_2-orthoAngleRange) && (angle < M_PI_2+orthoAngleRange)) // Swiping South
- {
- biasY = 0.0f, vertical = Up;
- }
- else if((angle >= -M_PI_2-orthoAngleRange) && (angle < -M_PI_2+orthoAngleRange)) // Swiping North
- {
- biasY = 1.0f, vertical = Down;
- }
- }
- }
-
- // isFlick: Whether this gesture is a flick or not.
- bool isFlick = (horizontal != All || vertical != All);
- // isFreeFlick: Whether this gesture is a flick under free panning criteria.
- bool isFreeFlick = velocity.LengthSquared() > (FREE_FLICK_SPEED_THRESHOLD*FREE_FLICK_SPEED_THRESHOLD);
-
- if(isFlick || isFreeFlick)
- {
- positionDuration = Vector2::ONE * mFlickDuration;
- alphaFunction = mFlickAlphaFunction;
- }
-
- // Calculate next positionSnap ////////////////////////////////////////////////////////////
-
- if(mActorAutoSnapEnabled)
- {
- Vector3 size = Self().GetCurrentSize();