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