New Bouncing Effect
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / internal / controls / scrollable / scroll-view / scroll-overshoot-indicator-impl.h
1 #ifndef __DALI_TOOLKIT_INTERNAL_SCROLL_OVERSHOOT_INDICATOR_H__
2 #define __DALI_TOOLKIT_INTERNAL_SCROLL_OVERSHOOT_INDICATOR_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 #include <dali/dali.h>
22
23 namespace Dali
24 {
25
26 namespace Toolkit
27 {
28
29 namespace Internal
30 {
31 class Scrollable;
32 class ScrollOvershootEffect;
33 class ScrollOvershootEffectGradient;
34 class ScrollOvershootEffectRipple;
35 typedef IntrusivePtr<ScrollOvershootEffect> ScrollOvershootEffectPtr;
36 typedef IntrusivePtr<ScrollOvershootEffectGradient> ScrollOvershootEffectGradientPtr;
37 typedef IntrusivePtr<ScrollOvershootEffectRipple> ScrollOvershootEffectRipplePtr;
38
39 struct ScrollOvershootIndicator : public Dali::RefObject
40 {
41 public:
42
43   /**
44    * ScrollOvershootIndicator constructor.
45    */
46   ScrollOvershootIndicator();
47
48   /**
49    * Virtual destructor
50    */
51   virtual ~ScrollOvershootIndicator();
52
53   /**
54    * Attaches the scroll indicator to a scrollable actor
55    *
56    * &param[in] scrollable The scrollable actor to attach to
57    */
58   void AttachToScrollable(Scrollable& scrollable);
59
60   /**
61    * Detaches the scroll indicator from a scrollable actor
62    *
63    * &param[in] scrollable The scrollable actor to detach from
64    */
65   void DetachFromScrollable(Scrollable& scrollable);
66
67   /**
68    * Resets the indicator
69    */
70   void Reset();
71
72   /**
73    * Clears the overshoot
74    */
75   void ClearOvershoot();
76
77   /**
78    * Create an initialized ScrollOvershootIndicator
79    *
80    * @return A pointer to the created ScrollOvershootIndicator.
81    */
82   static ScrollOvershootIndicator* New();
83
84   /**
85    * Set the color of the overshoot effect.
86    * @parm[in] color The color of the overshoot effect
87    */
88   void SetOvershootEffectColor( const Vector4& color );
89
90 private:
91   ScrollOvershootEffectPtr mEffectX;                      ///< effect used for x-axis/horizontal display
92   ScrollOvershootEffectPtr mEffectY;                      ///< effect used for y-axis/vertical display
93 };
94
95 /**
96  * ScrollOvershootEffect is a derivable class, designed to allow the application programmer to create their own
97  * overshoot effect and apply it with minimal implementation required
98  */
99 struct ScrollOvershootEffect : public Dali::RefObject
100 {
101 public:
102   /**
103    * Create a new overshoot effect, passing in whether it is vertical or horizontal
104    *
105    * @param[in] vertical whether this effect is a vertical or horizontal one
106    */
107   ScrollOvershootEffect( bool vertical );
108
109   /**
110    * Virtual destructor
111    */
112   virtual ~ScrollOvershootEffect() {}
113
114   /**
115    * Returns if this is a vertical or horizontal overhoot effect
116    *
117    * @return true or false
118    */
119   bool IsVertical() const;
120
121   /**
122    * Applies the indicator effect, all derived effects must implement this function
123    *
124    * @param[in] scrollable the scrollable object to apply this effect to
125    */
126   virtual void Apply() = 0;
127
128   /**
129    * Removes the indicator effect, all derived effects must implement this function
130    *
131    * @param[in] scrollable the scrollable object to remove this effect from
132    */
133   virtual void Remove( Scrollable& scrollable ) = 0;
134
135   /**
136    * Resets this overshoot effect
137    */
138   virtual void Reset() = 0;
139
140   /**
141    * Sets up property notifications for overshoot values
142    */
143   virtual void UpdatePropertyNotifications() {}
144
145   /**
146    * @copydoc ScrollOvershootIndicator::SetOvershootEffectColor()
147    */
148   virtual void SetOvershootEffectColor( const Vector4& color ) = 0;
149
150   /**
151    * Sets shader overshoot value, either immediately of by animating over time
152    *
153    * @param[in] amount The amount to set overshoot to [-1.0f,1.0f]
154    * @param[in] animate Whether to animate or set immediately
155    */
156   virtual void SetOvershoot(float amount, bool animate = true) = 0;
157
158 private:
159   bool mVertical;                      ///< whether this is a vertical/horizontal effect
160 };
161
162 /**
163  * ScrollOvershootEffectRipple creates an animated bounce effect at the end of the scrollable area if the user
164  * attempts to scroll past it
165  */
166 struct ScrollOvershootEffectRipple : public ScrollOvershootEffect, public ConnectionTracker
167 {
168   enum AnimationState
169   {
170     AnimatingIn  = 0x01,  ///< animating overshoot to 0
171     AnimatingOut = 0x02,  ///< animating overshoot to negative (overshoot image displays in +ve area of screen)
172     AnimateBack  = 0x04,  ///< indicates that we need to animate overshoot back to zero immediately after it has finished animating in
173   };
174
175 public:
176
177   /**
178    * Create a new gradient overshoot effect, passing in whether it is vertical or horizontal
179    *
180    * @param[in] vertical Whether this indicator is vertical or horizontal
181    */
182   ScrollOvershootEffectRipple( bool vertical, Scrollable& scrollable );
183
184   /**
185    * @copydoc ScrollOvershootEffect::Apply
186    */
187   virtual void Apply();
188
189   /**
190    * @copydoc ScrollOvershootEffect::Remove
191    */
192   virtual void Remove( Scrollable& scrollable );
193
194   /**
195    * @copydoc ScrollOvershootEffect::Reset
196    */
197   virtual void Reset();
198
199   /**
200    * @copydoc ScrollOvershootEffect::UpdatePropertyNotifications
201    */
202   void UpdatePropertyNotifications();
203
204   /**
205    * @copydoc ScrollOvershootEffect::SetOvershootEffectColor()
206    */
207   void SetOvershootEffectColor( const Vector4& color );
208
209   /**
210    * Updates the vibility of the overshoot image as well as updating its size, position and rotation
211    * This function is called when animation starts and finishes
212    *
213    * @param[in] visible Whether to set the image visible or not
214    */
215   void UpdateVisibility( bool visible );
216
217   /**
218    * Informs overshoot effect to update image position and to animate effect overshoot value for a
219    * positive overshoot value from scrollview
220    *
221    * @param[in] source the property notification that triggered this callback
222    */
223   void OnOvershootNotification(PropertyNotification& source);
224
225   /**
226    * @copydoc ScrollOvershootEffect::SetOvershoot()
227    */
228   void SetOvershoot(float amount, bool animate = true);
229
230   /**
231    * Connects to the animation finished signal of our overshoot animation
232    *
233    * @param[in] animation the animation instance that has finished
234    */
235   void OnOvershootAnimFinished(Animation& animation);
236
237   /**
238    * Creates a new ScrollOvershootEffectGradient objects and returns a pointer to it
239    *
240    * @param[in] vertical whether to create a vertical(true) or horizontal effect
241    * @return a pointer to the new effect
242    */
243   static ScrollOvershootEffectRipplePtr New( bool vertical, Scrollable& scrollable );
244
245 private:
246   Actor                 mOvershootOverlay;             ///< the actor which displays the overshoot effect
247   Scrollable&           mAttachedScrollView;           ///< the actor that this indicator has been attached to
248   Animation             mScrollOvershootAnimation;     ///< overshoot animation
249   PropertyNotification  mOvershootIncreaseNotification;///< notification used to inform as overshoot increases
250   PropertyNotification  mOvershootDecreaseNotification;///< notification used to inform as overshoot decreases
251   Property::Index       mCanScrollPropertyIndex;       ///< property index to a property that informs indicator if it is needed
252   Property::Index       mOvershootProperty;            ///< index of the overshoot property in the scrollable actor
253   Property::Index       mEffectOvershootProperty;      ///< index of the effect's overshoot property
254   float                 mMaxOvershootImageSize;        ///< maximum height of the image when overshoot value is 1.0f
255   float                 mOvershootAnimationDuration;   ///< time taken for overshoot to go from fully offscreen to fully onscreen and vice versa
256   float                 mOvershoot;                    ///< last overshoot value as detected by notifications
257   unsigned short        mAnimationStateFlags;          ///< contains flags indicating the current state of the overshoot animation
258 };
259
260 } // namespace Internal
261
262 } // namespace Toolkit
263
264 } // namespace Dali
265
266 #endif // __DALI_TOOLKIT_INTERNAL_SCROLL_OVERSHOOT_INDICATOR_H__