From: Xiangyin Ma Date: Wed, 11 Jun 2014 11:09:47 +0000 (+0100) Subject: New Bouncing Effect X-Git-Tag: dali_1.0.0~29 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=a1a30b337ce9bf681f3738e43d1b6846732d5e1b;hp=b422e5389b5b78d6037865c77453ab2fb5e47a0d New Bouncing Effect Patch 1: Add API CreateBouncingEffectActor to creates a Dali::Actor to display the bouncing effect for overshoot Patch 5: Integrate with ScrollView, ItemView Patch 7: Add PROPERTY_OVERSHOOT_EFFECT_COLOR to allow the StyleManager to apply the theme color Reduce the height of the effect when the width of scrollable is less than 180px patch 9: Add the script for overshoot-effect-color patch 14: fix the size bug Change-Id: I2f979ff59ab78b4ce8931b36d0bc2dff48dc7901 Signed-off-by: Adeel Kazmi --- diff --git a/base/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.cpp b/base/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.cpp new file mode 100644 index 0000000..237e81a --- /dev/null +++ b/base/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include +#include + +// EXTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +namespace +{ +// Bouncing effect is presented by stacked three layers with same color and opacity +const size_t NUM_LAYERS( 3 ); +const Vector3 LAYER_HEIGHTS( 1.f, 27.f/42.f, 13.f/42.f); + +// use the actor color to paint every layer +const char* MESH_FRAGMENT_SHADER = +"void main()\n" +"{\n" +" gl_FragColor = uColor;\n" +"}\n"; + +// Constraint to move the vertices vertically +struct VertexPositionConstraint +{ + VertexPositionConstraint( float initialY, float range ) + : mInitialY( initialY ), + mRange( range ) + { + } + + Vector3 operator()( const Vector3& current, const PropertyInput& bounceCoef ) + { + float positionY = mInitialY + mRange * fabsf(bounceCoef.GetFloat()); + return Vector3( current.x, positionY, current.z ); + } + + float mInitialY; + float mRange; +}; + +} // namespace Anon + +Actor CreateBouncingEffectActor( Property::Index& bouncePropertyIndex ) +{ + Dali::AnimatableMesh mesh; + Dali::MeshActor meshActor; + + Dali::AnimatableMesh::Faces faces; + faces.reserve( NUM_LAYERS * 6 ); // 2 triangles per layer + for( size_t i=0; i( i ); // the interval between each layer is 0.01 + mesh[j ].SetPosition( Vector3( -0.5f, -0.5f, positionZ ) ); + mesh[j+1].SetPosition( Vector3( 0.5f, -0.5f, positionZ ) ); + mesh[j+2].SetPosition( Vector3( -0.5f, -0.5f, positionZ ) ); + mesh[j+3].SetPosition( Vector3( 0.5f, -0.5f, positionZ ) ); + } + + meshActor = Dali::MeshActor::New(mesh); + meshActor.SetAffectedByLighting(false); + + Dali::ShaderEffect shaderEffect = Dali::ShaderEffect::New( "", MESH_FRAGMENT_SHADER, + GEOMETRY_TYPE_MESH, + Dali::ShaderEffect::HINT_BLENDING ); + meshActor.SetShaderEffect(shaderEffect); + + // To control the movement of all vertices with one custom property + bouncePropertyIndex = meshActor.RegisterProperty("BounceCoeffcient", 0.f); + for( size_t i=0;i( mesh.GetPropertyIndex(j+2, AnimatableVertex::POSITION ), + Source(meshActor, bouncePropertyIndex), + VertexPositionConstraint(-0.5f, LAYER_HEIGHTS[i]) ) ); + mesh.ApplyConstraint( Constraint::New( mesh.GetPropertyIndex(j+3, AnimatableVertex::POSITION), + Source(meshActor, bouncePropertyIndex), + VertexPositionConstraint(-0.5f, LAYER_HEIGHTS[i]) ) ); + } + + return meshActor; +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/base/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h b/base/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h new file mode 100644 index 0000000..b374df5 --- /dev/null +++ b/base/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h @@ -0,0 +1,69 @@ +#ifndef __DALI_TOOLKIT_INTERNAL_BOUNCING_EFFECT_ACTOR_H__ +#define __DALI_TOOLKIT_INTERNAL_BOUNCING_EFFECT_ACTOR_H__ + +/* + * Copyright (c) 2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +/** + * @brief Creates a Dali::Actor to display the bouncing effect for overshoot + * + * Usage example: + * @code + * // create the actor and get the property index for animation + * Property::Index bouncePropertyIndex = Property::INVALID_INDEX; + * Actor bounceActor = CreateBouncingEffectActor( bouncePropertyIndex ); + + * // set size and color + * bounceActor.SetSize(720.f, 42.f ); + * bounceActor.SetColor( Vector4( 0.0,0.64f,0.85f,0.25f ) ); + * + * // add to stage + * bounceActor.SetParentOrigin(ParentOrigin::CENTER); + * Stage::GetCurrent().Add(bounceActor); + + * // start the bouncing animation + * Animation anim = Animation::New(2.0f); + * anim.AnimateTo( Property( bounceActor, bouncePropertyIndex ), 1.f, AlphaFunctions::Sin ); + * anim.Play(); + * @endcode + * + * @param[out] bouncePropertyIndex The property index which controls the bouncing + * @return The actor which displays the bouncing effect + */ +Actor CreateBouncingEffectActor( Property::Index& bouncePropertyIndex); + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + + +#endif /* __DALI_TOOLKIT_INTERNAL_BOUNCING_EFFECT_ACTOR_H__ */ 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 55f87ad..42254a9 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 @@ -25,7 +25,7 @@ #include #include #include -#include +#include using namespace std; using namespace Dali; @@ -48,7 +48,8 @@ const float DEFAULT_COLOR_VISIBILITY_REMOVE_TIME = 0.5f; // 0.5 second const float MILLISECONDS_PER_SECONDS = 1000.0f; -const Rect OVERSHOOT_BOUNCE_IMAGE_1_PIXEL_AREA( 0, 0, 720, 58 ); +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 @@ -156,7 +157,7 @@ float CalculateScrollDistance(Vector2 panDistance, Toolkit::ItemLayout& layout) struct OvershootOverlaySizeConstraint { - float operator()(const float& current, + Vector3 operator()(const Vector3& current, const PropertyInput& parentScrollDirectionProperty, const PropertyInput& parentOvershootProperty, const PropertyInput& parentSizeProperty) @@ -176,7 +177,9 @@ struct OvershootOverlaySizeConstraint overlayWidth = fabsf(parentScrollDirection.x) > Math::MACHINE_EPSILON_1 ? parentSize.y : parentSize.x; } - return overlayWidth; + float overlayHeight = (overlayWidth > OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD) ? OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height : OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height*0.5f; + + return Vector3( overlayWidth, overlayHeight, current.depth ); } }; @@ -1667,25 +1670,35 @@ void ItemView::ScrollTo(const Vector3& position, float duration) mScrollStartedSignalV2.Emit(GetCurrentScrollPosition()); } +void ItemView::SetOvershootEffectColor( const Vector4& color ) +{ + mOvershootEffectColor = color; + if( mOvershootOverlay ) + { + mOvershootOverlay.SetColor( color ); + } +} + void ItemView::SetOvershootEnabled( bool enable ) { Actor self = Self(); if( enable ) { - mOvershootEffect = BouncingEffect::New(Scrollable::DEFAULT_OVERSHOOT_COLOUR); - mOvershootOverlay = CreateSolidColorActor(Vector4::ONE); + Property::Index effectOvershootPropertyIndex = Property::INVALID_INDEX; + mOvershootOverlay = CreateBouncingEffectActor( effectOvershootPropertyIndex ); + mOvershootOverlay.SetColor(mOvershootEffectColor); mOvershootOverlay.SetParentOrigin(ParentOrigin::TOP_LEFT); mOvershootOverlay.SetAnchorPoint(AnchorPoint::TOP_LEFT); mOvershootOverlay.SetDrawMode(DrawMode::OVERLAY); - mOvershootOverlay.SetShaderEffect(mOvershootEffect); self.Add(mOvershootOverlay); - Constraint constraint = Constraint::New( Actor::SIZE_WIDTH, + + Constraint constraint = Constraint::New( Actor::SIZE, ParentSource( mPropertyScrollDirection ), Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ), ParentSource( Actor::SIZE ), OvershootOverlaySizeConstraint() ); mOvershootOverlay.ApplyConstraint(constraint); - mOvershootOverlay.SetSize(OVERSHOOT_BOUNCE_IMAGE_1_PIXEL_AREA.width, OVERSHOOT_BOUNCE_IMAGE_1_PIXEL_AREA.height); + mOvershootOverlay.SetSize(OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.width, OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height); constraint = Constraint::New( Actor::ROTATION, ParentSource( mPropertyScrollDirection ), @@ -1705,12 +1718,11 @@ void ItemView::SetOvershootEnabled( bool enable ) OvershootOverlayVisibilityConstraint() ); mOvershootOverlay.ApplyConstraint(constraint); - int effectOvershootPropertyIndex = mOvershootEffect.GetPropertyIndex(mOvershootEffect.GetProgressRatePropertyName()); Actor self = Self(); constraint = Constraint::New( effectOvershootPropertyIndex, Source( mScrollPositionObject, ScrollConnector::OVERSHOOT ), EqualToConstraint() ); - mOvershootEffect.ApplyConstraint(constraint); + mOvershootOverlay.ApplyConstraint(constraint); } else { @@ -1719,7 +1731,6 @@ void ItemView::SetOvershootEnabled( bool enable ) self.Remove(mOvershootOverlay); mOvershootOverlay.Reset(); } - mOvershootEffect.Reset(); } } diff --git a/base/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h b/base/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h index 62ba4df..76a0c26 100644 --- a/base/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h +++ b/base/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h @@ -28,7 +28,6 @@ #include #include #include -#include namespace Dali { @@ -245,6 +244,11 @@ public: void ScrollTo(const Vector3& position, float duration); /** + * @copydoc Toolkit::Internal::Scrollable::SetOvershootEffectColor + */ + void SetOvershootEffectColor( const Vector4& color ); + + /** * @brief Set whether to enable automatic refresh or not. When refresh is disabled, * ItemView will not automatically refresh the cache in the given interval when the * layout position is changed. This is useful in some cases, for example, automatic @@ -584,8 +588,7 @@ private: Dali::Gesture::State mGestureState; - ImageActor mOvershootOverlay; ///< The overlay actor for overshoot effect - BouncingEffect mOvershootEffect; ///< The vertex/fragment shader used to display the overshoot ripple effect + Actor mOvershootOverlay; ///< The overlay actor for overshoot effect Dali::Toolkit::ScrollConnector mScrollConnector; ///< Connects ItemView with scrollable components e.g. scroll bars Constrainable mScrollPositionObject; ///< From mScrollConnector 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 94aca48..2662324 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 @@ -21,27 +21,39 @@ #include #include +#include #include -#include 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 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) @@ -91,6 +103,30 @@ void ScrollOvershootIndicator::Reset() 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) { @@ -113,13 +149,13 @@ ScrollOvershootEffectRipple::ScrollOvershootEffectRipple( bool vertical, Scrolla 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() @@ -127,19 +163,18 @@ 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) { @@ -151,14 +186,14 @@ void ScrollOvershootEffectRipple::Remove( Scrollable& scrollable ) 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() @@ -203,9 +238,17 @@ 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 ) { @@ -213,41 +256,41 @@ void ScrollOvershootEffectRipple::UpdateVisibility( bool 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); } } } @@ -303,7 +346,7 @@ void ScrollOvershootEffectRipple::SetOvershoot(float amount, bool animate) if( mOvershootAnimationDuration > Math::MACHINE_EPSILON_1 ) { // setup the new overshoot to 0 animation - float currentOvershoot = fabsf( mRippleEffect.GetProperty( mEffectOvershootProperty ) ); + float currentOvershoot = fabsf( mOvershootOverlay.GetProperty( mEffectOvershootProperty ).Get() ); float duration = mOvershootAnimationDuration * (animatingOn ? (1.0f - currentOvershoot) : currentOvershoot); if( duration > Math::MACHINE_EPSILON_0 ) @@ -317,14 +360,14 @@ void ScrollOvershootEffectRipple::SetOvershoot(float amount, bool animate) } 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 ) { @@ -338,7 +381,7 @@ void ScrollOvershootEffectRipple::OnOvershootAnimFinished(Animation& animation) if( mAnimationStateFlags & AnimatingOut ) { // should now be offscreen - mOvershootImage.SetVisible(false); + mOvershootOverlay.SetVisible(false); } if( (mAnimationStateFlags & AnimateBack) ) { 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 ce0b8d5..7263f0c 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 @@ -19,7 +19,6 @@ */ #include -#include namespace Dali { @@ -71,12 +70,23 @@ public: void Reset(); /** + * Clears the overshoot + */ + void ClearOvershoot(); + + /** * Create an initialized ScrollOvershootIndicator * * @return A pointer to the created ScrollOvershootIndicator. */ static ScrollOvershootIndicator* New(); + /** + * Set the color of the overshoot effect. + * @parm[in] color The color of the overshoot effect + */ + void SetOvershootEffectColor( const Vector4& color ); + private: ScrollOvershootEffectPtr mEffectX; ///< effect used for x-axis/horizontal display ScrollOvershootEffectPtr mEffectY; ///< effect used for y-axis/vertical display @@ -132,6 +142,19 @@ public: */ virtual void UpdatePropertyNotifications() {} + /** + * @copydoc ScrollOvershootIndicator::SetOvershootEffectColor() + */ + virtual void SetOvershootEffectColor( const Vector4& color ) = 0; + + /** + * Sets shader overshoot value, either immediately of by animating over time + * + * @param[in] amount The amount to set overshoot to [-1.0f,1.0f] + * @param[in] animate Whether to animate or set immediately + */ + virtual void SetOvershoot(float amount, bool animate = true) = 0; + private: bool mVertical; ///< whether this is a vertical/horizontal effect }; @@ -179,6 +202,11 @@ public: void UpdatePropertyNotifications(); /** + * @copydoc ScrollOvershootEffect::SetOvershootEffectColor() + */ + void SetOvershootEffectColor( const Vector4& color ); + + /** * Updates the vibility of the overshoot image as well as updating its size, position and rotation * This function is called when animation starts and finishes * @@ -195,10 +223,7 @@ public: void OnOvershootNotification(PropertyNotification& source); /** - * Sets shader overshoot value, either immediately of by animating over time - * - * @param[in] amount The amount to set overshoot to [-1.0f,1.0f] - * @param[in] animate Whether to animate or set immediately + * @copydoc ScrollOvershootEffect::SetOvershoot() */ void SetOvershoot(float amount, bool animate = true); @@ -218,9 +243,8 @@ public: static ScrollOvershootEffectRipplePtr New( bool vertical, Scrollable& scrollable ); private: - ImageActor mOvershootImage; ///< the overshoot image... + Actor mOvershootOverlay; ///< the actor which displays the overshoot effect Scrollable& mAttachedScrollView; ///< the actor that this indicator has been attached to - BouncingEffect mRippleEffect; ///< the ripple vertex/fragment shader effect Animation mScrollOvershootAnimation; ///< overshoot animation PropertyNotification mOvershootIncreaseNotification;///< notification used to inform as overshoot increases PropertyNotification mOvershootDecreaseNotification;///< notification used to inform as overshoot decreases 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 790c7f8..0c761fb 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 @@ -1905,6 +1905,15 @@ void ScrollView::RemoveOverlay(Actor actor) mInternalActor.Remove( actor ); } +void ScrollView::SetOvershootEffectColor( const Vector4& color ) +{ + mOvershootEffectColor = color; + if( mOvershootIndicator ) + { + mOvershootIndicator->SetOvershootEffectColor( color ); + } +} + void ScrollView::SetScrollingDirection( Radian direction, Radian threshold ) { PanGestureDetector panGesture( GetPanGestureDetector() ); @@ -2587,6 +2596,11 @@ void ScrollView::OnPan(PanGesture gesture) { self.RemoveConstraint(mScrollMainInternalPrePositionConstraint); } + + if( mOvershootIndicator ) + { + mOvershootIndicator->ClearOvershoot(); + } } else { diff --git a/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.h b/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.h index 3f8562f..19cdce0 100644 --- a/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.h +++ b/base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.h @@ -507,6 +507,11 @@ public: */ void RemoveOverlay(Actor actor); + /** + * @copydoc Toolkit::Internal::Scrollable::SetOvershootEffectColor + */ + void SetOvershootEffectColor( const Vector4& color ); + public: //Signals /** diff --git a/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp b/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp index 7b83883..555ae70 100644 --- a/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp +++ b/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp @@ -32,11 +32,14 @@ namespace Dali namespace Toolkit { +const Property::Index Scrollable::PROPERTY_OVERSHOOT_EFFECT_COLOR( Toolkit::Internal::Control::CONTROL_PROPERTY_END_INDEX + 1 ); + namespace Internal { namespace { +const Vector4 DEFAULT_OVERSHOOT_COLOUR(0.0f, 0.64f, 0.85f, 0.25f); BaseHandle Create() { @@ -51,11 +54,17 @@ SignalConnectorType s2(mType, Toolkit::Scrollable::SIGNAL_SCROLL_COMPLETED, &Scr SignalConnectorType s3(mType, Toolkit::Scrollable::SIGNAL_SCROLL_UPDATED, &Scrollable::DoConnectSignal); SignalConnectorType s4(mType, Toolkit::Scrollable::SIGNAL_SCROLL_CLAMPED, &Scrollable::DoConnectSignal); +PropertyRegistration property1( mType, + "overshoot-effect-color", + Toolkit::Scrollable::PROPERTY_OVERSHOOT_EFFECT_COLOR, + Property::VECTOR4, + &Scrollable::SetProperty, + &Scrollable::GetProperty ); + } const std::string Scrollable::SCROLLABLE_CAN_SCROLL_VERTICAL( "scrollable-can-scroll-vertical" ); const std::string Scrollable::SCROLLABLE_CAN_SCROLL_HORIZONTAL( "scrollable-can-scroll-horizontal" ); -const Vector4 Scrollable::DEFAULT_OVERSHOOT_COLOUR(0.0f, 0.64f, 0.85f, 0.6f); /////////////////////////////////////////////////////////////////////////////////////////////////// // Scrollable @@ -65,6 +74,7 @@ const Vector4 Scrollable::DEFAULT_OVERSHOOT_COLOUR(0.0f, 0.64f, 0.85f, 0.6f) // we dont want size negotiation while scrolling if we can avoid it Scrollable::Scrollable() : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS | NO_SIZE_NEGOTIATION ) ), + mOvershootEffectColor( DEFAULT_OVERSHOOT_COLOUR ), mPropertyRelativePosition(Property::INVALID_INDEX), mPropertyPositionMin(Property::INVALID_INDEX), mPropertyPositionMax(Property::INVALID_INDEX), @@ -151,6 +161,11 @@ void Scrollable::DisableScrollComponent(Toolkit::Scrollable::ScrollComponentType } } +Vector4 Scrollable::GetOvershootEffectColor() const +{ + return mOvershootEffectColor; +}; + Toolkit::Scrollable::ScrollStartedSignalV2& Scrollable::ScrollStartedSignal() { return mScrollStartedSignalV2; @@ -203,6 +218,46 @@ bool Scrollable::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface return connected; } +void Scrollable::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value ) +{ + Toolkit::Scrollable scrollable = Toolkit::Scrollable::DownCast( Dali::BaseHandle( object ) ); + + if( scrollable ) + { + Scrollable& scrollableImpl( GetImpl( scrollable ) ); + switch( index ) + { + case Toolkit::Scrollable::PROPERTY_OVERSHOOT_EFFECT_COLOR: + { + scrollableImpl.SetOvershootEffectColor( value.Get() ); + break; + } + } + } +} + +Property::Value Scrollable::GetProperty( BaseObject* object, Property::Index index ) +{ + Property::Value value; + + Toolkit::Scrollable scrollable = Toolkit::Scrollable::DownCast( Dali::BaseHandle( object ) ); + + if( scrollable ) + { + Scrollable& scrollableImpl( GetImpl( scrollable ) ); + switch( index ) + { + case Toolkit::Scrollable::PROPERTY_OVERSHOOT_EFFECT_COLOR: + { + value = scrollableImpl.GetOvershootEffectColor(); + break; + } + } + } + + return value; +} + Toolkit::ScrollComponent Scrollable::NewScrollComponent(Toolkit::Scrollable& scrollable, Toolkit::Scrollable::ScrollComponentType type) { Toolkit::ScrollComponent instance; diff --git a/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.h b/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.h index 10d9f1d..a536a51 100644 --- a/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.h +++ b/base/dali-toolkit/internal/controls/scrollable/scrollable-impl.h @@ -45,7 +45,6 @@ class Scrollable : public Control public: static const std::string SCROLLABLE_CAN_SCROLL_VERTICAL; static const std::string SCROLLABLE_CAN_SCROLL_HORIZONTAL; - static const Vector4 DEFAULT_OVERSHOOT_COLOUR; /** * Create a new Scrollable. @@ -107,6 +106,18 @@ public: */ virtual void ScrollTo(const Vector3 &position, float duration) = 0; + /** + * Set the color of the overshoot effect. + * @parm[in] color The color of the overshoot effect + */ + virtual void SetOvershootEffectColor( const Vector4& color ) = 0; + + /** + * Retrieve the color of the overshoot effect. + * @return The color of the overshoot effect. + */ + Vector4 GetOvershootEffectColor() const; + private: /** @@ -149,6 +160,24 @@ public: //Signals */ static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor ); + //properties + + /** + * Called when a property of an object of this type is set. + * @param[in] object The object whose property is set. + * @param[in] index The property index. + * @param[in] value The new property value. + */ + static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value ); + + /** + * Called to retrieve a property of an object of this type. + * @param[in] object The object whose property is to be retrieved. + * @param[in] index The property index. + * @return The current value of the property. + */ + static Property::Value GetProperty( BaseObject* object, Property::Index index ); + protected: /** @@ -193,6 +222,8 @@ private: protected: + Vector4 mOvershootEffectColor; ///