#include <boost/bind.hpp>
#include <dali-toolkit/internal/controls/scrollable/scrollable-impl.h>
+#include <dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h>
#include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h>
-#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
using namespace Dali;
-namespace Dali
-{
-
-namespace Toolkit
+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;
-namespace Internal
+// local helper function to resize the height of the bounce actor
+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_MAX_OVERSHOOT_HEIGHT = 36.0f; // 36 pixels
-const Rect<int> OVERSHOOT_RIPPLE_IMAGE_1_PIXEL_AREA( 0, 0, 720, 58 );
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
+}
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
ScrollOvershootIndicator::ScrollOvershootIndicator() :
mEffectX(NULL),
mEffectY(NULL)
mEffectY->Reset();
}
+void ScrollOvershootIndicator::SetOvershootEffectColor( const Vector4& color )
+{
+ if(mEffectX)
+ {
+ mEffectX->SetOvershootEffectColor(color);
+ }
+ if(mEffectY)
+ {
+ mEffectY->SetOvershootEffectColor(color);
+ }
+}
+
+void ScrollOvershootIndicator::ClearOvershoot()
+{
+ if(mEffectX)
+ {
+ mEffectX->SetOvershoot(0.0f);
+ }
+ if(mEffectY)
+ {
+ mEffectY->SetOvershoot(0.0f);
+ }
+}
+
ScrollOvershootEffect::ScrollOvershootEffect( bool vertical ) :
mVertical(vertical)
{
mOvershoot(0.0f),
mAnimationStateFlags(0)
{
- mRippleEffect = BouncingEffect::New(Scrollable::DEFAULT_OVERSHOOT_COLOUR);
- mOvershootImage = CreateSolidColorActor(Vector4::ONE);
- mOvershootImage.SetParentOrigin(ParentOrigin::TOP_LEFT);
- mOvershootImage.SetAnchorPoint(AnchorPoint::TOP_LEFT);
- mOvershootImage.SetDrawMode(DrawMode::OVERLAY);
- mOvershootImage.SetShaderEffect(mRippleEffect);
- mOvershootImage.SetVisible(false);
+ mOvershootOverlay = CreateBouncingEffectActor(mEffectOvershootProperty);
+ mOvershootOverlay.SetColor(mAttachedScrollView.GetOvershootEffectColor());
+ mOvershootOverlay.SetParentOrigin(ParentOrigin::TOP_LEFT);
+ mOvershootOverlay.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+ mOvershootOverlay.SetDrawMode(DrawMode::OVERLAY);
+ mOvershootOverlay.SetVisible(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);
mCanScrollPropertyIndex = self.GetPropertyIndex(IsVertical() ? Scrollable::SCROLLABLE_CAN_SCROLL_VERTICAL : Scrollable::SCROLLABLE_CAN_SCROLL_HORIZONTAL);
- mEffectOvershootProperty = mRippleEffect.GetPropertyIndex(mRippleEffect.GetProgressRatePropertyName());
// make sure height is set, since we only create a constraint for image width
- mOvershootImage.SetSize(OVERSHOOT_RIPPLE_IMAGE_1_PIXEL_AREA.width, OVERSHOOT_RIPPLE_IMAGE_1_PIXEL_AREA.height);
+ mOvershootOverlay.SetSize(OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.width, OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height);
- mAttachedScrollView.AddOverlay(mOvershootImage);
+ mAttachedScrollView.AddOverlay(mOvershootOverlay);
UpdatePropertyNotifications();
}
void ScrollOvershootEffectRipple::Remove( Scrollable& scrollable )
{
- if(mOvershootImage)
+ if(mOvershootOverlay)
{
if(mOvershootIncreaseNotification)
{
scrollable.Self().RemovePropertyNotification(mOvershootDecreaseNotification);
mOvershootDecreaseNotification.Reset();
}
- scrollable.RemoveOverlay(mOvershootImage);
+ scrollable.RemoveOverlay(mOvershootOverlay);
}
}
void ScrollOvershootEffectRipple::Reset()
{
- mOvershootImage.SetVisible(false);
- mRippleEffect.SetUniform(mRippleEffect.GetProgressRatePropertyName(), 0.0f);
+ mOvershootOverlay.SetVisible(false);
+ mOvershootOverlay.SetProperty( mEffectOvershootProperty, 0.f);
}
void ScrollOvershootEffectRipple::UpdatePropertyNotifications()
}
}
+void ScrollOvershootEffectRipple::SetOvershootEffectColor( const Vector4& color )
+{
+ if(mOvershootOverlay)
+ {
+ mOvershootOverlay.SetColor(color);
+ }
+}
+
void ScrollOvershootEffectRipple::UpdateVisibility( bool visible )
{
- mOvershootImage.SetVisible(visible);
+ mOvershootOverlay.SetVisible(visible);
// make sure overshoot image is correctly placed
if( visible )
{
if(mOvershoot > 0.0f)
{
// positive overshoot
- const Vector3 imageSize = mOvershootImage.GetCurrentSize();
+ const Vector3 size = mOvershootOverlay.GetCurrentSize();
Vector3 relativeOffset;
const Vector3 parentSize = self.GetCurrentSize();
if(IsVertical())
{
- mOvershootImage.SetRotation(Quaternion(0.0f, Vector3::ZAXIS));
- mOvershootImage.SetSize(parentSize.width, imageSize.height, imageSize.depth);
+ mOvershootOverlay.SetRotation(Quaternion(0.0f, Vector3::ZAXIS));
+ mOvershootOverlay.SetSize(parentSize.width, GetBounceActorHeight(parentSize.width), size.depth);
}
else
{
- mOvershootImage.SetRotation(Quaternion(1.5f * Math::PI, Vector3::ZAXIS));
- mOvershootImage.SetSize(parentSize.height, imageSize.height, imageSize.depth);
+ mOvershootOverlay.SetRotation(Quaternion(1.5f * Math::PI, Vector3::ZAXIS));
+ mOvershootOverlay.SetSize(parentSize.height, GetBounceActorHeight(parentSize.height), size.depth);
relativeOffset = Vector3(0.0f, 1.0f, 0.0f);
}
- mOvershootImage.SetPosition(relativeOffset * parentSize);
+ mOvershootOverlay.SetPosition(relativeOffset * parentSize);
}
else
{
// negative overshoot
- const Vector3 imageSize = mOvershootImage.GetCurrentSize();
+ const Vector3 size = mOvershootOverlay.GetCurrentSize();
Vector3 relativeOffset;
const Vector3 parentSize = self.GetCurrentSize();
if(IsVertical())
{
- mOvershootImage.SetRotation(Quaternion(Math::PI, Vector3::ZAXIS));
- mOvershootImage.SetSize(parentSize.width, imageSize.height, imageSize.depth);
+ mOvershootOverlay.SetRotation(Quaternion(Math::PI, Vector3::ZAXIS));
+ mOvershootOverlay.SetSize(parentSize.width, GetBounceActorHeight(parentSize.width), size.depth);
relativeOffset = Vector3(1.0f, 1.0f, 0.0f);
}
else
{
- mOvershootImage.SetRotation(Quaternion(0.5f * Math::PI, Vector3::ZAXIS));
- mOvershootImage.SetSize(parentSize.height, imageSize.height, imageSize.depth);
+ mOvershootOverlay.SetRotation(Quaternion(0.5f * Math::PI, Vector3::ZAXIS));
+ mOvershootOverlay.SetSize(parentSize.height, GetBounceActorHeight(parentSize.height), size.depth);
relativeOffset = Vector3(1.0f, 0.0f, 0.0f);
}
- mOvershootImage.SetPosition(relativeOffset * parentSize);
+ mOvershootOverlay.SetPosition(relativeOffset * parentSize);
}
}
}
if( mOvershootAnimationDuration > Math::MACHINE_EPSILON_1 )
{
// setup the new overshoot to 0 animation
- float currentOvershoot = fabsf( mRippleEffect.GetProperty<float>( mEffectOvershootProperty ) );
+ float currentOvershoot = fabsf( mOvershootOverlay.GetProperty( mEffectOvershootProperty ).Get<float>() );
float duration = mOvershootAnimationDuration * (animatingOn ? (1.0f - currentOvershoot) : currentOvershoot);
if( duration > Math::MACHINE_EPSILON_0 )
}
mScrollOvershootAnimation = Animation::New(duration);
mScrollOvershootAnimation.FinishedSignal().Connect( this, &ScrollOvershootEffectRipple::OnOvershootAnimFinished );
- mScrollOvershootAnimation.AnimateTo( Property(mRippleEffect, mEffectOvershootProperty), amount, TimePeriod(0.0f, duration) );
+ mScrollOvershootAnimation.AnimateTo( Property(mOvershootOverlay, mEffectOvershootProperty), amount, TimePeriod(duration) );
mScrollOvershootAnimation.Play();
mAnimationStateFlags = animatingOn ? AnimatingIn : AnimatingOut;
}
}
else
{
- mRippleEffect.SetProgressRate(amount);
+ mOvershootOverlay.SetProperty( mEffectOvershootProperty, amount);
}
if( absAmount > Math::MACHINE_EPSILON_1 )
{
if( mAnimationStateFlags & AnimatingOut )
{
// should now be offscreen
- mOvershootImage.SetVisible(false);
+ mOvershootOverlay.SetVisible(false);
}
if( (mAnimationStateFlags & AnimateBack) )
{