From: David Steele Date: Thu, 21 Oct 2021 16:53:19 +0000 (+0100) Subject: Refactoring scroll-view-impl.cpp to reduce loc X-Git-Tag: dali_2.0.49~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=61341cddafc30912d5247867b3f20e424edeff1b;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git Refactoring scroll-view-impl.cpp to reduce loc Change-Id: I7699976711d4a9ab24092ca8f07106e524409b63 --- diff --git a/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp b/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp index 8ca6855..708830f 100644 --- a/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp +++ b/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp @@ -154,6 +154,107 @@ Vector3 GetPositionOfAnchor(Actor& actor, const Vector3& anchor) return childPosition + childAnchor * childSize; } +/** + * Returns the closest actor to the given position + * @param[in] actor The scrollview actor + * @param[in] internalActor The internal actor (to ignore) + * @param[in] position The given position + * @param[in] dirX Direction to search in + * @param[in] dirY Direction to search in + * @param[in] dirZ Direction to search in + * @return the closest child actor + */ +using FindDirection = Dali::Toolkit::Internal::ScrollView::FindDirection; + +Actor FindClosestActorToPosition( + CustomActor actor, Actor internalActor, const Vector3& position, FindDirection dirX, FindDirection dirY, FindDirection dirZ) +{ + Actor closestChild; + float closestDistance2 = 0.0f; + Vector3 actualPosition = position; + + unsigned int numChildren = actor.GetChildCount(); + + for(unsigned int i = 0; i < numChildren; ++i) + { + Actor child = actor.GetChildAt(i); + + if(internalActor == 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 > FindDirection::All) // != All,None + { + FindDirection deltaH = delta.x > 0 ? FindDirection::Right : FindDirection::Left; + if(dirX != deltaH) + { + continue; + } + } + + // Y-axis checking (only find Actors to the [dirY] of actualPosition) + if(dirY > FindDirection::All) // != All,None + { + FindDirection deltaV = delta.y > 0 ? FindDirection::Down : FindDirection::Up; + if(dirY != deltaV) + { + continue; + } + } + + // Z-axis checking (only find Actors to the [dirZ] of actualPosition) + if(dirZ > FindDirection::All) // != All,None + { + FindDirection deltaV = delta.y > 0 ? FindDirection::In : FindDirection::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 != FindDirection::None) + { + distance2 += delta.x * delta.x; + } + + if(dirY != FindDirection::None) + { + distance2 += delta.y * delta.y; + } + + if(dirZ != FindDirection::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; +} + // AlphaFunctions ///////////////////////////////////////////////////////////////////////////////// float FinalDefaultAlphaFunction(float offset) @@ -227,6 +328,259 @@ void InternalPrePositionMaxConstraint(Vector2& scrollMax, const PropertyInputCon scrollMax = max - size.GetVectorXY(); } +/** + * Clamp a position + * @param[in] size The size to clamp to + * @param[in] rulerX The horizontal ruler + * @param[in] rulerY The vertical ruler + * @param[in,out] position The position to clamp + * @param[out] clamped the clamped state + */ +void ClampPosition(const Vector3& size, Dali::Toolkit::RulerPtr rulerX, Dali::Toolkit::RulerPtr rulerY, Vector2& position, Dali::Toolkit::ClampState2D& clamped) +{ + position.x = -rulerX->Clamp(-position.x, size.width, 1.0f, clamped.x); // NOTE: X & Y rulers think in -ve coordinate system. + position.y = -rulerY->Clamp(-position.y, size.height, 1.0f, clamped.y); // That is scrolling RIGHT (e.g. 100.0, 0.0) means moving LEFT. +} + +/** + * 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. + * + * @param[in] scrollView The main scrollview + * @param[in] rulerX The X ruler + * @param[in] rulerY The Y ruler + * @param[in] lockAxis Which axis (if any) is locked. + * @param[in] velocity Current pan velocity + * @param[in] maxOvershoot Maximum overshoot + * @param[in] inAcessibilityPan True if we are currently panning with accessibility + * @param[out] positionSnap The target position of snap animation + * @param[out] positionDuration The duration of the snap animation + * @param[out] alphaFunction The snap animation alpha function + * @param[out] isFlick if we are flicking or not + * @param[out] isFreeFlick if we are free flicking or not + */ +void SnapWithVelocity( + Dali::Toolkit::Internal::ScrollView& scrollView, + Dali::Toolkit::RulerPtr rulerX, + Dali::Toolkit::RulerPtr rulerY, + Dali::Toolkit::Internal::ScrollView::LockAxis lockAxis, + Vector2 velocity, + Vector2 maxOvershoot, + Vector2& positionSnap, + Vector2& positionDuration, + AlphaFunction& alphaFunction, + bool inAccessibilityPan, + bool& isFlick, + bool& isFreeFlick) +{ + // 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(); + float biasX = 0.5f; + float biasY = 0.5f; + FindDirection horizontal = FindDirection::None; + FindDirection vertical = FindDirection::None; + + using LockAxis = Dali::Toolkit::Internal::ScrollView::LockAxis; + + // 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 = scrollView.GetMinimumSpeedForFlick() * scrollView.GetMinimumSpeedForFlick(); + + // Flick logic X Axis + + if(rulerX->IsEnabled() && lockAxis != LockAxis::LockHorizontal) + { + horizontal = FindDirection::All; + + if(speed2 > flickSpeedThreshold2 || // exceeds flick threshold + inAccessibilityPan) // With AccessibilityPan its easier to move between snap positions + { + if((angle >= -orthoAngleRange) && (angle < orthoAngleRange)) // Swiping East + { + biasX = 0.0f, horizontal = FindDirection::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 = FindDirection::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(rulerY->IsEnabled() && lockAxis != LockAxis::LockVertical) + { + vertical = FindDirection::All; + + if(speed2 > flickSpeedThreshold2 || // exceeds flick threshold + inAccessibilityPan) // 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 = FindDirection::Up; + } + else if((angle >= -M_PI_2 - orthoAngleRange) && (angle < -M_PI_2 + orthoAngleRange)) // Swiping North + { + biasY = 1.0f, vertical = FindDirection::Down; + } + } + } + + // isFlick: Whether this gesture is a flick or not. + isFlick = (horizontal != FindDirection::All || vertical != FindDirection::All); + // isFreeFlick: Whether this gesture is a flick under free panning criteria. + isFreeFlick = velocity.LengthSquared() > (FREE_FLICK_SPEED_THRESHOLD * FREE_FLICK_SPEED_THRESHOLD); + + if(isFlick || isFreeFlick) + { + positionDuration = Vector2::ONE * scrollView.GetScrollFlickDuration(); + alphaFunction = scrollView.GetScrollFlickAlphaFunction(); + } + + // Calculate next positionSnap //////////////////////////////////////////////////////////// + + if(scrollView.GetActorAutoSnap()) + { + Vector3 size = scrollView.Self().GetCurrentProperty(Actor::Property::SIZE); + + Actor child = scrollView.FindClosestActorToPosition(Vector3(size.width * 0.5f, size.height * 0.5f, 0.0f), horizontal, vertical); + + if(!child && isFlick) + { + // If we conducted a direction limited search and found no actor, then just snap to the closest actor. + child = scrollView.FindClosestActorToPosition(Vector3(size.width * 0.5f, size.height * 0.5f, 0.0f)); + } + + if(child) + { + Vector2 position = scrollView.Self().GetCurrentProperty(Toolkit::ScrollView::Property::SCROLL_POSITION); + + // Get center-point of the Actor. + Vector3 childPosition = GetPositionOfAnchor(child, AnchorPoint::CENTER); + + if(rulerX->IsEnabled()) + { + positionSnap.x = position.x - childPosition.x + size.width * 0.5f; + } + if(rulerY->IsEnabled()) + { + positionSnap.y = position.y - childPosition.y + size.height * 0.5f; + } + } + } + + Vector2 startPosition = positionSnap; + positionSnap.x = -rulerX->Snap(-positionSnap.x, biasX); // NOTE: X & Y rulers think in -ve coordinate system. + positionSnap.y = -rulerY->Snap(-positionSnap.y, biasY); // That is scrolling RIGHT (e.g. 100.0, 0.0) means moving LEFT. + + Dali::Toolkit::ClampState2D clamped; + Vector3 size = scrollView.Self().GetCurrentProperty(Actor::Property::SIZE); + Vector2 clampDelta(Vector2::ZERO); + ClampPosition(size, rulerX, rulerY, positionSnap, clamped); + + if((rulerX->GetType() == Dali::Toolkit::Ruler::FREE || rulerY->GetType() == Dali::Toolkit::Ruler::FREE) && + isFreeFlick && !scrollView.GetActorAutoSnap()) + { + // Calculate target position based on velocity of flick. + + // a = Deceleration (Set to diagonal stage length * friction coefficient) + // u = Initial Velocity (Flick velocity) + // v = 0 (Final Velocity) + // t = Time (Velocity / Deceleration) + Vector2 stageSize = Stage::GetCurrent().GetSize(); + float stageLength = Vector3(stageSize.x, stageSize.y, 0.0f).Length(); + float a = (stageLength * scrollView.GetFrictionCoefficient()); + Vector3 u = Vector3(velocity.x, velocity.y, 0.0f) * scrollView.GetFlickSpeedCoefficient(); + float speed = u.Length(); + u /= speed; + + // TODO: Change this to a decay function. (faster you flick, the slower it should be) + speed = std::min(speed, stageLength * scrollView.GetMaxFlickSpeed()); + u *= speed; + alphaFunction = ConstantDecelerationAlphaFunction; + + float t = speed / a; + + if(rulerX->IsEnabled() && rulerX->GetType() == Dali::Toolkit::Ruler::FREE) + { + positionSnap.x += t * u.x * 0.5f; + } + + if(rulerY->IsEnabled() && rulerY->GetType() == Dali::Toolkit::Ruler::FREE) + { + positionSnap.y += t * u.y * 0.5f; + } + + clampDelta = positionSnap; + ClampPosition(size, rulerX, rulerY, positionSnap, clamped); + + if((positionSnap - startPosition).LengthSquared() > Math::MACHINE_EPSILON_0) + { + clampDelta -= positionSnap; + clampDelta.x = clampDelta.x > 0.0f ? std::min(clampDelta.x, maxOvershoot.x) : std::max(clampDelta.x, -maxOvershoot.x); + clampDelta.y = clampDelta.y > 0.0f ? std::min(clampDelta.y, maxOvershoot.y) : std::max(clampDelta.y, -maxOvershoot.y); + } + else + { + clampDelta = Vector2::ZERO; + } + + // If Axis is Free and has velocity, then calculate time taken + // to reach target based on velocity in axis. + if(rulerX->IsEnabled() && rulerX->GetType() == Dali::Toolkit::Ruler::FREE) + { + float deltaX = fabsf(startPosition.x - positionSnap.x); + + if(fabsf(u.x) > Math::MACHINE_EPSILON_1) + { + positionDuration.x = fabsf(deltaX / u.x); + } + else + { + positionDuration.x = 0; + } + } + + if(rulerY->IsEnabled() && rulerY->GetType() == Dali::Toolkit::Ruler::FREE) + { + float deltaY = fabsf(startPosition.y - positionSnap.y); + + if(fabsf(u.y) > Math::MACHINE_EPSILON_1) + { + positionDuration.y = fabsf(deltaY / u.y); + } + else + { + positionDuration.y = 0; + } + } + } + + if(scrollView.IsOvershootEnabled()) + { + // Scroll to the end of the overshoot only when overshoot is enabled. + positionSnap += clampDelta; + } +} + } // unnamed namespace namespace Dali @@ -1345,90 +1699,7 @@ Actor ScrollView::FindClosestActor() 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; + return ::FindClosestActorToPosition(Self(), mInternalActor, position, dirX, dirY, dirZ); } bool ScrollView::ScrollToSnapPoint() @@ -1438,214 +1709,15 @@ bool ScrollView::ScrollToSnapPoint() 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 positionSnap = mScrollPrePosition; 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().GetCurrentProperty(Actor::Property::SIZE); - - Actor child = FindClosestActorToPosition(Vector3(size.width * 0.5f, size.height * 0.5f, 0.0f), horizontal, vertical); - - if(!child && isFlick) - { - // If we conducted a direction limited search and found no actor, then just snap to the closest actor. - child = FindClosestActorToPosition(Vector3(size.width * 0.5f, size.height * 0.5f, 0.0f)); - } - - if(child) - { - Vector2 position = Self().GetCurrentProperty(Toolkit::ScrollView::Property::SCROLL_POSITION); - - // Get center-point of the Actor. - Vector3 childPosition = GetPositionOfAnchor(child, AnchorPoint::CENTER); - - if(mRulerX->IsEnabled()) - { - positionSnap.x = position.x - childPosition.x + size.width * 0.5f; - } - if(mRulerY->IsEnabled()) - { - positionSnap.y = position.y - childPosition.y + size.height * 0.5f; - } - } - } - - Vector2 startPosition = positionSnap; - positionSnap.x = -mRulerX->Snap(-positionSnap.x, biasX); // NOTE: X & Y rulers think in -ve coordinate system. - positionSnap.y = -mRulerY->Snap(-positionSnap.y, biasY); // That is scrolling RIGHT (e.g. 100.0, 0.0) means moving LEFT. - - Vector2 clampDelta(Vector2::ZERO); - ClampPosition(positionSnap); - - if((mRulerX->GetType() == Ruler::FREE || mRulerY->GetType() == Ruler::FREE) && isFreeFlick && !mActorAutoSnapEnabled) - { - // Calculate target position based on velocity of flick. - - // a = Deceleration (Set to diagonal stage length * friction coefficient) - // u = Initial Velocity (Flick velocity) - // v = 0 (Final Velocity) - // t = Time (Velocity / Deceleration) - Vector2 stageSize = Stage::GetCurrent().GetSize(); - float stageLength = Vector3(stageSize.x, stageSize.y, 0.0f).Length(); - float a = (stageLength * mFrictionCoefficient); - Vector3 u = Vector3(velocity.x, velocity.y, 0.0f) * mFlickSpeedCoefficient; - float speed = u.Length(); - u /= speed; - - // TODO: Change this to a decay function. (faster you flick, the slower it should be) - speed = std::min(speed, stageLength * mMaxFlickSpeed); - u *= speed; - alphaFunction = ConstantDecelerationAlphaFunction; - - float t = speed / a; - - if(mRulerX->IsEnabled() && mRulerX->GetType() == Ruler::FREE) - { - positionSnap.x += t * u.x * 0.5f; - } - - if(mRulerY->IsEnabled() && mRulerY->GetType() == Ruler::FREE) - { - positionSnap.y += t * u.y * 0.5f; - } - - clampDelta = positionSnap; - ClampPosition(positionSnap); - if((positionSnap - startPosition).LengthSquared() > Math::MACHINE_EPSILON_0) - { - clampDelta -= positionSnap; - clampDelta.x = clampDelta.x > 0.0f ? std::min(clampDelta.x, mMaxOvershoot.x) : std::max(clampDelta.x, -mMaxOvershoot.x); - clampDelta.y = clampDelta.y > 0.0f ? std::min(clampDelta.y, mMaxOvershoot.y) : std::max(clampDelta.y, -mMaxOvershoot.y); - } - else - { - clampDelta = Vector2::ZERO; - } - - // If Axis is Free and has velocity, then calculate time taken - // to reach target based on velocity in axis. - if(mRulerX->IsEnabled() && mRulerX->GetType() == Ruler::FREE) - { - float deltaX = fabsf(startPosition.x - positionSnap.x); - - if(fabsf(u.x) > Math::MACHINE_EPSILON_1) - { - positionDuration.x = fabsf(deltaX / u.x); - } - else - { - positionDuration.x = 0; - } - } - - if(mRulerY->IsEnabled() && mRulerY->GetType() == Ruler::FREE) - { - float deltaY = fabsf(startPosition.y - positionSnap.y); - - if(fabsf(u.y) > Math::MACHINE_EPSILON_1) - { - positionDuration.y = fabsf(deltaY / u.y); - } - else - { - positionDuration.y = 0; - } - } - } + AlphaFunction alphaFunction = mSnapAlphaFunction; + bool isFlick; + bool isFreeFlick; - if(IsOvershootEnabled()) - { - // Scroll to the end of the overshoot only when overshoot is enabled. - positionSnap += clampDelta; - } + ::SnapWithVelocity(*this, mRulerX, mRulerY, mLockAxis, velocity, mMaxOvershoot, positionSnap, positionDuration, alphaFunction, mInAccessibilityPan, isFlick, isFreeFlick); bool animating = AnimateTo(positionSnap, positionDuration, alphaFunction, false, DIRECTION_BIAS_NONE, DIRECTION_BIAS_NONE, isFlick || isFreeFlick ? FLICK : SNAP); @@ -1826,7 +1898,7 @@ Toolkit::ScrollView::SnapStartedSignalType& ScrollView::SnapStartedSignal() bool ScrollView::AccessibleImpl::ScrollToChild(Actor child) { auto scrollView = Dali::Toolkit::ScrollView::DownCast(Self()); - if (Toolkit::GetImpl(scrollView).FindClosestActor() == child) + if(Toolkit::GetImpl(scrollView).FindClosestActor() == child) { return false; } @@ -2704,8 +2776,7 @@ void ScrollView::ClampPosition(Vector2& position, ClampState2D& clamped) const { Vector3 size = Self().GetCurrentProperty(Actor::Property::SIZE); - position.x = -mRulerX->Clamp(-position.x, size.width, 1.0f, clamped.x); // NOTE: X & Y rulers think in -ve coordinate system. - position.y = -mRulerY->Clamp(-position.y, size.height, 1.0f, clamped.y); // That is scrolling RIGHT (e.g. 100.0, 0.0) means moving LEFT. + ::ClampPosition(size, mRulerX, mRulerY, position, clamped); } void ScrollView::WrapPosition(Vector2& position) const