Merge changes I2df640e0,Ia1188305,I7fae506e,I7967a7cc,Ib0fdcdf4, ... into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / slider / slider-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_SLIDER_H
2 #define DALI_TOOLKIT_INTERNAL_SLIDER_H
3
4 /*
5  * Copyright (c) 2020 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/object/property-array.h>
24 #include <dali/public-api/object/property-map.h>
25
26 // INTERNAL INCLUDES
27 #include <dali-toolkit/public-api/controls/control-impl.h>
28 #include <dali-toolkit/public-api/controls/slider/slider.h>
29 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
30 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
31 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
32
33 namespace Dali
34 {
35
36 namespace Toolkit
37 {
38
39 class Button;
40
41 namespace Internal
42 {
43
44 class Slider;
45
46 typedef Dali::IntrusivePtr< Slider > SliderPtr;
47
48 /**
49  * @copydoc Toolkit::Slider
50  */
51 class Slider : public Control
52 {
53 public:
54
55   typedef Property::Array MarkList;
56
57   /**
58    * Create a new Slider.
59    *
60    * @return A public handle to the newly allocated Slider.
61    */
62   static Dali::Toolkit::Slider New();
63
64 public:
65
66   // Properties
67
68   /**
69    * Set marks from a list
70    *
71    * @param[in] marks The list of marks to set
72    */
73   void SetMarks( const MarkList& marks );
74
75   /**
76    * Get the list of marks
77    *
78    * @return The marks list
79    */
80   const MarkList& GetMarks() const;
81
82   /**
83    * Set if should snap to marks or not
84    *
85    * @param[in] snap Flag to snap to marks or not
86    */
87   void SetSnapToMarks( bool snap );
88
89   /**
90    * Return if snap to marks is set or not
91    *
92    * @return If snap to marks is set
93    */
94   bool GetSnapToMarks() const;
95
96   /**
97    * Set the value of the slider
98    *
99    * @param[in] value The value to set. Will be clamped to [lowerBound .. upperBound]
100    */
101   void SetValue( float value );
102
103   /**
104    * Get the value of the slider
105    *
106    * @return The current value of the slider
107    */
108   float GetValue() const;
109
110   /**
111    * Set hit region
112    *
113    * @param[in] region The hit region
114    */
115   void SetHitRegion( const Vector2& region );
116
117   /**
118    * Get hit region
119    *
120    * @return The hit region
121    */
122   const Vector2& GetHitRegion() const;
123
124   /**
125    * Set the track region
126    *
127    * @param[in] region The track region
128    */
129   void SetTrackRegion( const Vector2& region );
130
131   /**
132    * Get the track region
133    *
134    * @return The track region
135    */
136   const Vector2& GetTrackRegion() const;
137
138   /**
139    * @brief Set the disabled color.
140    *
141    * @param[in] color The disabled color.
142    */
143   void SetDisabledColor( const Vector4& color );
144
145   /**
146    * @brief Get disabled color
147    *
148    * @return The disabled color
149    */
150   Vector4 GetDisabledColor() const;
151
152   /**
153    * Set the value precision to be used for numbers in the slider
154    *
155    * @param[in] precision The number of decimal places to use for printing numbers
156    */
157   void SetValuePrecision( int precision );
158
159   /**
160    * Get value precision
161    *
162    * @return The value precision
163    */
164   int GetValuePrecision() const;
165
166   /**
167    * Show the popup
168    *
169    * @param[in] showPopup The show popup flag
170    */
171   void SetShowPopup( bool showPopup );
172
173   /**
174    * Get show value in popup
175    *
176    * @return The show value flag
177    */
178   bool GetShowPopup() const;
179
180   /**
181    * Set show value on handle
182    *
183    * @param[in] showValue The show value flag
184    */
185   void SetShowValue( bool showValue );
186
187   /**
188    * Get show value on handle
189    *
190    * @return The show value flag
191    */
192   bool GetShowValue() const;
193
194   /**
195    * Set enabled
196    *
197    * param[in] enabled Set the enabled flag
198    */
199   void SetEnabled( bool enabled );
200
201   /**
202    * Return if enabled or not
203    *
204    * @return If enabled
205    */
206   bool IsEnabled() const;
207
208   /**
209    * @brief Set the mark tolerance
210    *
211    * The tolerance is the percentage of the slider width for which snapping to
212    * marks occurs
213    *
214    * @param[in] tolerance The percentage of width for which to snap
215    */
216   void SetMarkTolerance( float tolerance );
217
218   /**
219    * Return the mark tolerance
220    *
221    * @return The tolerance set for snapping to marks
222    */
223   float GetMarkTolerance() const;
224
225 public:
226   //Signals
227
228   /**
229    * @copydoc Toolkit::Slider::ValueChangedSignal()
230    */
231   Toolkit::Slider::ValueChangedSignalType& ValueChangedSignal();
232
233   /**
234    * copydoc Toolkit::Slider::SlidingFinishedSignal()
235    */
236   Toolkit::Slider::ValueChangedSignalType& SlidingFinishedSignal();
237
238   /**
239    * @copydoc Toolkit::Slider::MarkReachedSignal()
240    */
241   Toolkit::Slider::MarkReachedSignalType& MarkReachedSignal();
242
243   /**
244    * Connects a callback function with the object's signals.
245    * @param[in] object The object providing the signal.
246    * @param[in] tracker Used to disconnect the signal.
247    * @param[in] signalName The signal to connect to.
248    * @param[in] functor A newly allocated FunctorDelegate.
249    * @return True if the signal was connected.
250    * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
251    */
252   static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName,
253                                FunctorDelegate* functor );
254
255   // Properties
256
257   /**
258    * Called when a property of an object of this type is set.
259    * @param[in] object The object whose property is set.
260    * @param[in] index The property index.
261    * @param[in] value The new property value.
262    */
263   static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
264
265   /**
266    * Called to retrieve a property of an object of this type.
267    * @param[in] object The object whose property is to be retrieved.
268    * @param[in] index The property index.
269    * @return The current value of the property.
270    */
271   static Property::Value GetProperty( BaseObject* object, Property::Index propertyIndex );
272
273 protected:
274
275   /**
276    * Construct a new Slider.
277    */
278   Slider();
279
280   /**
281    * A reference counted object may only be deleted by calling Unreference()
282    */
283   virtual ~Slider();
284
285   /**
286    * @copydoc CustomActorImpl::OnRelayout
287    */
288   void OnRelayout( const Vector2& size, RelayoutContainer& container ) override;
289
290
291 private:
292
293   /**
294    * Domain is a from/to pair
295    */
296   struct Domain
297   {
298     Vector2 from;
299     Vector2 to;
300
301     Domain()
302     {
303     }
304     Domain( Vector2 fromVal, Vector2 toVal )
305         : from( fromVal ), to( toVal )
306     {
307     }
308   };
309
310   /**
311    * Slider states
312    */
313   enum SliderState
314   {
315     NORMAL,
316     DISABLED,
317     PRESSED,
318     FOCUSED
319   };
320
321 private:
322
323   /**
324    * @copydoc Toolkit::Control::OnInitialize()
325    */
326   void OnInitialize() override;
327
328   /**
329    * Hit region touch
330    *
331    * @param[in] actor The actor the event is raised for
332    * @param[in] touch The touch info
333    * @return If touch is handled or not
334    */
335   bool OnTouch( Actor actor, const TouchEvent& touch );
336
337   /**
338    * Pan gesture event
339    *
340    * @param[in] actor The actor the event is raised for
341    * @param[in] gesture The pan event info
342    */
343   void OnPan( Actor actor, const PanGesture& gesture );
344
345   /**
346    * Map a position onto a domain and return the result as a percentage
347    *
348    * @param[in] point The point to map onto the domain
349    * @return The result as a percentage [0..1]
350    */
351   float MapPercentage( const Vector2& point );
352
353   /**
354    * Map a value in the range to a percentage
355    *
356    * @param[in] point The value in range [lowerBound..upperBound]
357    * @return The result as a percentage [0..1]
358    */
359   float MapValuePercentage( float value );
360
361   /**
362    * Convert a point in local hit space into domain space
363    *
364    * @param[in] x The x position to convert
365    * @return The x position in domain space
366    */
367   float HitSpaceToDomain( float x );
368
369   /**
370    * Map a percentage onto the slider's bounds
371    *
372    * @param[in] percent The current value of slider in percent
373    * @param[in] lowerBound The lower bound to map onto
374    * @param[in] upperBound The upper bound to map onto
375    * @return The value of percent mapped from lowerBound to upperBound
376    */
377   float MapBounds( float percent, float lowerBound, float upperBound );
378
379   /**
380    * Get the range of the valid values the slider handle can move between
381    *
382    * @param[in] currentSize The current size of the slider
383    * @return The range as a domain pair
384    */
385   Domain CalcDomain( const Vector2& currentSize );
386
387   /**
388    * Create the hit region
389    *
390    * @return The hit region actor
391    */
392   Actor CreateHitRegion();
393
394   /**
395    * Create the track for the slider
396    *
397    * @return The track actor
398    */
399   Toolkit::ImageView CreateTrack();
400
401   /**
402    * Create the progress track for the slider
403    *
404    * @return The track actor
405    */
406   Toolkit::ImageView CreateProgress();
407
408   /**
409    * Create the handle for the slider
410    *
411    * @return The created image handle
412    */
413   Toolkit::ImageView CreateHandle();
414
415   /**
416    * Create the popup arrow
417    *
418    * @return The created image handle
419    */
420   Toolkit::ImageView CreatePopupArrow();
421
422   /**
423    * Create the popup
424    *
425    * @return The created image handle
426    */
427   Toolkit::ImageView CreatePopup();
428
429   /**
430    * Create the textview for the popup
431    *
432    * @return The textview created for the popup
433    */
434   Toolkit::TextLabel CreatePopupText();
435
436   /**
437    * Create the value display for the slider
438    *
439    * @return The created root actor of the display
440    */
441   Actor CreateValueDisplay();
442
443   /**
444    * Set the skin based on the current state
445    */
446   void UpdateSkin();
447
448   /**
449    * Create all the children
450    */
451   void CreateChildren();
452
453   /**
454    * Create value popup
455    */
456   void AddPopup();
457
458   /**
459    * Remove value popup
460    */
461   void RemovePopup();
462
463   /**
464    * Display the popup for a set duration with the given value
465    *
466    * @param[in] value The value to display in the popup
467    */
468   void DisplayPopup( float value );
469
470   /**
471    * If there are marks present, filter the incoming percent based on snapping to any nearby marks
472    *
473    * @param[in] value The incoming value on the slider to filter
474    * @return The filtered percentage snapped to any nearby marks
475    */
476   float MarkFilter( float value );
477
478   /**
479    * If there are marks present, snap the incoming percent to the nearest mark
480    *
481    * @param[in] value The incoming value on the slider to snap
482    * @return The filtered percentage snapped to the nearest mark
483    */
484   float SnapToMark( float value );
485
486   /**
487    * Search for if a mark has been reached
488    *
489    * @param[in] value The value to search against
490    * @param[out] outIndex The index of the mark if found
491    * @return If a mark has been found to match percent
492    */
493   bool MarkReached( float value, int& outIndex );
494
495   /**
496    * Handler for when the value view needs to be hidden
497    *
498    * @return If handled or not
499    */
500   bool HideValueView();
501
502   /**
503    * Set value choosing whether to fire signals or not
504    *
505    * @paramp[in] value The value to set
506    * @param[in] raiseSignals Configure signals to be raised or not.
507    */
508   void DisplayValue( float value, bool raiseSignals );
509
510   /**
511    * Create the image for the track
512    *
513    * @param[in] filename The track image
514    */
515   void SetTrackVisual( const std::string& filename );
516
517   /**
518    * @brief Set the track visual from an Dali::Property::Map
519    *
520    * @param[in] map The Dali::Property::Map to use for to display
521    */
522   void SetTrackVisual( Dali::Property::Map map );
523
524   /**
525    * @brief Return the track image.
526    *
527    * @return The track image.
528    */
529   std::string GetTrackVisual();
530
531   /**
532    * Create the image for the progress bar
533    *
534    * @param[in] filename The progress bar image
535    */
536   void SetProgressVisual( const std::string& filename );
537
538   /**
539    * @brief Set the progress visual from an Dali::Property::Map
540    *
541    * @param[in] map The Dali::Property::Map to use for to display
542    */
543   void SetProgressVisual( Dali::Property::Map map );
544
545   /**
546    * @brief Return the progress bar image.
547    *
548    * @return The progress bar image if it exists.
549    */
550   std::string GetProgressVisual();
551
552   /**
553    * @brief Create the image for the popup
554    *
555    * @param[in] filename The popup image
556    */
557   void CreatePopupImage( const std::string& filename );
558
559   /**
560    * @brief Set the popup image
561    *
562    * @param[in] filename The popup image to set
563    */
564   void SetPopupVisual( const std::string& filename );
565
566   /**
567    * @brief Set the popup from an Dali::Property::Map
568    *
569    * @param[in] map The Dali::Property::Map to use for to display
570    */
571   void SetPopupVisual( Dali::Property::Map map );
572
573   /**
574    * @brief Return the popup image.
575    *
576    * @return The popup image if it exists.
577    */
578   std::string GetPopupVisual();
579
580   /**
581    * @brief Set the popup arrow image
582    *
583    * @param[in] filename The popup arrow image to set
584    */
585   void SetPopupArrowVisual( const std::string& filename );
586
587   /**
588    * @brief Set the popup arrow from an Dali::Property::Map
589    *
590    * @param[in] map The Dali::Property::Map to use for to display
591    */
592   void SetPopupArrowVisual( Dali::Property::Map map );
593
594   /**
595    * @brief Return the popup arrow image.
596    *
597    * @return The popup arrow image if it exists.
598    */
599   std::string GetPopupArrowVisual();
600
601   /**
602    * Create the image for the popup arrow
603    *
604    * @param[in] filename The popup arrow image to load and set
605    */
606   void CreatePopupArrowImage( const std::string& filename );
607
608   /**
609    * Set the size of the progress bar region
610    *
611    * @param[in] region The size of the region to set
612    */
613   void ResizeProgressRegion( const Vector2& region );
614
615   /**
616    * Create the image for the handle
617    *
618    * @param[in] filename The handle image
619    */
620   void SetHandleVisual( const std::string& filename );
621
622   /**
623    * @brief Set the handle visual from an Dali::Property::Map
624    *
625    * @param[in] map The Dali::Property::Map to use for to display
626    */
627   void SetHandleVisual( Property::Map map );
628
629   /**
630    * @brief Return the handle image.
631    *
632    * @return The handle image if it exists.
633    */
634   std::string GetHandleVisual();
635
636   /**
637    * Reset the size of the handle
638    *
639    * @param[in] size The size of the handle to set
640    */
641   void ResizeHandleSize( const Vector2& size );
642
643   /**
644    * Create and display the value on the handle
645    */
646   void CreateHandleValueDisplay();
647
648   /**
649    * Remove and destroy the handle value display
650    */
651   void DestroyHandleValueDisplay();
652
653   /**
654    * Set the size of the handle
655    *
656    * @param[in] size The handle size
657    */
658   void SetHandleSize( const Vector2& size );
659
660   /**
661    * Get the size of the handle
662    *
663    * @return The handle size
664    */
665   const Vector2& GetHandleSize() const;
666
667   /**
668    * Set the lower bound of the slider's value
669    *
670    * @param[in] bound The value to set for the lower bound
671    */
672   void SetLowerBound( float bound );
673
674   /**
675    * Get the lower bound of the slider's value
676    *
677    * @return The lower bound value
678    */
679   float GetLowerBound() const;
680
681   /**
682    * Set the upper bound of the slider's value
683    *
684    * @param[in] bound The value to set for the upper bound
685    */
686   void SetUpperBound( float bound );
687
688   /**
689    * Get the upper bound of the slider's value
690    *
691    * @return The upper bound value
692    */
693   float GetUpperBound() const;
694
695 private:
696
697   // Undefined
698   Slider( const Slider& );
699
700   // Undefined
701   Slider& operator=( const Slider& rhs );
702
703 private:
704
705   Domain mDomain;                           ///< Current domain of the handle
706
707   Actor mHitArea;                           ///< The input handler
708   Actor mValueDisplay;                      ///< Display of the value
709   Toolkit::ImageView mTrack;                ///< Track image
710   Toolkit::ImageView mHandle;               ///< Slider handle
711   Toolkit::ImageView mProgress;             ///< Progress bar
712   Toolkit::ImageView mPopup;                ///< Popup backing
713   Toolkit::ImageView mPopupArrow;           ///< Popup arrow backing
714
715   Toolkit::TextLabel mValueTextLabel;       //< The text value in popup
716   Toolkit::TextLabel mHandleValueTextLabel; ///< The text value on handle
717   Vector2 mHandleLastTouchPoint;            ///< The last touch point for the handle
718   Timer mValueTimer;                        ///< Timer used to hide value view
719
720   Toolkit::Slider::ValueChangedSignalType mValueChangedSignal;       ///< Signal emitted when the value is changed
721   Toolkit::Slider::ValueChangedSignalType mSlidingFinishedSignal;    ///< Signal emitted when a sliding is finished
722   Toolkit::Slider::MarkReachedSignalType mMarkReachedSignal;         ///< Signal emitted when a mark is reached
723
724   SliderState mState;                 ///< The state of the slider
725
726   PanGestureDetector mPanDetector;    ///< Hit region pan detector
727
728   MarkList mMarks;                    ///< List of discreet marks
729
730   std::string mPopupVisual;           ///< Image for popup image
731   std::string mPopupArrowVisual;      ///< Image for popup arrow image
732   std::string mTrackVisual;           ///< Image for track image
733   std::string mHandleVisual;          ///< Image for handle image
734   std::string mProgressVisual;        ///< Image for progress bar image
735
736   Property::Map mPopupMap;         ///< the Property::Map if the image came from a Property::Map, empty otherwise
737   Property::Map mTrackMap;         ///< the Property::Map if the image came from a Property::Map, empty otherwise
738   Property::Map mHandleMap;        ///< the Property::Map if the image came from a Property::Map, empty otherwise
739   Property::Map mProgressMap;      ///< the Property::Map if the image came from a Property::Map, empty otherwise
740   Property::Map mPopupArrowMap;    ///< the Property::Map if the image came from a Property::Map, empty otherwise
741
742   Vector4 mDisabledColor;    ///< The color to tint the slider when disabled
743
744   Vector2 mHitRegion;     ///< Size of hit region
745   Vector2 mTrackRegion;   ///< Size of track region
746   Vector2 mHandleSize;    ///< Size of the handle
747
748   float mLowerBound = 0.0f;        ///< Lower bound on value
749   float mUpperBound = 1.0f;        ///< Upper bound on value
750   float mValue = 0.0f;             ///< Current value of slider
751
752   float mMarkTolerance = 0.05f;     ///< Tolerance in percentage of slider width for which to snap to marks
753
754   int mValuePrecision;      ///< The precision to use for outputting the value
755
756   bool mShowPopup   : 1,      ///< Show the popup or not
757        mShowValue   : 1,      ///< Whether to display the value number or not on the handle
758        mSnapToMarks : 1;      ///< Turn on or off snapping to marks
759
760 protected:
761   struct AccessibleImpl : public Control::Impl::AccessibleImpl,
762                           public virtual Dali::Accessibility::Value
763   {
764     using Control::Impl::AccessibleImpl::AccessibleImpl;
765     double GetMinimum() override;
766     double GetCurrent() override;
767     double GetMaximum() override;
768     bool SetCurrent( double ) override;
769     double GetMinimumIncrement() override;
770   };
771 };
772
773 } // namespace Internal
774
775 // Helpers for public-api forwarding methods
776
777 inline Toolkit::Internal::Slider& GetImpl( Toolkit::Slider& pub )
778 {
779   DALI_ASSERT_ALWAYS( pub );
780
781   Dali::RefObject& handle = pub.GetImplementation();
782
783   return static_cast< Toolkit::Internal::Slider& >( handle );
784 }
785
786 inline const Toolkit::Internal::Slider& GetImpl( const Toolkit::Slider& pub )
787 {
788   DALI_ASSERT_ALWAYS( pub );
789
790   const Dali::RefObject& handle = pub.GetImplementation();
791
792   return static_cast< const Toolkit::Internal::Slider& >( handle );
793 }
794
795 } // namespace Toolkit
796
797 } // namespace Dali
798
799 #endif // DALI_TOOLKIT_INTERNAL_SLIDER_H