4d871a79538cf702fdde6f1f13580dd8c0227619
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / scrollable / scroll-view / scroll-view-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_SCROLL_VIEW_H
2 #define DALI_TOOLKIT_INTERNAL_SCROLL_VIEW_H
3
4 /*
5  * Copyright (c) 2021 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 // EXTERNAL INCLUDES
22 #include <dali/public-api/adaptor-framework/timer.h>
23 #include <dali/public-api/animation/animation.h>
24 #include <dali/public-api/object/property-notification.h>
25 #include <dali/public-api/object/weak-handle.h>
26
27 // INTERNAL INCLUDES
28 #include <dali-toolkit/devel-api/controls/scroll-bar/scroll-bar.h>
29 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-base-impl.h>
30 #include <dali-toolkit/public-api/controls/control-impl.h>
31 #include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view-effect.h>
32 #include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h>
33 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl-constraints.h>
34
35 namespace Dali
36 {
37 namespace Toolkit
38 {
39 namespace Internal
40 {
41 class ScrollView;
42 typedef IntrusivePtr<ScrollView> ScrollViewPtr;
43
44 class ScrollInternalConstraints;
45 typedef IntrusivePtr<ScrollInternalConstraints> ScrollInternalConstraintsPtr;
46
47 class ScrollOvershootIndicator;
48 typedef IntrusivePtr<ScrollOvershootIndicator> ScrollOvershootIndicatorPtr;
49
50 /**
51  * @copydoc Toolkit::ScrollView
52  */
53 class ScrollView : public ScrollBase
54 {
55 public:
56   /**
57    * FindDirection specifies how searching is conducted within the Find... routines.
58    */
59   enum FindDirection
60   {
61     None  = -3, ///< Includes none within the search query.
62     All   = -2, ///< Includes all within the search query.
63     Left  = -1, ///< Includes only those not right !(>)
64     Right = 1,  ///< Includes only those right (>)
65     Up    = -1, ///< Includes only those not below  !(>)
66     Down  = 1,  ///< Includes only those below (>)
67     Out   = -1, ///< Includes only those not infront  !(>)
68     In    = 1   ///< Includes only those infront (>)
69   };
70
71   enum LockAxis
72   {
73     LockPossible = 0, ///< Locking is possible, but not set in stone yet.
74     LockHorizontal,   ///< Locking is set to horizontal. (can pan vertically)
75     LockVertical,     ///< Locking is set to vertical. (can pan horizontally)
76     LockNone          ///< Locking is set to none (free panning).
77   };
78
79   enum ScrollStateFlag
80   {
81     AnimatingInternalX = 0x01, ///< animating mPropertyX due to externally requested ScrollTo or internal snapping operation
82     AnimatingInternalY = 0x02, ///< animating mPropertyY due to externally requested ScrollTo or internal snapping operation
83     SnappingInternalX  = 0x04, ///< snapping mPropertyX back to mPropertyPreScroll x value to remove x overshoot over time
84     SnappingInternalY  = 0x08, ///< snapping mPropertyY back to mPropertyPreScroll y value to remove y overshoot over time
85   };
86
87   static const unsigned int SCROLL_X_STATE_MASK    = AnimatingInternalX | SnappingInternalX;
88   static const unsigned int SCROLL_Y_STATE_MASK    = AnimatingInternalY | SnappingInternalY;
89   static const unsigned int SCROLL_ANIMATION_FLAGS = AnimatingInternalX | AnimatingInternalY;
90   static const unsigned int SNAP_ANIMATION_FLAGS   = SnappingInternalX | SnappingInternalY;
91
92 private:
93   typedef std::vector<Dali::Toolkit::ScrollViewEffect> ScrollViewEffectContainer; ///< Container of Dali::Toolkit::ScrollViewEffect
94   typedef ScrollViewEffectContainer::iterator          ScrollViewEffectIter;      ///< Iterator for Dali::Toolkit::ScrollViewEffectContainer
95
96 public:
97   /**
98    * Create a new ScrollView.
99    * @return A public handle to the newly allocated ScrollView.
100    */
101   static Dali::Toolkit::ScrollView New();
102
103 public:
104   /**
105    * @copydoc Toolkit::ScrollView::GetScrollSnapAlphaFunction
106    */
107   AlphaFunction GetScrollSnapAlphaFunction() const
108   {
109     return mSnapAlphaFunction;
110   }
111
112   /**
113    * @copydoc Toolkit::ScrollView::SetScrollSnapAlphaFunction
114    */
115   void SetScrollSnapAlphaFunction(AlphaFunction alpha)
116   {
117     mSnapAlphaFunction = alpha;
118   }
119
120   /**
121    * @copydoc Toolkit::ScrollView::GetScrollFlickAlphaFunction
122    */
123   AlphaFunction GetScrollFlickAlphaFunction() const
124   {
125     return mFlickAlphaFunction;
126   }
127
128   /**
129    * @copydoc Toolkit::ScrollView::SetScrollFlickAlphaFunction
130    */
131   void SetScrollFlickAlphaFunction(AlphaFunction alpha)
132   {
133     mFlickAlphaFunction = alpha;
134   }
135
136   /**
137    * @copydoc Toolkit::ScrollView::GetScrollSnapDuration
138    */
139   float GetScrollSnapDuration() const
140   {
141     return mSnapDuration;
142   }
143
144   /**
145    * @copydoc Toolkit::ScrollView::SetScrollSnapDuration
146    */
147   void SetScrollSnapDuration(float time)
148   {
149     mSnapDuration = time;
150   }
151
152   /**
153    * @copydoc Toolkit::ScrollView::GetScrollFlickDuration
154    */
155   float GetScrollFlickDuration() const
156   {
157     return mFlickDuration;
158   }
159
160   /**
161    * @copydoc Toolkit::ScrollView::SetScrollFlickDuration
162    */
163   void SetScrollFlickDuration(float time)
164   {
165     mFlickDuration = time;
166   }
167
168   /**
169    * @copydoc Toolkit::ScrollView::ApplyEffect
170    */
171   void ApplyEffect(Toolkit::ScrollViewEffect effect);
172
173   /**
174    * @copydoc Toolkit::ScrollView::RemoveEffect
175    */
176   void RemoveEffect(Toolkit::ScrollViewEffect effect);
177
178   /**
179    * @copydoc Toolkit::ScrollView::RemoveAllEffects
180    */
181   void RemoveAllEffects();
182
183   /**
184    * @copydoc Toolkit::ScrollView::ApplyConstraintToChildren
185    */
186   void ApplyConstraintToChildren(Constraint constraint);
187
188   /**
189    * @copydoc Toolkit::ScrollView::RemoveConstraintsFromChildren
190    */
191   void RemoveConstraintsFromChildren();
192
193   /**
194    * @copydoc Toolkit::ScrollView::GetRulerX
195    */
196   const RulerPtr GetRulerX() const
197   {
198     return mRulerX;
199   }
200
201   /**
202    * @copydoc Toolkit::ScrollView::GetRulerY
203    */
204   const RulerPtr GetRulerY() const
205   {
206     return mRulerY;
207   }
208
209   /**
210    * @copydoc Toolkit::ScrollView::SetRulerX
211    */
212   void SetRulerX(RulerPtr ruler);
213
214   /**
215    * @copydoc Toolkit::ScrollView::SetRulerY
216    */
217   void SetRulerY(RulerPtr ruler);
218
219   /**
220    * Retrieve the touch sensitivity.
221    *
222    * @return whether the touch sensitivity is true or false.
223    */
224   bool GetScrollSensitive()
225   {
226     return mSensitive;
227   }
228
229   /**
230    * @copydoc Toolkit::ScrollView::SetScrollSensitive
231    */
232   void SetScrollSensitive(bool sensitive);
233
234   /**
235    * @copydoc Toolkit::ScrollView::SetMaxOvershoot
236    */
237   void SetMaxOvershoot(float overshootX, float overshootY);
238
239   /**
240    * @copydoc Toolkit::ScrollView::SetSnapOvershootAlphaFunction
241    */
242   void SetSnapOvershootAlphaFunction(AlphaFunction alpha)
243   {
244     mSnapOvershootAlphaFunction = alpha;
245   }
246
247   /**
248    * Retrieve the duartion of Snap Overshoot animation
249    *
250    * @return the duration.
251    */
252   float GetSnapOvershootDuration()
253   {
254     return mSnapOvershootDuration;
255   }
256
257   /**
258    * @copydoc Toolkit::ScrollView::SetSnapOvershootDuration
259    */
260   void SetSnapOvershootDuration(float duration)
261   {
262     mSnapOvershootDuration = duration;
263   }
264
265   /**
266    * Retrieve whether Actor Auto-Snap mode is enabled or not.
267    *
268    * @return Actor Auto-Snap mode Enabled flag.
269    */
270   bool GetActorAutoSnap();
271
272   /**
273    * @copydoc Toolkit::ScrollView::SetActorAutoSnap
274    */
275   void SetActorAutoSnap(bool enable)
276   {
277     mActorAutoSnapEnabled = enable;
278   }
279
280   /**
281    * Enables or Disables Auto Resizing mode for ScrollView contents.
282    *
283    * When enabled, the ScrollView's X/Y Domains are restricted to the
284    * dimensions of the content's bounds, which may change as Actors are
285    * Added/Removed, and repositioned.
286    *
287    * @note This has been disabled for now, as this requires some fundamental
288    * changes to the way Actors positions and bounds are retrieved.
289    * (currently only constraints have these initial state knowledge)
290    *
291    * @param[in] enable Enables (true), or disables (false) Auto Resize.
292    */
293   void SetAutoResize(bool enable);
294
295   /**
296    * Returns whether the wrap mode has been enabled (true) or not (false).
297    *
298    * @return Wrap Mode Enabled flag.
299    */
300   bool GetWrapMode() const
301   {
302     return mWrapMode;
303   }
304
305   /**
306    * @copydoc Toolkit::ScrollView::SetWrapMode
307    */
308   void SetWrapMode(bool enable);
309
310   /**
311    * @copydoc Toolkit::ScrollView::GetScrollupdateDistance
312    */
313   int GetScrollUpdateDistance() const
314   {
315     return mScrollUpdateDistance;
316   }
317
318   /**
319    * @copydoc Toolkit::ScrollView::SetScrollUpdateDistance
320    */
321   void SetScrollUpdateDistance(int distance)
322   {
323     mScrollUpdateDistance = distance;
324   }
325
326   /**
327    * @copydoc Toolkit::ScrollView::GetAxisAutoLock
328    */
329   bool GetAxisAutoLock() const
330   {
331     return mAxisAutoLock;
332   }
333
334   /**
335    * @copydoc Toolkit::ScrollView::SetAxisAutoLock
336    */
337   void SetAxisAutoLock(bool enable);
338
339   /**
340    * @copydoc Toolkit::ScrollView::GetAxisAutoLockGradient
341    */
342   float GetAxisAutoLockGradient() const
343   {
344     return mAxisAutoLockGradient;
345   }
346
347   /**
348    * @copydoc Toolkit::ScrollView::SetAxisAutoLockGradient
349    */
350   void SetAxisAutoLockGradient(float gradient);
351
352   /**
353    * @copydoc Toolkit::ScrollView::GetFrictionCoefficient
354    */
355   float GetFrictionCoefficient() const
356   {
357     return mFrictionCoefficient;
358   }
359
360   /**
361    * @copydoc Toolkit::ScrollView::SetFrictionCoefficient
362    */
363   void SetFrictionCoefficient(float friction);
364
365   /**
366    * @copydoc Toolkit::ScrollView::GetFlickSpeedCoefficient
367    */
368   float GetFlickSpeedCoefficient() const
369   {
370     return mFlickSpeedCoefficient;
371   }
372
373   /**
374    * @copydoc Toolkit::ScrollView::SetFlickSpeedCoefficient
375    */
376   void SetFlickSpeedCoefficient(float speed)
377   {
378     mFlickSpeedCoefficient = speed;
379   }
380
381   /**
382    * @copydoc Toolkit::ScrollView::GetMinimumDistanceForFlick
383    */
384   Vector2 GetMinimumDistanceForFlick() const
385   {
386     return mMinFlickDistance;
387   }
388
389   /**
390    * @copydoc Toolkit::ScrollView::SetMinimumDistanceForFlick
391    */
392   void SetMinimumDistanceForFlick(const Vector2& distance)
393   {
394     mMinFlickDistance = distance;
395   }
396
397   /**
398    * @copydoc Toolkit::ScrollView::GetMinimumSpeedForFlick
399    */
400   float GetMinimumSpeedForFlick() const
401   {
402     return mFlickSpeedThreshold;
403   }
404
405   /**
406    * @copydoc Toolkit::ScrollView::SetMinimumSpeedForFlick
407    */
408   void SetMinimumSpeedForFlick(float speed)
409   {
410     mFlickSpeedThreshold = speed;
411   }
412
413   /**
414    * @copydoc Toolkit::ScrollView::GetMaxFlickSpeed
415    */
416   float GetMaxFlickSpeed() const
417   {
418     return mMaxFlickSpeed;
419   }
420
421   /**
422    * @copydoc Toolkit::ScrollView::SetMaxFlickSpeed
423    */
424   void SetMaxFlickSpeed(float speed)
425   {
426     mMaxFlickSpeed = speed;
427   }
428
429   /**
430    * @copydoc Toolkit::ScrollView::GetWheelScrollDistanceStep
431    */
432   Vector2 GetWheelScrollDistanceStep() const
433   {
434     return mWheelScrollDistanceStep;
435   }
436
437   /**
438    * @copydoc Toolkit::ScrollView::SetWheelScrollDistanceStep
439    */
440   void SetWheelScrollDistanceStep(Vector2 step)
441   {
442     mWheelScrollDistanceStep = step;
443   }
444
445   /**
446    * @copydoc Toolkit::ScrollView::GetCurrentPage
447    */
448   unsigned int GetCurrentPage() const;
449
450   /**
451    * @copydoc Toolkit::ScrollView::GetCurrentScrollPosition
452    */
453   Vector2 GetCurrentScrollPosition() const;
454
455   /**
456    * @copydoc ScrollTo(const Vector2&)
457    */
458   void TransformTo(const Vector2& position,
459                    DirectionBias  horizontalBias = DIRECTION_BIAS_NONE,
460                    DirectionBias  verticalBias   = DIRECTION_BIAS_NONE);
461
462   /**
463    * @copydoc ScrollTo(const Vector2&, float, AlhpaFunction, DirectionBias, DirectionBias)
464    */
465   void TransformTo(const Vector2& position, float duration, AlphaFunction alpha, DirectionBias horizontalBias = DIRECTION_BIAS_NONE, DirectionBias verticalBias = DIRECTION_BIAS_NONE);
466
467   /**
468    * @copydoc Toolkit::ScrollView::ScrollTo(const Vector2 &position)
469    */
470   void ScrollTo(const Vector2& position);
471
472   /**
473    * @copydoc Toolkit::Scrollable::ScrollTo(const Vector2& position, float duration)
474    */
475   void ScrollTo(const Vector2& position, float duration);
476
477   /**
478    * @copydoc Toolkit::Scrollable::ScrollTo(const Vector2& position, float duration, AlphaFunction alpha)
479    */
480   void ScrollTo(const Vector2& position, float duration, AlphaFunction alpha);
481
482   /**
483    * @copydoc Toolkit::ScrollView::ScrollTo(const Vector2 &position, float duration, DirectionBias horizontalBias, DirectionBias verticalBias)
484    */
485   void ScrollTo(const Vector2& position, float duration, DirectionBias horizontalBias, DirectionBias verticalBias);
486
487   /**
488    * @copydoc Toolkit::ScrollView::ScrollTo(const Vector2 &position, float duration, AlphaFunction alpha, DirectionBias horizontalBias, DirectionBias verticalBias)
489    */
490   void ScrollTo(const Vector2& position, float duration, AlphaFunction alpha, DirectionBias horizontalBias, DirectionBias verticalBias);
491
492   /**
493    * @copydoc Toolkit::ScrollView::ScrollTo(unsigned int page)
494    */
495   void ScrollTo(unsigned int page);
496
497   /**
498    * @copydoc Toolkit::ScrollView::ScrollTo(unsigned int page, float duration, DirectionBias bias)
499    */
500   void ScrollTo(unsigned int page, float duration, DirectionBias bias = DIRECTION_BIAS_NONE);
501
502   /**
503    * @copydoc Toolkit::ScrollView::ScrollTo(Actor& actor)
504    */
505   void ScrollTo(Actor& actor);
506
507   /**
508    * @copydoc Toolkit::ScrollView::ScrollTo(Actor& actor, float duration)
509    */
510   void ScrollTo(Actor& actor, float duration);
511
512   /**
513    * @copydoc Toolkit::ScrollView::SetScrollingDirection()
514    */
515   void SetScrollingDirection(Radian direction, Radian threshold);
516
517   /**
518    * @copydoc Toolkit::ScrollView::RemoveScrollingDirection()
519    */
520   void RemoveScrollingDirection(Radian angle);
521
522   /**
523     * Finds the closest Actor to the current center of the ScrollView.
524     *
525     * @return A handle to the actor if found, or an empty handle if not.
526     */
527   Actor FindClosestActor();
528
529   /**
530    * Finds the closest Actor to position in ScrollView
531    *
532    * @param[in] position position within ScrollView.
533    * @param[in] dirX Whether to search only those elements that are Left,Right, or All
534    * @param[in] dirY Whether to search only those elements that are Up,Down, or All
535    * @param[in] dirZ Whether to search only those elements that are Out,In, or All
536    * @return A handle to the actor if found, or an empty handle if not.
537    */
538   Actor FindClosestActorToPosition(const Vector3& position, FindDirection dirX = All, FindDirection dirY = All, FindDirection dirZ = All);
539
540   /**
541    * @copydoc Toolkit::ScrollView::ScrollToSnapPoint
542   */
543   bool ScrollToSnapPoint();
544
545   /**
546    * Stops animation
547    */
548   void StopAnimation(void);
549
550   /**
551    * Stops the input animation
552    *
553    * @param[in] the animation to stop
554    */
555   void StopAnimation(Animation& animation);
556
557   /**
558    * Animates to position transform.
559    *
560    * @param[in] position The position to animate to
561    * @param[in] positionDuration The number of seconds this animation should run for in each axis.
562    * @param[in] alpha The easing alpha function to use.
563    * @param[in] findShortcuts (optional) Whether to find the shortest route (in Wrap mode)
564    * @param[in] horizontalBias (optional) Whether to bias animation to left or right (or no biasing)
565    * @param[in] verticalBias (optional) Whether to bias animation to top or bottom (or no biasing)
566    * @return True if animation necessary and taking place to reach desired transform.
567    */
568   bool AnimateTo(const Vector2& position, const Vector2& positionDuration, AlphaFunction alpha, bool findShortcuts = true, DirectionBias horizontalBias = DIRECTION_BIAS_NONE, DirectionBias verticalBias = DIRECTION_BIAS_NONE, SnapType snapType = SNAP);
569
570   /**
571    * @copydoc Toolkit::Scrollable::AddOverlay()
572    */
573   void AddOverlay(Actor actor);
574
575   /**
576    * @copydoc Toolkit::Scrollable::RemoveOverlay()
577    */
578   void RemoveOverlay(Actor actor);
579
580   /**
581    * @copydoc Toolkit::Internal::Scrollable::SetOvershootSize
582    */
583   void SetOvershootSize(const Vector2& size);
584
585   /**
586    * @copydoc Toolkit::Internal::Scrollable::SetOvershootEffectColor
587    */
588   void SetOvershootEffectColor(const Vector4& color);
589
590   //properties
591
592   /**
593    * Called when a property of an object of this type is set.
594    * @param[in] object The object whose property is set.
595    * @param[in] index The property index.
596    * @param[in] value The new property value.
597    */
598   static void SetProperty(BaseObject* object, Property::Index index, const Property::Value& value);
599
600   /**
601    * Called to retrieve a property of an object of this type.
602    * @param[in] object The object whose property is to be retrieved.
603    * @param[in] index The property index.
604    * @return The current value of the property.
605    */
606   static Property::Value GetProperty(BaseObject* object, Property::Index index);
607
608 public: //Signals
609   /**
610    * @copydoc Dali::Toolkit::ScrollView::SnapStartedSignal()
611    */
612   Toolkit::ScrollView::SnapStartedSignalType& SnapStartedSignal();
613
614   /**
615    * Connects a callback function with the object's signals.
616    * @param[in] object The object providing the signal.
617    * @param[in] tracker Used to disconnect the signal.
618    * @param[in] signalName The signal to connect to.
619    * @param[in] functor A newly allocated FunctorDelegate.
620    * @return True if the signal was connected.
621    * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
622    */
623   static bool DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor);
624
625 private: // private overridden functions from CustomActorImpl and Controls
626   /**
627    * @copydoc Dali::CustomActorImpl::OnSizeAnimation(Animation&, const Vector3&)
628    */
629   void OnSizeAnimation(Animation& animation, const Vector3& targetSize) override;
630
631   /**
632    * @copydoc CustomActorImpl::OnSizeSet(const Vector3&)
633    */
634   void OnSizeSet(const Vector3& size) override;
635
636   /**
637    * From CustomActorImpl; called after a child has been added to the owning actor.
638    * @param[in] child The child which has been added.
639    */
640   void OnChildAdd(Actor& child) override;
641
642   /**
643    * From CustomActorImpl; called shortly before a child is removed from the owning actor.
644    * @param[in] child The child being removed.
645    */
646   void OnChildRemove(Actor& child) override;
647
648   /**
649    * Called after a wheelEvent is received by the owning actor.
650    * @param[in] actor Actor associated with the event.
651    * @param[in] event The wheel event.
652    * @return True if the event should be consumed.
653    */
654   bool OnWheelEvent(Actor actor, const WheelEvent& event);
655
656   /**
657    * @copydoc Toolkit::Control::OnInitialize()
658    */
659   void OnInitialize() override;
660
661   /**
662    * @copydoc CustomActorImpl::OnSceneConnection()
663    */
664   void OnSceneConnection(int depth) override;
665
666   /**
667    * @copydoc CustomActorImpl::OnSceneDisconnection()
668    */
669   void OnSceneDisconnection() override;
670
671   /**
672    * @copydoc Toolkit::Control::OnAccessibilityPan()
673    */
674   bool OnAccessibilityPan(PanGesture gesture) override;
675
676   /**
677    * @copydoc Toolkit::Scrollable::EnableScrollOvershoot()
678    */
679   void EnableScrollOvershoot(bool enable) override;
680
681 private:
682   /**
683    * Called after a touchSignal is received by the owning actor.
684    *
685    * We don't consume these events as content within the container may consume events.
686    *
687    * @param[in] actor The touched actor.
688    * @param[in] touch The touch information.
689    * @return True if the event should be consumed.
690    */
691   bool OnTouch(Actor actor, const TouchEvent& touch);
692
693   /**
694    * Start a timer which calls OnTouchDownTimeout()
695    */
696   void StartTouchDownTimer();
697
698   /**
699    * Stop a timer which calls OnTouchDownTimeout()
700    */
701   void StopTouchDownTimer();
702
703   /**
704    * Helper to detect when touch-point has been down (outside of pan gesture)
705    */
706   bool OnTouchDownTimeout();
707
708   /**
709    * Called whenever a snap animation has completed
710    * @param[in] source the Animation instance that has completed.
711    * Resets all scrolling animations and states, leaving current scroll position at SCROLL_POSITION
712    */
713   void ResetScrolling();
714
715   /**
716    * Updates mScrollInternalPosition, mScrollPrePosition and mScrollPostPosition from their property counterparts
717    */
718   void UpdateLocalScrollProperties();
719
720   /**
721    * Makes sure scroll values are ready for animated scrolling
722    */
723   void PreAnimatedScrollSetup();
724
725   /**
726    * Finish an animated scroll, ensuring all scroll properties are updated
727    * and synchronised
728    */
729   void FinaliseAnimatedScroll();
730
731   /**
732    * Animates the internal x property to the given value
733    *
734    * @param[in] position The X position to animate to
735    * @param[in] duration The time in seconds for animation
736    * @param[in] alpha The alpha function to use for animating
737    */
738   void AnimateInternalXTo(float position, float duration, AlphaFunction alpha);
739
740   /**
741    * Animates the internal y property to the given value
742    *
743    * @param[in] position The Y position to animate to
744    * @param[in] duration The time in seconds for animation
745    * @param[in] alpha The alpha function to use for animating
746    */
747   void AnimateInternalYTo(float position, float duration, AlphaFunction alpha);
748
749   /**
750    * Called whenever a snap animation on the x-axis has completed
751    * @param[in] source the Animation instance that has completed.
752    */
753   void OnScrollAnimationFinished(Animation& source);
754
755   /**
756    * Called when either the X or Y internal scroll positions have finished snapping back to SCROLL_PRE_POSITION
757    *
758    * @param[in] source the Animation instance that has completed.
759    */
760   void OnSnapInternalPositionFinished(Animation& source);
761
762   /**
763    * Called whenever a snap animation on the x-axis has completed and we need to snap pre scroll
764    * position to our clamped position
765    * @param[in] position The x position to snap pre scroll property to
766    */
767   void SnapInternalXTo(float position);
768
769   /**
770    * Called whenever a snap animation on the y-axis has completed and we need to snap pre scroll
771    * position to our clamped position
772    * @param[in] position The y position to snap pre scroll property to
773    */
774   void SnapInternalYTo(float position);
775
776   /**
777    * This is called internally whenever the Scroll Rulers are
778    * modified. This will update the properties: 'scrollPositionMin'
779    * and 'scrollPositionMax' to reflect the changes.
780    */
781   void UpdatePropertyDomain();
782
783   /**
784    * Called when the gesture starts.
785    */
786   void GestureStarted();
787
788   /**
789    * Amalgamated Gesture Continuing event
790    *
791    * @param[in] panDelta average panning delta from base position (0)
792    */
793   void GestureContinuing(const Vector2& panDelta);
794
795   /**
796    * Called upon pan gesture event.
797    *
798    * @param[in] gesture The gesture event.
799    */
800   void OnPan(const PanGesture& pan);
801
802   /**
803    * Extension of the above gestures.
804    *
805    * @param[in] gesture The gesture event.
806    */
807   void OnGestureEx(GestureState state);
808
809   /**
810    * Performs snapping while taking into account Velocity of gesture
811    * (velocity in pixels/sec)
812    *
813    * @param[in] velocity velocity in pixels/sec
814    */
815   bool SnapWithVelocity(Vector2 velocity);
816
817   /**
818    * Finishes Container Transform
819    * (occurs upon finishing gesture i.e. releasing)
820    */
821   void FinishTransform();
822
823   /**
824    * Returns overshoot vector based on current position
825    *
826    * Overshoot vector is defined as how far outside of bounds
827    * the viewport is trying to view (prior to being clamped).
828    *
829    * an overshoot of (100,50), means user is in bottom right corner,
830    * trying to pan +100 to the right, and +50 below. This can be used
831    * to determine an effect, such as stretching.
832    *
833    * @param[in] position The position for which you wish to obtain overshoot vector
834    */
835   Vector2 GetOvershoot(Vector2& position) const;
836
837   /**
838    * Clamps position within the domain set up by X/Y Rulers
839    *
840    * @param[in,out] position The position you wish to clamp
841    */
842   void ClampPosition(Vector2& position) const;
843
844   /**
845    * Clamps position within the domain set up by X/Y Rulers
846    *
847    * @param[in,out] position The position you wish to clamp
848    * @param[out] clamped The results of the clamping.
849    */
850   void ClampPosition(Vector2& position, ClampState2D& clamped) const;
851
852   /**
853    * Wraps position within the domain set up by X/Y Rulers
854    *
855    * @note Only wraps if mWrapMode is enabled, and respective domains
856    * are enabled.
857    *
858    * @param[in,out] position The position you wish to wrap
859    */
860   void WrapPosition(Vector2& position) const;
861
862 protected:
863   struct AccessibleImpl : public Scrollable::AccessibleImpl
864   {
865     using Scrollable::AccessibleImpl::AccessibleImpl;
866
867     bool ScrollToChild(Actor child) override;
868   };
869
870   /**
871    * Construct a new ScrollView.
872    */
873   ScrollView();
874
875   /**
876    * A reference counted object may only be deleted by calling Unreference()
877    */
878   virtual ~ScrollView();
879
880 private:
881   /**
882    * Searches this ScrollView, and attempts to Unbind
883    * systematically this Actor from the ScrollView attached.
884    *
885    * @param[in] child The actor to be unbound.
886    */
887   void FindAndUnbindActor(Actor child) override;
888
889   /**
890    * Gets position property.
891    *
892    * @return The current position
893    */
894   Vector2 GetPropertyPrePosition() const;
895
896   /**
897    * Gets position property.
898    *
899    * @return The current position
900    */
901   Vector2 GetPropertyPosition() const;
902
903   /**
904    * Handles a Stopped animation. Its position properties need to be saved, and the animation flag
905    * switched off.
906    */
907   void HandleStoppedAnimation();
908
909   /**
910    * Handles a Stopped animation (whether the animation completed, or was
911    * manually stopped). Its position properties need to be saved, and the
912    * animation flag switched off.
913    */
914   void HandleSnapAnimationFinished();
915
916   /**
917    * Checks if the property notifications are active and adds them if not
918    */
919   void SetScrollUpdateNotification(bool enabled);
920
921   /**
922    * Refresh the ScrollView (used when animating to update application developer of changes)
923    * @return True if the refresh timer should be kept running.
924    */
925   void OnScrollUpdateNotification(Dali::PropertyNotification& source);
926
927   /**
928    * Set up default rulers using a property map
929    * @param[in] scrollModeMap A map defining the characteristics of X and Y scrolling
930    * using either FixedRuler or DefaultRuler.
931    */
932   void SetScrollMode(const Property::Map& scrollModeMap);
933
934 private:
935   // Undefined
936   ScrollView(const ScrollView&);
937
938   // Undefined
939   ScrollView& operator=(const ScrollView& rhs);
940
941 private:
942   ScrollViewConstraints mConstraints;
943
944   unsigned long mTouchDownTime; ///< The touch down time
945
946   int     mGestureStackDepth; ///< How many gestures are currently occuring.
947   Vector2 mPanStartPosition;  ///< Where the pan gesture's touch down occured
948   Vector2 mPanDelta;          ///< Amount currently panned.
949
950   unsigned int mScrollStateFlags; ///< flags indicating current state of scrolling
951   // Scroll delegate pre and post position properties...
952   Vector2 mScrollPrePosition;    ///< Wrapped scroll position, but not clamped
953   Vector2 mScrollPostPosition;   ///< Wrapped and clamped, this is the final scroll position used
954   Vector2 mScrollTargetPosition; ///< Final target position for an animated scroll
955   Vector2 mDomainOffset;         ///< Domain offset (this keeps track of the domain boundaries that scroll positions traverses)
956
957   // Rulers for each axes...
958   RulerPtr mRulerX;
959   RulerPtr mRulerY;
960
961   // Last property values set to ScrollView
962   Vector2 mMinScroll;
963   Vector2 mMaxScroll;
964
965   Animation mInternalXAnimation; ///< Animates mPropertyX to a snap position or application requested scroll position
966   Animation mInternalYAnimation; ///< Animates mPropertyY to a snap position or application requested scroll position
967
968   Vector2  mLastVelocity; ///< Record the last velocity from PanGesture (Finish event doesn't have correct velocity)
969   LockAxis mLockAxis;
970
971   Timer mTouchDownTimer; ///< Used to interrupt snap-animation. This cannot be done in OnTouch without breaking fast flick behavior.
972
973   float                      mScrollUpdateDistance;      ///< Distance for scrolling to travel for the scroll update notifications
974   Dali::PropertyNotification mScrollXUpdateNotification; ///< scroll x position update notification
975   Dali::PropertyNotification mScrollYUpdateNotification; ///< scroll y position update notification
976
977   Actor mInternalActor; ///< Internal actor (we keep internal actors in here e.g. scrollbars, so we can ignore it in searches)
978
979   ScrollViewEffectContainer mEffects; ///< Container keeping track of all the applied effects.
980
981   Vector2       mMaxOvershoot;               ///< Number of scrollable pixels that will take overshoot from 0.0f to 1.0f
982   Vector2       mUserMaxOvershoot;           ///< Set by user, allows overriding of default max overshoot for the scroll indicator
983   float         mSnapOvershootDuration;      ///< Duration for overshoot snapping back to Vector2::ZERO
984   AlphaFunction mSnapOvershootAlphaFunction; ///< AlphaFunction to be used for this overshoot.
985
986   float         mSnapDuration;      ///< Time for the snap animation to take (in seconds).
987   AlphaFunction mSnapAlphaFunction; ///< AlphaFunction to be used for the Snap Animation.
988
989   Vector2       mMinFlickDistance;    ///< Minimum pan distance required for a flick
990   float         mFlickSpeedThreshold; ///< Minimum pan speed required for a flick in pixels/ms
991   float         mFlickDuration;       ///< Time for the flick animation to take (in seconds).
992   AlphaFunction mFlickAlphaFunction;  ///< AlphaFunction to be used for the Flick Animation.
993
994   float mAxisAutoLockGradient;  ///< Axis Auto-lock gradient threshold. Above this gradient and it will lock scrolling to closest axis.
995   float mFrictionCoefficient;   ///< Friction coefficient. Amount of friction to apply to free panning flick animation. in stage.lengths/sec
996   float mFlickSpeedCoefficient; ///< Flick velocity coefficient. Input touch velocity is multiplied by this.
997   float mMaxFlickSpeed;         ///< Maximum flick speed. Maximum speed of flick in stage.lengths/sec.
998
999   Vector2 mWheelScrollDistanceStep; ///< The step of scroll distance in actor coordinates in X and Y axes for each wheel event received.
1000
1001   ScrollOvershootIndicatorPtr    mOvershootIndicator;
1002   WeakHandle<Toolkit::ScrollBar> mScrollBar;
1003
1004   Toolkit::ScrollView::SnapStartedSignalType mSnapStartedSignal;
1005
1006   bool mInAccessibilityPan : 1;         ///< With AccessibilityPan its easier to move between snap positions
1007   bool mScrolling : 1;                  ///< Flag indicating whether the scroll view is being scrolled (by user or animation)
1008   bool mScrollInterrupted : 1;          ///< Flag set for when a down event interrupts a scroll
1009   bool mPanning : 1;                    ///< Whether scroll view is currently panning or not
1010   bool mSensitive : 1;                  ///< Scroll Sensitivity Flag.
1011   bool mTouchDownTimeoutReached : 1;    ///< Indicates when down event timeout occured without corresponding up event (touch still down)
1012   bool mActorAutoSnapEnabled : 1;       ///< Whether to automatically snap to closest actor.
1013   bool mAutoResizeContainerEnabled : 1; ///< Whether to automatically resize container (affects RulerDomain's on X/Y axes)
1014   bool mWrapMode : 1;                   ///< Whether to wrap contents based on container size.
1015   bool mAxisAutoLock : 1;               ///< Whether to automatically lock axis when panning.
1016   bool mAlterChild : 1;                 ///< Internal flag to control behavior of OnChildAdd/OnChildRemove when Adding internal Actors.
1017   bool mDefaultMaxOvershoot : 1;        ///< Whether to use default max overshoot or application defined one
1018   bool mCanScrollHorizontal : 1;        ///< Local value of our property to check against
1019   bool mCanScrollVertical : 1;          ///< Local value of our property to check against
1020   bool mTransientScrollBar : 1;         ///< True if scroll-bar should be automatically show/hidden during/after panning
1021
1022   friend ScrollViewConstraints;
1023 };
1024
1025 /**
1026  * Returns whether to lock scrolling to a particular axis
1027  *
1028  * @param[in] panDelta Distance panned since gesture started
1029  * @param[in] currentLockAxis The current lock axis value
1030  * @param[in] lockGradient How quickly to lock to a particular axis
1031  *
1032  * @return The new axis lock state
1033  */
1034 ScrollView::LockAxis GetLockAxis(const Vector2& panDelta, ScrollView::LockAxis currentLockAxis, float lockGradient);
1035
1036 } // namespace Internal
1037
1038 // Helpers for public-api forwarding methods
1039
1040 inline Toolkit::Internal::ScrollView& GetImpl(Toolkit::ScrollView& scrollView)
1041 {
1042   DALI_ASSERT_ALWAYS(scrollView);
1043
1044   Dali::RefObject& handle = scrollView.GetImplementation();
1045
1046   return static_cast<Toolkit::Internal::ScrollView&>(handle);
1047 }
1048
1049 inline const Toolkit::Internal::ScrollView& GetImpl(const Toolkit::ScrollView& scrollView)
1050 {
1051   DALI_ASSERT_ALWAYS(scrollView);
1052
1053   const Dali::RefObject& handle = scrollView.GetImplementation();
1054
1055   return static_cast<const Toolkit::Internal::ScrollView&>(handle);
1056 }
1057
1058 } // namespace Toolkit
1059
1060 } // namespace Dali
1061
1062 #endif // DALI_TOOLKIT_INTERNAL_SCROLL_VIEW_H