From 421b1cb023ab3a51842d1c7dab553e241c2301d0 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Fri, 12 Dec 2014 15:10:42 +0000 Subject: [PATCH] Change overshoot to have constant speed as a property Change-Id: Ie5264aa8950713b9c62be2689f57dfe3adb199da --- .../scrollable/item-view/item-view-impl.cpp | 48 +++++++++++----------- .../scroll-overshoot-indicator-impl.cpp | 47 +++++++-------------- .../scroll-view/scroll-overshoot-indicator-impl.h | 7 +--- .../scrollable/scroll-view/scroll-view-impl.cpp | 5 +-- .../controls/scrollable/scrollable-impl.cpp | 30 ++++++++++++++ .../internal/controls/scrollable/scrollable-impl.h | 11 +++++ .../public-api/controls/scrollable/scrollable.cpp | 10 +++++ .../public-api/controls/scrollable/scrollable.h | 14 +++++++ 8 files changed, 105 insertions(+), 67 deletions(-) diff --git a/base/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp b/base/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp index 708d98f..6d4d4b8 100644 --- a/base/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp +++ b/base/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp @@ -59,8 +59,6 @@ const float MILLISECONDS_PER_SECONDS = 1000.0f; const Vector2 OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE( 720.0f, 42.0f ); const float OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD = 180.0f; const Vector4 OVERSHOOT_OVERLAY_NINE_PATCH_BORDER(0.0f, 0.0f, 1.0f, 12.0f); -const float MAXIMUM_OVERSHOOT_HEIGHT = 36.0f; // 36 pixels -const float DEFAULT_OVERSHOOT_ANIMATION_DURATION = 0.5f; // 0.5 second const float DEFAULT_KEYBOARD_FOCUS_SCROLL_DURATION = 0.2f; const string LAYOUT_POSITION_PROPERTY_NAME( "item-view-layout-position" ); @@ -1256,23 +1254,18 @@ void ItemView::OnPan( const PanGesture& gesture ) float firstItemScrollPosition = ClampFirstItemPosition(layoutPositionDelta, layoutSize, *mActiveLayout); + float currentOvershoot = mScrollPositionObject.GetProperty(ScrollConnector::OVERSHOOT); + mScrollPositionObject.SetProperty( ScrollConnector::SCROLL_POSITION, firstItemScrollPosition ); self.SetProperty(mPropertyPosition, GetScrollPosition(firstItemScrollPosition, layoutSize)); - mTotalPanDisplacement += gesture.displacement; - mScrollOvershoot = layoutPositionDelta - firstItemScrollPosition; - if( mScrollOvershoot > Math::MACHINE_EPSILON_1 ) - { - AnimateScrollOvershoot(1.0f); - } - else if( mScrollOvershoot < -Math::MACHINE_EPSILON_1 ) - { - AnimateScrollOvershoot(-1.0f); - } - else + if( (firstItemScrollPosition >= 0.0f && currentOvershoot < 1.0f) || (firstItemScrollPosition <= mActiveLayout->GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), layoutSize) && currentOvershoot > -1.0f) ) { - AnimateScrollOvershoot(0.0f); + mTotalPanDisplacement += gesture.displacement; } + + mScrollOvershoot = CalculateScrollOvershoot(); + mScrollPositionObject.SetProperty( ScrollConnector::OVERSHOOT, mScrollOvershoot ); } break; @@ -1600,7 +1593,6 @@ void ItemView::SetOvershootEnabled( bool enable ) OvershootOverlayVisibilityConstraint() ); mOvershootOverlay.ApplyConstraint(constraint); - Actor self = Self(); constraint = Constraint::New( effectOvershootPropertyIndex, Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ), EqualToConstraint() ); @@ -1633,7 +1625,7 @@ float ItemView::CalculateScrollOvershoot() overshoot = positionDelta - clamppedPosition; } - return overshoot; + return overshoot > 0.0f ? std::min(overshoot, 1.0f) : std::max(overshoot, -1.0f); } void ItemView::AnimateScrollOvershoot(float overshootAmount, bool animateBack) @@ -1649,17 +1641,23 @@ void ItemView::AnimateScrollOvershoot(float overshootAmount, bool animateBack) return; } - Actor self = Self(); - float currentOvershoot = mScrollPositionObject.GetProperty(ScrollConnector::OVERSHOOT); - float duration = DEFAULT_OVERSHOOT_ANIMATION_DURATION * (animatingOn ? (1.0f - fabsf(currentOvershoot)) : fabsf(currentOvershoot)); + if(mOvershootAnimationSpeed > Math::MACHINE_EPSILON_0) + { + float currentOvershoot = mScrollPositionObject.GetProperty(ScrollConnector::OVERSHOOT); + float duration = mOvershootOverlay.GetCurrentSize().height * (animatingOn ? (1.0f - fabsf(currentOvershoot)) : fabsf(currentOvershoot)) / mOvershootAnimationSpeed; - RemoveAnimation(mScrollOvershootAnimation); - mScrollOvershootAnimation = Animation::New(duration); - mScrollOvershootAnimation.FinishedSignal().Connect(this, &ItemView::OnOvershootOnFinished); - mScrollOvershootAnimation.AnimateTo( Property(mScrollPositionObject, ScrollConnector::OVERSHOOT), overshootAmount, TimePeriod(0.0f, duration) ); - mScrollOvershootAnimation.Play(); + RemoveAnimation(mScrollOvershootAnimation); + mScrollOvershootAnimation = Animation::New(duration); + mScrollOvershootAnimation.FinishedSignal().Connect(this, &ItemView::OnOvershootOnFinished); + mScrollOvershootAnimation.AnimateTo( Property(mScrollPositionObject, ScrollConnector::OVERSHOOT), overshootAmount, TimePeriod(0.0f, duration) ); + mScrollOvershootAnimation.Play(); - mAnimatingOvershootOn = animatingOn; + mAnimatingOvershootOn = animatingOn; + } + else + { + mScrollPositionObject.SetProperty( ScrollConnector::OVERSHOOT, overshootAmount ); + } } void ItemView::SetItemsParentOrigin( const Vector3& parentOrigin ) diff --git a/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.cpp b/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.cpp index e6876dc..26c3af8 100644 --- a/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.cpp +++ b/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.cpp @@ -30,7 +30,6 @@ using namespace Dali; namespace { -const float DEFAULT_MAX_OVERSHOOT_HEIGHT = 36.0f; // 36 pixels const Vector2 OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE( 720.0f, 42.0f ); const float OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD = 180.0f; @@ -40,10 +39,9 @@ float GetBounceActorHeight( float width ) return (width > OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD) ? OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height : OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height * 0.5f; } -const float DEFAULT_OVERSHOOT_ANIMATION_DURATION = 0.35f; // time in seconds -const float MAX_OVERSHOOT_NOTIFY_AMOUNT = 0.9f; // maximum amount to set notification for increased overshoot, beyond this we just wait for it to reduce again -const float MIN_OVERSHOOT_NOTIFY_AMOUNT = Math::MACHINE_EPSILON_1; // minimum amount to set notification for reduced overshoot, beyond this we just wait for it to increase again -const float OVERSHOOT_NOTIFY_STEP = 0.1f; // amount to set notifications beyond current overshoot value +const float MAX_OVERSHOOT_NOTIFY_AMOUNT = 0.99f; // maximum amount to set notification for increased overshoot, beyond this we just wait for it to reduce again +const float MIN_OVERSHOOT_NOTIFY_AMOUNT = Math::MACHINE_EPSILON_0; // minimum amount to set notification for reduced overshoot, beyond this we just wait for it to increase again +const float OVERSHOOT_NOTIFY_STEP = 0.01f; // amount to set notifications beyond current overshoot value } @@ -143,11 +141,8 @@ bool ScrollOvershootEffect::IsVertical() const ScrollOvershootEffectRipple::ScrollOvershootEffectRipple( bool vertical, Scrollable& scrollable ) : ScrollOvershootEffect( vertical ), mAttachedScrollView(scrollable), - mCanScrollPropertyIndex(Property::INVALID_INDEX), mOvershootProperty(Property::INVALID_INDEX), mEffectOvershootProperty(Property::INVALID_INDEX), - mMaxOvershootImageSize(DEFAULT_MAX_OVERSHOOT_HEIGHT), - mOvershootAnimationDuration(DEFAULT_OVERSHOOT_ANIMATION_DURATION), mOvershoot(0.0f), mAnimationStateFlags(0) { @@ -164,7 +159,6 @@ void ScrollOvershootEffectRipple::Apply() { Actor self = mAttachedScrollView.Self(); mOvershootProperty = self.GetPropertyIndex(IsVertical() ? Toolkit::ScrollView::SCROLL_OVERSHOOT_Y_PROPERTY_NAME : Toolkit::ScrollView::SCROLL_OVERSHOOT_X_PROPERTY_NAME); - mCanScrollPropertyIndex = self.GetPropertyIndex(IsVertical() ? Scrollable::SCROLLABLE_CAN_SCROLL_VERTICAL : Scrollable::SCROLLABLE_CAN_SCROLL_HORIZONTAL); // make sure height is set, since we only create a constraint for image width mOvershootOverlay.SetSize(OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.width, OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height); @@ -301,22 +295,7 @@ void ScrollOvershootEffectRipple::OnOvershootNotification(PropertyNotification& { Actor self = mAttachedScrollView.Self(); mOvershoot = self.GetProperty(mOvershootProperty); - if( source == mOvershootIncreaseNotification ) - { - if( mOvershoot > Math::MACHINE_EPSILON_0 ) - { - SetOvershoot(1.0f); - } - else if ( mOvershoot < -Math::MACHINE_EPSILON_0 ) - { - SetOvershoot(-1.0f); - } - } - else if( source == mOvershootDecreaseNotification ) - { - SetOvershoot(0.0f); - // overshoot reducing - } + SetOvershoot(mOvershoot, false); UpdatePropertyNotifications(); } @@ -344,12 +323,18 @@ void ScrollOvershootEffectRipple::SetOvershoot(float amount, bool animate) mAnimationStateFlags |= AnimateBack; return; } - // When we need to animate overshoot to 0 - if( mOvershootAnimationDuration > Math::MACHINE_EPSILON_1 ) + + if( absAmount > Math::MACHINE_EPSILON_1 ) + { + UpdateVisibility(true); + } + + float overshootAnimationSpeed = mAttachedScrollView.Self().GetProperty(Toolkit::Scrollable::PROPERTY_OVERSHOOT_ANIMATION_SPEED); + + if( animate && overshootAnimationSpeed > Math::MACHINE_EPSILON_0 ) { - // setup the new overshoot to 0 animation float currentOvershoot = fabsf( mOvershootOverlay.GetProperty( mEffectOvershootProperty ).Get() ); - float duration = mOvershootAnimationDuration * (animatingOn ? (1.0f - currentOvershoot) : currentOvershoot); + float duration = mOvershootOverlay.GetCurrentSize().height * (animatingOn ? (1.0f - currentOvershoot) : currentOvershoot) / overshootAnimationSpeed; if( duration > Math::MACHINE_EPSILON_0 ) { @@ -370,10 +355,6 @@ void ScrollOvershootEffectRipple::SetOvershoot(float amount, bool animate) { mOvershootOverlay.SetProperty( mEffectOvershootProperty, amount); } - if( absAmount > Math::MACHINE_EPSILON_1 ) - { - UpdateVisibility(true); - } } void ScrollOvershootEffectRipple::OnOvershootAnimFinished(Animation& animation) diff --git a/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.h b/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.h index b0e904a..f19e39c 100644 --- a/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.h +++ b/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.h @@ -254,13 +254,10 @@ private: Animation mScrollOvershootAnimation; ///< overshoot animation PropertyNotification mOvershootIncreaseNotification;///< notification used to inform as overshoot increases PropertyNotification mOvershootDecreaseNotification;///< notification used to inform as overshoot decreases - Property::Index mCanScrollPropertyIndex; ///< property index to a property that informs indicator if it is needed Property::Index mOvershootProperty; ///< index of the overshoot property in the scrollable actor Property::Index mEffectOvershootProperty; ///< index of the effect's overshoot property - float mMaxOvershootImageSize; ///< maximum height of the image when overshoot value is 1.0f - float mOvershootAnimationDuration; ///< time taken for overshoot to go from fully offscreen to fully onscreen and vice versa - float mOvershoot; ///< last overshoot value as detected by notifications - unsigned short mAnimationStateFlags; ///< contains flags indicating the current state of the overshoot animation + float mOvershoot; ///< last overshoot value as detected by notifications + unsigned short mAnimationStateFlags; ///< contains flags indicating the current state of the overshoot animation }; } // namespace Internal diff --git a/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp b/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp index 792f33a..e2df7a5 100644 --- a/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp +++ b/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp @@ -61,8 +61,6 @@ const float FLICK_ORTHO_ANGLE_RANGE = 75.0f; const unsigned int MAXIMUM_NUMBER_OF_VALUES = 5; ///< Number of values to use for weighted pan calculation. const Vector2 DEFAULT_MOUSE_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION = Vector2(0.17f, 0.1f); ///< The step of horizontal scroll distance in the proportion of stage size for each mouse wheel event received. const unsigned long MINIMUM_TIME_BETWEEN_DOWN_AND_UP_FOR_RESET( 150u ); -const float DEFAULT_OVERSHOOT_ANIMATION_DURATION = 0.35f; // time in seconds -const Vector2 OVERSCROLL_CLAMP(1.0f, 1.0f); // maximum overscroll allowed in pixels when overshoot indicator is being used const float TOUCH_DOWN_TIMER_INTERVAL = 100.0f; const float DEFAULT_SCROLL_UPDATE_DISTANCE( 30.0f ); ///< Default distance to travel in pixels for scroll update signal @@ -1308,7 +1306,7 @@ void ScrollView::ScrollTo(const Vector3& position, float duration, void ScrollView::ScrollTo(const Vector3& position, float duration, AlphaFunction alpha, DirectionBias horizontalBias, DirectionBias verticalBias) { - DALI_LOG_SCROLL_STATE("[0x%X] position[%.2f, %.2f] duration[%.2f]", this, position.x, position.y, duration, int(horizontalBias), int(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); } @@ -1776,7 +1774,6 @@ void ScrollView::SetOvershootEnabled(bool enabled) } if( enabled ) { - mMaxOvershoot = OVERSCROLL_CLAMP; mOvershootIndicator->AttachToScrollable(*this); } else diff --git a/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp b/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp index 27bd343..e378a3d 100644 --- a/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp +++ b/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp @@ -36,6 +36,7 @@ namespace Toolkit { const Property::Index Scrollable::PROPERTY_OVERSHOOT_EFFECT_COLOR( Toolkit::Internal::Control::CONTROL_PROPERTY_END_INDEX + 1 ); +const Property::Index Scrollable::PROPERTY_OVERSHOOT_ANIMATION_SPEED( Toolkit::Internal::Control::CONTROL_PROPERTY_END_INDEX + 2 ); namespace Internal { @@ -43,6 +44,7 @@ namespace Internal namespace { const Vector4 DEFAULT_OVERSHOOT_COLOUR(0.0f, 0.64f, 0.85f, 0.25f); +const float DEFAULT_OVERSHOOT_ANIMATION_SPEED(120.0f); // 120 pixels per second BaseHandle Create() { @@ -64,6 +66,13 @@ PropertyRegistration property1( mType, &Scrollable::SetProperty, &Scrollable::GetProperty ); +PropertyRegistration property2( mType, + "overshoot-animation-speed", + Toolkit::Scrollable::PROPERTY_OVERSHOOT_ANIMATION_SPEED, + Property::FLOAT, + &Scrollable::SetProperty, + &Scrollable::GetProperty ); + } const std::string Scrollable::SCROLLABLE_CAN_SCROLL_VERTICAL( "scrollable-can-scroll-vertical" ); @@ -78,6 +87,7 @@ const std::string Scrollable::SCROLLABLE_CAN_SCROLL_HORIZONTAL( "scrollable-can- Scrollable::Scrollable() : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS | NO_SIZE_NEGOTIATION ) ), mOvershootEffectColor( DEFAULT_OVERSHOOT_COLOUR ), + mOvershootAnimationSpeed ( DEFAULT_OVERSHOOT_ANIMATION_SPEED ), mPropertyRelativePosition(Property::INVALID_INDEX), mPropertyPositionMin(Property::INVALID_INDEX), mPropertyPositionMax(Property::INVALID_INDEX), @@ -169,6 +179,16 @@ Vector4 Scrollable::GetOvershootEffectColor() const return mOvershootEffectColor; }; +void Scrollable::SetOvershootAnimationSpeed( float pixelsPerSecond ) +{ + mOvershootAnimationSpeed = pixelsPerSecond; +} + +float Scrollable::GetOvershootAnimationSpeed() const +{ + return mOvershootAnimationSpeed; +}; + Toolkit::Scrollable::ScrollStartedSignalV2& Scrollable::ScrollStartedSignal() { return mScrollStartedSignalV2; @@ -235,6 +255,11 @@ void Scrollable::SetProperty( BaseObject* object, Property::Index index, const P scrollableImpl.SetOvershootEffectColor( value.Get() ); break; } + case Toolkit::Scrollable::PROPERTY_OVERSHOOT_ANIMATION_SPEED: + { + scrollableImpl.SetOvershootAnimationSpeed( value.Get() ); + break; + } } } } @@ -255,6 +280,11 @@ Property::Value Scrollable::GetProperty( BaseObject* object, Property::Index ind value = scrollableImpl.GetOvershootEffectColor(); break; } + case Toolkit::Scrollable::PROPERTY_OVERSHOOT_ANIMATION_SPEED: + { + value = scrollableImpl.GetOvershootAnimationSpeed(); + break; + } } } diff --git a/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.h b/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.h index 554135b..8abf7d5 100644 --- a/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.h +++ b/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.h @@ -119,6 +119,16 @@ public: */ Vector4 GetOvershootEffectColor() const; + /** + * @copydoc Dali::Toolkit::Scrollable::SetOvershootAnimationSpeed(float pixelsPerSecond) + */ + void SetOvershootAnimationSpeed( float pixelsPerSecond ); + + /** + * @copydoc Dali::Toolkit::Scrollable::GetOvershootAnimationSpeed() + */ + float GetOvershootAnimationSpeed() const; + private: /** @@ -224,6 +234,7 @@ private: protected: Vector4 mOvershootEffectColor; ///