X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Fscrollable%2Fscroll-view%2Fscroll-overshoot-indicator-impl.cpp;h=c02c7ec6f00c64433c635fe93695ec818bca38dd;hp=3a9d9b96ae423cbe1e44747ab1ceeb3d6b93bcc4;hb=405f6216e6bb0c6c5e88a809452f5ecf490ea1ba;hpb=2ec164cd618f93ccafe17b1d0b8ff16401ed4aef diff --git a/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.cpp b/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.cpp index 3a9d9b9..c02c7ec 100644 --- a/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.cpp +++ b/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,24 +18,22 @@ // CLASS HEADER #include -// EXTERNAL INCLUDES -#include - // INTERNAL INCLUDES #include +#include #include using namespace Dali; namespace { -const Vector2 OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE( 720.0f, 42.0f ); + const float OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD = 180.0f; // local helper function to resize the height of the bounce actor -float GetBounceActorHeight( float width ) +float GetBounceActorHeight( float width, float defaultHeight ) { - return (width > OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD) ? OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height : OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height * 0.5f; + return (width > OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD) ? defaultHeight : defaultHeight * 0.5f; } 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 @@ -114,18 +112,6 @@ void ScrollOvershootIndicator::SetOvershootEffectColor( const Vector4& color ) } } -void ScrollOvershootIndicator::ClearOvershoot() -{ - if(mEffectX) - { - mEffectX->SetOvershoot(0.0f); - } - if(mEffectY) - { - mEffectY->SetOvershoot(0.0f); - } -} - ScrollOvershootEffect::ScrollOvershootEffect( bool vertical ) : mVertical(vertical) { @@ -143,28 +129,53 @@ ScrollOvershootEffectRipple::ScrollOvershootEffectRipple( bool vertical, Scrolla mOvershootProperty(Property::INVALID_INDEX), mEffectOvershootProperty(Property::INVALID_INDEX), mOvershoot(0.0f), + mOvershootSize( scrollable.GetOvershootSize() ), mAnimationStateFlags(0) { + mOvershootOverlay = CreateBouncingEffectActor(mEffectOvershootProperty); + mOvershootOverlay.SetProperty( Actor::Property::COLOR,mAttachedScrollView.GetOvershootEffectColor()); + mOvershootOverlay.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::TOP_LEFT ); + mOvershootOverlay.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT); + mOvershootOverlay.SetProperty( Actor::Property::VISIBLE,false); } 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); + mOvershootProperty = IsVertical() ? Toolkit::ScrollView::Property::OVERSHOOT_Y : Toolkit::ScrollView::Property::OVERSHOOT_X; // make sure height is set, since we only create a constraint for image width + mOvershootSize = mAttachedScrollView.GetOvershootSize(); + mOvershootOverlay.SetProperty( Actor::Property::SIZE, mOvershootSize ); + mAttachedScrollView.AddOverlay(mOvershootOverlay); UpdatePropertyNotifications(); } void ScrollOvershootEffectRipple::Remove( Scrollable& scrollable ) { + if(mOvershootOverlay) + { + if(mOvershootIncreaseNotification) + { + scrollable.Self().RemovePropertyNotification(mOvershootIncreaseNotification); + mOvershootIncreaseNotification.Reset(); + } + if(mOvershootDecreaseNotification) + { + scrollable.Self().RemovePropertyNotification(mOvershootDecreaseNotification); + mOvershootDecreaseNotification.Reset(); + } + scrollable.RemoveOverlay(mOvershootOverlay); + } } void ScrollOvershootEffectRipple::Reset() { + mOvershootOverlay.SetProperty( Actor::Property::VISIBLE,false); + mOvershootOverlay.SetProperty( mEffectOvershootProperty, 0.f); } void ScrollOvershootEffectRipple::UpdatePropertyNotifications() @@ -186,7 +197,7 @@ void ScrollOvershootEffectRipple::UpdatePropertyNotifications() increaseStep = MAX_OVERSHOOT_NOTIFY_AMOUNT; } mOvershootIncreaseNotification = self.AddPropertyNotification( mOvershootProperty, OutsideCondition(-increaseStep, increaseStep) ); - mOvershootIncreaseNotification.SetNotifyMode(PropertyNotification::NotifyOnTrue); + mOvershootIncreaseNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_TRUE); mOvershootIncreaseNotification.NotifySignal().Connect(this, &ScrollOvershootEffectRipple::OnOvershootNotification); } @@ -204,29 +215,132 @@ void ScrollOvershootEffectRipple::UpdatePropertyNotifications() reduceStep = MIN_OVERSHOOT_NOTIFY_AMOUNT; } mOvershootDecreaseNotification = self.AddPropertyNotification( mOvershootProperty, InsideCondition(-reduceStep, reduceStep) ); - mOvershootDecreaseNotification.SetNotifyMode(PropertyNotification::NotifyOnTrue); + mOvershootDecreaseNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_TRUE); mOvershootDecreaseNotification.NotifySignal().Connect(this, &ScrollOvershootEffectRipple::OnOvershootNotification); } } void ScrollOvershootEffectRipple::SetOvershootEffectColor( const Vector4& color ) { + if(mOvershootOverlay) + { + mOvershootOverlay.SetProperty( Actor::Property::COLOR,color); + } } void ScrollOvershootEffectRipple::UpdateVisibility( bool visible ) { + mOvershootOverlay.SetProperty( Actor::Property::VISIBLE,visible); + // make sure overshoot image is correctly placed + if( visible ) + { + Actor self = mAttachedScrollView.Self(); + if(mOvershoot > 0.0f) + { + // positive overshoot + const Vector3 size = mOvershootOverlay.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ); + Vector3 relativeOffset; + const Vector3 parentSize = self.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ); + if(IsVertical()) + { + mOvershootOverlay.SetProperty( Actor::Property::ORIENTATION, Quaternion( Quaternion( Radian( 0.0f ), Vector3::ZAXIS ) ) ); + mOvershootOverlay.SetProperty( Actor::Property::SIZE, Vector3( parentSize.width, GetBounceActorHeight(parentSize.width, mOvershootSize.height), size.depth ) ); + } + else + { + mOvershootOverlay.SetProperty( Actor::Property::ORIENTATION, Quaternion( Quaternion( Radian( 1.5f * Math::PI ), Vector3::ZAXIS ) ) ); + mOvershootOverlay.SetProperty( Actor::Property::SIZE, Vector3( parentSize.height, GetBounceActorHeight(parentSize.height, mOvershootSize.height), size.depth ) ); + relativeOffset = Vector3(0.0f, 1.0f, 0.0f); + } + mOvershootOverlay.SetProperty( Actor::Property::POSITION, relativeOffset * parentSize ); + } + else + { + // negative overshoot + const Vector3 size = mOvershootOverlay.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ); + Vector3 relativeOffset; + const Vector3 parentSize = self.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ); + if(IsVertical()) + { + mOvershootOverlay.SetProperty( Actor::Property::ORIENTATION, Quaternion( Quaternion( Radian( Math::PI ), Vector3::ZAXIS ) ) ); + mOvershootOverlay.SetProperty( Actor::Property::SIZE, Vector3( parentSize.width, GetBounceActorHeight(parentSize.width, mOvershootSize.height), size.depth ) ); + relativeOffset = Vector3(1.0f, 1.0f, 0.0f); + } + else + { + mOvershootOverlay.SetProperty( Actor::Property::ORIENTATION, Quaternion( Quaternion( Radian( 0.5f * Math::PI ), Vector3::ZAXIS ) ) ); + mOvershootOverlay.SetProperty( Actor::Property::SIZE, Vector3( parentSize.height, GetBounceActorHeight(parentSize.height, mOvershootSize.height), size.depth ) ); + relativeOffset = Vector3(1.0f, 0.0f, 0.0f); + } + mOvershootOverlay.SetProperty( Actor::Property::POSITION, relativeOffset * parentSize ); + } + } } void ScrollOvershootEffectRipple::OnOvershootNotification(PropertyNotification& source) { Actor self = mAttachedScrollView.Self(); - mOvershoot = self.GetProperty(mOvershootProperty); + mOvershoot = self.GetCurrentProperty< float >( mOvershootProperty ); SetOvershoot(mOvershoot, false); UpdatePropertyNotifications(); } void ScrollOvershootEffectRipple::SetOvershoot(float amount, bool animate) { + float absAmount = fabsf(amount); + bool animatingOn = absAmount > Math::MACHINE_EPSILON_0; + if( (animatingOn && (mAnimationStateFlags & AnimatingIn)) ) + { + // trying to do what we are already doing + if( mAnimationStateFlags & AnimateBack ) + { + mAnimationStateFlags &= ~AnimateBack; + } + return; + } + if( (!animatingOn && (mAnimationStateFlags & AnimatingOut)) ) + { + // trying to do what we are already doing + return; + } + if( !animatingOn && (mAnimationStateFlags & AnimatingIn) ) + { + // dont interrupt while animating on + mAnimationStateFlags |= AnimateBack; + return; + } + + 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 ) + { + float currentOvershoot = fabsf( mOvershootOverlay.GetProperty( mEffectOvershootProperty ).Get() ); + float duration = mOvershootOverlay.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ).height * (animatingOn ? (1.0f - currentOvershoot) : currentOvershoot) / overshootAnimationSpeed; + + if( duration > Math::MACHINE_EPSILON_0 ) + { + if(mScrollOvershootAnimation) + { + mScrollOvershootAnimation.FinishedSignal().Disconnect( this, &ScrollOvershootEffectRipple::OnOvershootAnimFinished ); + mScrollOvershootAnimation.Stop(); + mScrollOvershootAnimation.Reset(); + } + mScrollOvershootAnimation = Animation::New(duration); + mScrollOvershootAnimation.FinishedSignal().Connect( this, &ScrollOvershootEffectRipple::OnOvershootAnimFinished ); + mScrollOvershootAnimation.AnimateTo( Property(mOvershootOverlay, mEffectOvershootProperty), amount, TimePeriod(duration) ); + mScrollOvershootAnimation.Play(); + mAnimationStateFlags = animatingOn ? AnimatingIn : AnimatingOut; + } + } + else + { + mOvershootOverlay.SetProperty( mEffectOvershootProperty, amount); + } } void ScrollOvershootEffectRipple::OnOvershootAnimFinished(Animation& animation) @@ -234,6 +348,8 @@ void ScrollOvershootEffectRipple::OnOvershootAnimFinished(Animation& animation) bool animateOff = false; if( mAnimationStateFlags & AnimatingOut ) { + // should now be offscreen + mOvershootOverlay.SetProperty( Actor::Property::VISIBLE,false); } if( (mAnimationStateFlags & AnimateBack) ) {