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" );
float firstItemScrollPosition = ClampFirstItemPosition(layoutPositionDelta, layoutSize, *mActiveLayout);
+ float currentOvershoot = mScrollPositionObject.GetProperty<float>(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;
OvershootOverlayVisibilityConstraint() );
mOvershootOverlay.ApplyConstraint(constraint);
- Actor self = Self();
constraint = Constraint::New<float>( effectOvershootPropertyIndex,
Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ),
EqualToConstraint() );
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)
return;
}
- Actor self = Self();
- float currentOvershoot = mScrollPositionObject.GetProperty<float>(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<float>(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 )
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;
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
}
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)
{
{
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);
{
Actor self = mAttachedScrollView.Self();
mOvershoot = self.GetProperty<float>(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();
}
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<float>(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>() );
- 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 )
{
{
mOvershootOverlay.SetProperty( mEffectOvershootProperty, amount);
}
- if( absAmount > Math::MACHINE_EPSILON_1 )
- {
- UpdateVisibility(true);
- }
}
void ScrollOvershootEffectRipple::OnOvershootAnimFinished(Animation& animation)
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
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
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);
}
}
if( enabled )
{
- mMaxOvershoot = OVERSCROLL_CLAMP;
mOvershootIndicator->AttachToScrollable(*this);
}
else
{
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
{
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()
{
&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" );
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),
return mOvershootEffectColor;
};
+void Scrollable::SetOvershootAnimationSpeed( float pixelsPerSecond )
+{
+ mOvershootAnimationSpeed = pixelsPerSecond;
+}
+
+float Scrollable::GetOvershootAnimationSpeed() const
+{
+ return mOvershootAnimationSpeed;
+};
+
Toolkit::Scrollable::ScrollStartedSignalV2& Scrollable::ScrollStartedSignal()
{
return mScrollStartedSignalV2;
scrollableImpl.SetOvershootEffectColor( value.Get<Vector4>() );
break;
}
+ case Toolkit::Scrollable::PROPERTY_OVERSHOOT_ANIMATION_SPEED:
+ {
+ scrollableImpl.SetOvershootAnimationSpeed( value.Get<float>() );
+ break;
+ }
}
}
}
value = scrollableImpl.GetOvershootEffectColor();
break;
}
+ case Toolkit::Scrollable::PROPERTY_OVERSHOOT_ANIMATION_SPEED:
+ {
+ value = scrollableImpl.GetOvershootAnimationSpeed();
+ break;
+ }
}
}
*/
Vector4 GetOvershootEffectColor() const;
+ /**
+ * @copydoc Dali::Toolkit::Scrollable::SetOvershootAnimationSpeed(float pixelsPerSecond)
+ */
+ void SetOvershootAnimationSpeed( float pixelsPerSecond );
+
+ /**
+ * @copydoc Dali::Toolkit::Scrollable::GetOvershootAnimationSpeed()
+ */
+ float GetOvershootAnimationSpeed() const;
+
private:
/**
protected:
Vector4 mOvershootEffectColor; ///<The color of the overshoot bouncing effect
+ float mOvershootAnimationSpeed; ///<The speed of the overshoot animation (pixels per second)
Property::Index mPropertyRelativePosition;///< Scroll Relative Position ("scroll-relative-position") [range from 0.0f - 1.0f in each axes]
Property::Index mPropertyPositionMin; ///< Scroll Domain Minimum ("position-min")
return GetImpl(*this).GetOvershootEffectColor();
}
+void Scrollable::SetOvershootAnimationSpeed( float pixelsPerSecond )
+{
+ GetImpl(*this).SetOvershootAnimationSpeed(pixelsPerSecond);
+}
+
+float Scrollable::GetOvershootAnimationSpeed() const
+{
+ return GetImpl(*this).GetOvershootAnimationSpeed();
+}
+
} // namespace Toolkit
} // namespace Dali
/// @name Properties
/** @{ */
static const Property::Index PROPERTY_OVERSHOOT_EFFECT_COLOR; ///< Property, name "overshoot-effect-color", @see SetOvershootEffectColor(), type VECTOR4
+ static const Property::Index PROPERTY_OVERSHOOT_ANIMATION_SPEED; ///< Property, name "overshoot-animation-speed", @see SetOvershootAnimationSpeed(), type FLOAT
/** @} */
/// @name Signals
*/
Vector4 GetOvershootEffectColor() const;
+ /**
+ * @brief Set the speed of overshoot animation in pixels per second.
+ * When the speed is not greater than 0, the overshoot is set instantly with no animation.
+ * @param[in] pixelsPerSecond The speed of the overshoot animation.
+ */
+ void SetOvershootAnimationSpeed( float pixelsPerSecond );
+
+ /**
+ * @brief Get the speed of overshoot animation in pixels per second.
+ * @return The speed of the overshoot animation.
+ */
+ float GetOvershootAnimationSpeed() const;
+
public: // Not intended for application developers
/**