[NUI] Enable TextLabel's BindableProperties to be affected by Layout change
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Slider.cs
1 /*
2  * Copyright(c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 using System;
18 using Tizen.NUI.BaseComponents;
19 using System.ComponentModel;
20 using Tizen.NUI.Binding;
21
22 namespace Tizen.NUI.Components
23 {
24     /// <summary>
25     /// Slider value changed event data.
26     /// </summary>
27     /// <since_tizen> 8 </since_tizen>
28     public class SliderValueChangedEventArgs : EventArgs
29     {
30         /// <summary>
31         /// Current Slider value
32         /// </summary>
33         /// <since_tizen> 8 </since_tizen>
34         public float CurrentValue { get; set; }
35     }
36
37     /// <summary>
38     /// Slider sliding started event data.
39     /// </summary>
40     /// <since_tizen> 8 </since_tizen>
41     public class SliderSlidingStartedEventArgs : EventArgs
42     {
43         /// <summary>
44         /// Current Slider value
45         /// </summary>
46         /// <since_tizen> 8 </since_tizen>
47         public float CurrentValue { get; set; }
48     }
49
50     /// <summary>
51     /// Slider sliding finished event data.
52     /// </summary>
53     /// <since_tizen> 8 </since_tizen>
54     public class SliderSlidingFinishedEventArgs : EventArgs
55     {
56         /// <summary>
57         /// Current Slider value
58         /// </summary>
59         /// <since_tizen> 8 </since_tizen>
60         public float CurrentValue { get; set; }
61     }
62
63     /// <summary>
64     /// A slider lets users select a value from a continuous or discrete range of values by moving the slider thumb.
65     /// </summary>
66     /// <since_tizen> 6 </since_tizen>
67     public partial class Slider : Control
68     {
69         /// <summary>
70         /// IndicatorTypeProperty
71         /// </summary>
72         [EditorBrowsable(EditorBrowsableState.Never)]
73         public static readonly BindableProperty IndicatorTypeProperty = BindableProperty.Create("IndicatorType", typeof(IndicatorType), typeof(Slider), IndicatorType.None, propertyChanged: (bindable, oldValue, newValue) =>
74         {
75             var instance = (Slider)bindable;
76             if (newValue != null)
77             {
78                 instance.privateIndicatorType = (IndicatorType)newValue;
79             }
80         },
81         defaultValueCreator: (bindable) =>
82         {
83             var instance = (Slider)bindable;
84             return instance.privateIndicatorType;
85         });
86
87         /// <summary>
88         /// SpaceBetweenTrackAndIndicatorProperty
89         /// </summary>
90         [EditorBrowsable(EditorBrowsableState.Never)]
91         public static readonly BindableProperty SpaceBetweenTrackAndIndicatorProperty = BindableProperty.Create(nameof(SpaceBetweenTrackAndIndicator), typeof(uint), typeof(Slider), (uint)0, propertyChanged: (bindable, oldValue, newValue) =>
92         {
93             var instance = (Slider)bindable;
94             if (newValue != null)
95             {
96                 instance.privateSpaceBetweenTrackAndIndicator = (uint)newValue;
97             }
98         },
99         defaultValueCreator: (bindable) =>
100         {
101             var instance = (Slider)bindable;
102             return instance.privateSpaceBetweenTrackAndIndicator;
103         });
104
105         /// <summary>
106         /// TrackThicknessProperty
107         /// </summary>
108         [EditorBrowsable(EditorBrowsableState.Never)]
109         public static readonly BindableProperty TrackThicknessProperty = BindableProperty.Create(nameof(TrackThickness), typeof(uint), typeof(Slider), (uint)0, propertyChanged: (bindable, oldValue, newValue) =>
110         {
111             var instance = (Slider)bindable;
112             if (newValue != null)
113             {
114                 instance.privateTrackThickness = (uint)newValue;
115             }
116         },
117         defaultValueCreator: (bindable) =>
118         {
119             var instance = (Slider)bindable;
120             return instance.privateTrackThickness;
121         });
122
123         /// <summary>
124         /// IsValueShownProperty
125         /// </summary>
126         [EditorBrowsable(EditorBrowsableState.Never)]
127         public static readonly BindableProperty IsValueShownProperty = BindableProperty.Create(nameof(IsValueShown), typeof(bool), typeof(Slider), true, propertyChanged: (bindable, oldValue, newValue) =>
128         {
129             var instance = (Slider)bindable;
130             if (newValue != null)
131             {
132                 bool newValueShown = (bool)newValue;
133                 if (instance.isValueShown != newValueShown)
134                 {
135                     instance.isValueShown = newValueShown;
136                 }
137             }
138         },
139         defaultValueCreator: (bindable) =>
140         {
141             var instance = (Slider)bindable;
142             return instance.isValueShown;
143         });
144
145         /// <summary>
146         /// ValueIndicatorTextProperty
147         /// </summary>
148         [EditorBrowsable(EditorBrowsableState.Never)]
149         public static readonly BindableProperty ValueIndicatorTextProperty = BindableProperty.Create(nameof(ValueIndicatorText), typeof(string), typeof(Slider), string.Empty, propertyChanged: (bindable, oldValue, newValue) =>
150         {
151             var instance = (Slider)bindable;
152             if (newValue != null)
153             {
154                 string newText = (string)newValue;
155                 instance.valueIndicatorText.Text = newText;
156             }
157         },
158         defaultValueCreator: (bindable) =>
159         {
160             var instance = (Slider)bindable;
161             return instance.valueIndicatorText.Text;
162         });
163
164         /// <summary>
165         /// Bindable property of CurrentValue
166         /// <remark>
167         /// Hidden API, used for NUI XAML data binding
168         /// </remark>
169         /// </summary>
170         [EditorBrowsable(EditorBrowsableState.Never)]
171         public static readonly BindableProperty CurrentValueProperty = BindableProperty.Create(nameof(CurrentValue), typeof(float), typeof(Slider), 0.0f, BindingMode.TwoWay,
172             propertyChanged: (bindable, oldValue, newValue) =>
173             {
174                 var instance = (Slider)bindable;
175
176                 if (newValue != null)
177                 {
178                     instance.curValue = (float)newValue;
179                     if (instance.IsHighlighted)
180                     {
181                         instance.EmitAccessibilityEvent(ObjectPropertyChangeEvent.Value);
182                     }
183                     instance.UpdateValue();
184                 }
185             },
186             defaultValueCreator: (bindable) =>
187             {
188                 var instance = (Slider)bindable;
189                 return instance.curValue;
190             }
191         );
192
193         static Slider() { }
194
195         /// <summary>
196         /// The constructor of the Slider class.
197         /// </summary>
198         /// <since_tizen> 6 </since_tizen>
199         public Slider()
200         {
201             Initialize();
202         }
203
204         /// <summary>
205         /// The constructor of the Slider class with specific style.
206         /// </summary>
207         /// <param name="style">The string to initialize the Slider</param>
208         /// <since_tizen> 8 </since_tizen>
209         public Slider(string style) : base(style)
210         {
211             Initialize();
212         }
213
214         /// <summary>
215         /// The constructor of the Slider class with specific style.
216         /// </summary>
217         /// <param name="sliderStyle">The style object to initialize the Slider</param>
218         /// <since_tizen> 8 </since_tizen>
219         public Slider(SliderStyle sliderStyle) : base(sliderStyle)
220         {
221             Initialize();
222         }
223
224         /// <summary>
225         /// The value changed event handler.
226         /// </summary>
227         /// <since_tizen> 6 </since_tizen>
228         [Obsolete("Deprecated in API8; Will be removed in API10. Please use ValueChanged event instead.")]
229         public event EventHandler<ValueChangedArgs> ValueChangedEvent
230         {
231             add
232             {
233                 valueChangedHandler += value;
234             }
235             remove
236             {
237                 valueChangedHandler -= value;
238             }
239         }
240
241         /// <summary>
242         /// The sliding finished event handler.
243         /// </summary>
244         /// <since_tizen> 6 </since_tizen>
245         [Obsolete("Deprecated in API8; Will be removed in API10. Please use SlidingFinished event instead.")]
246         public event EventHandler<SlidingFinishedArgs> SlidingFinishedEvent
247         {
248             add
249             {
250                 slidingFinishedHandler += value;
251             }
252             remove
253             {
254                 slidingFinishedHandler -= value;
255             }
256         }
257
258         /// <summary>
259         /// The value changed event handler.
260         /// </summary>
261         /// <since_tizen> 8 </since_tizen>
262         public event EventHandler<SliderValueChangedEventArgs> ValueChanged
263         {
264             add
265             {
266                 sliderValueChangedHandler += value;
267             }
268             remove
269             {
270                 sliderValueChangedHandler -= value;
271             }
272         }
273
274         /// <summary>
275         /// The sliding started event handler.
276         /// </summary>
277         /// <since_tizen> 8 </since_tizen>
278         public event EventHandler<SliderSlidingStartedEventArgs> SlidingStarted
279         {
280             add
281             {
282                 sliderSlidingStartedHandler += value;
283             }
284             remove
285             {
286                 sliderSlidingStartedHandler -= value;
287             }
288         }
289
290         /// <summary>
291         /// The sliding finished event handler.
292         /// </summary>
293         /// <since_tizen> 8 </since_tizen>
294         public event EventHandler<SliderSlidingFinishedEventArgs> SlidingFinished
295         {
296             add
297             {
298                 sliderSlidingFinishedHandler += value;
299             }
300             remove
301             {
302                 sliderSlidingFinishedHandler -= value;
303             }
304         }
305
306         /// <summary>
307         /// The state changed event handler.
308         /// </summary>
309         /// <since_tizen> 6 </since_tizen>
310         [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")]
311         public event EventHandler<StateChangedArgs> StateChangedEvent
312         {
313             add
314             {
315                 stateChangedHandler += value;
316             }
317             remove
318             {
319                 stateChangedHandler -= value;
320             }
321         }
322
323         /// <summary>
324         /// The direction type of slider.
325         /// </summary>
326         /// <since_tizen> 6 </since_tizen>
327         public enum DirectionType
328         {
329             /// <summary>
330             /// The Horizontal type.
331             /// </summary>
332             /// <since_tizen> 6 </since_tizen>
333             Horizontal,
334
335             /// <summary>
336             /// The Vertical type.
337             /// </summary>
338             /// <since_tizen> 6 </since_tizen>
339             Vertical
340         }
341
342         /// <summary>
343         /// The indicator type of slider.
344         /// </summary>
345         /// <since_tizen> 6 </since_tizen>
346         public enum IndicatorType
347         {
348             /// <summary> Only contains slider bar.</summary>
349             /// <since_tizen> 6 </since_tizen>
350             None,
351
352             /// <summary> Contains slider bar, IndicatorImage.</summary>
353             /// <since_tizen> 6 </since_tizen>
354             Image,
355
356             /// <summary> Contains slider bar, IndicatorText.</summary>
357             /// <since_tizen> 6 </since_tizen>
358             Text
359         }
360
361         /// <summary>
362         /// Return currently applied style.
363         /// </summary>
364         /// <remarks>
365         /// Modifying contents in style may cause unexpected behaviour.
366         /// </remarks>
367         /// <since_tizen> 8 </since_tizen>
368         public SliderStyle Style => (SliderStyle)(ViewStyle as SliderStyle)?.Clone();
369
370         /// <summary>
371         /// Gets or sets the direction type of slider.
372         /// </summary>
373         /// <since_tizen> 6 </since_tizen>
374         public DirectionType Direction
375         {
376             get
377             {
378                 return direction;
379             }
380             set
381             {
382                 if (direction == value)
383                 {
384                     return;
385                 }
386                 direction = value;
387                 RelayoutBaseComponent(false);
388                 UpdateBgTrackSize();
389                 UpdateBgTrackPosition();
390                 UpdateWarningTrackSize();
391                 UpdateValue();
392             }
393         }
394
395         /// <summary>
396         /// Gets or sets the indicator type, arrow or sign.
397         /// </summary>
398         /// <since_tizen> 6 </since_tizen>
399         public IndicatorType Indicator
400         {
401             get
402             {
403                 return (IndicatorType)GetValue(IndicatorTypeProperty);
404             }
405             set
406             {
407                 SetValue(IndicatorTypeProperty, value);
408             }
409         }
410
411         /// <summary>
412         /// Gets or sets the minimum value of slider.
413         /// </summary>
414         /// <since_tizen> 6 </since_tizen>
415         public float MinValue
416         {
417             get
418             {
419                 return minValue;
420             }
421             set
422             {
423                 minValue = value;
424                 UpdateValue();
425             }
426         }
427
428         /// <summary>
429         /// Gets or sets the maximum value of slider.
430         /// </summary>
431         /// <since_tizen> 6 </since_tizen>
432         public float MaxValue
433         {
434             get
435             {
436                 return maxValue;
437             }
438             set
439             {
440                 maxValue = value;
441                 UpdateValue();
442             }
443         }
444
445         /// <summary>
446         /// Gets or sets the current value of slider.
447         /// </summary>
448         /// <since_tizen> 6 </since_tizen>
449         public float CurrentValue
450         {
451             get
452             {
453                 return (float)GetValue(CurrentValueProperty);
454             }
455             set
456             {
457                 SetValue(CurrentValueProperty, value);
458             }
459         }
460
461         /// <summary>
462         /// Gets or sets the size of the thumb image object.
463         /// </summary>
464         /// <since_tizen> 6 </since_tizen>
465         public Size ThumbSize
466         {
467             get
468             {
469                 return thumbImage?.Size;
470             }
471             set
472             {
473                 if (null != thumbImage)
474                 {
475                     thumbImage.Size = value;
476                     thumbSize = value;
477                 }
478             }
479         }
480
481         /// <summary>
482         /// Gets or sets the resource url of the thumb image object.
483         ///
484         /// Please use ThumbImageUrl property.
485         /// </summary>
486         /// <since_tizen> 6 </since_tizen>
487         public string ThumbImageURL
488         {
489             get
490             {
491                 return thumbImage?.ResourceUrl;
492             }
493             set
494             {
495                 if (null != thumbImage)
496                 {
497                     thumbImage.ResourceUrl = value;
498                     thumbImageUrl = value;
499                 }
500             }
501         }
502
503         /// <summary>
504         /// Gets or sets the resource url selector of the thumb image object.
505         /// Getter returns copied selector value if exist, null otherwise.
506         ///
507         /// Please use ThumbImageUrl property.
508         /// </summary>
509         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
510         /// <since_tizen> 6 </since_tizen>
511         public StringSelector ThumbImageURLSelector
512         {
513             get => thumbImage == null ? null : new StringSelector((Selector<string>)thumbImage.GetValue(ImageView.ResourceUrlSelectorProperty));
514             set
515             {
516                 if (value == null || thumbImage == null)
517                 {
518                     throw new NullReferenceException("Slider.ThumbImageURLSelector is null");
519                 }
520                 else
521                 {
522                     thumbImage.SetValue(ImageView.ResourceUrlSelectorProperty, value);
523                     thumbImageUrlSelector = value;
524                 }
525             }
526         }
527
528         /// <summary>
529         /// Gets or sets the Url of the thumb image.
530         /// </summary>
531         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
532         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
533         [EditorBrowsable(EditorBrowsableState.Never)]
534         public Selector<string> ThumbImageUrl
535         {
536             get
537             {
538                 if (thumbImage == null)
539                 {
540                     return null;
541                 }
542                 else
543                 {
544                     return (Selector<string>)thumbImage.GetValue(ImageView.ResourceUrlSelectorProperty);
545                 }
546             }
547             set
548             {
549                 if (value == null || thumbImage == null)
550                 {
551                     throw new NullReferenceException("Slider.ThumbImageUrl is null");
552                 }
553                 else
554                 {
555                     thumbImage.SetValue(ImageView.ResourceUrlSelectorProperty, value);
556                     thumbImageUrlSelector = value;
557                 }
558             }
559         }
560
561         /// <summary>
562         /// Gets or sets the color of the thumb image object.
563         /// </summary>
564         /// <since_tizen> 8 </since_tizen>
565         public Color ThumbColor
566         {
567             get
568             {
569                 return thumbImage?.Color;
570             }
571             set
572             {
573                 if (null != thumbImage)
574                 {
575                     thumbImage.BackgroundColor = value;
576                     thumbColor = value;
577                 }
578             }
579         }
580
581         /// <summary>
582         /// Gets or sets the color of the background track image object.
583         /// </summary>
584         /// <since_tizen> 6 </since_tizen>
585         public Color BgTrackColor
586         {
587             get
588             {
589                 return bgTrackImage?.BackgroundColor;
590             }
591             set
592             {
593                 if (null != bgTrackImage)
594                 {
595                     bgTrackImage.BackgroundColor = value;
596                 }
597             }
598         }
599
600         /// <summary>
601         /// Gets or sets the color of the slided track image object.
602         /// </summary>
603         /// <since_tizen> 6 </since_tizen>
604         public Color SlidedTrackColor
605         {
606             get
607             {
608                 return slidedTrackImage?.BackgroundColor;
609             }
610             set
611             {
612                 if (null != slidedTrackImage)
613                 {
614                     slidedTrackImage.BackgroundColor = value;
615                 }
616             }
617         }
618
619         /// <summary>
620         /// Gets or sets the thickness value of the track.
621         /// </summary>
622         /// <since_tizen> 6 </since_tizen>
623         public uint TrackThickness
624         {
625             get
626             {
627                 return (uint)GetValue(TrackThicknessProperty);
628             }
629             set
630             {
631                 SetValue(TrackThicknessProperty, value);
632             }
633         }
634
635         /// <summary>
636         /// Gets or sets the warning start value between minimum value and maximum value of slider.
637         /// </summary>
638         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
639         [EditorBrowsable(EditorBrowsableState.Never)]
640         public float WarningStartValue
641         {
642             get
643             {
644                 return warningStartValue;
645             }
646             set
647             {
648                 warningStartValue = value;
649                 UpdateValue();
650             }
651         }
652
653         /// <summary>
654         /// Gets or sets the color of the warning track image object.
655         /// </summary>
656         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
657         [EditorBrowsable(EditorBrowsableState.Never)]
658         public Color WarningTrackColor
659         {
660             get
661             {
662                 return warningTrackImage?.BackgroundColor;
663             }
664             set
665             {
666                 if (null != warningTrackImage)
667                 {
668                     warningTrackImage.BackgroundColor = value;
669                 }
670             }
671         }
672
673         /// <summary>
674         /// Gets or sets the color of the warning slided track image object.
675         /// </summary>
676         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
677         [EditorBrowsable(EditorBrowsableState.Never)]
678         public Color WarningSlidedTrackColor
679         {
680             get
681             {
682                 return warningSlidedTrackImage?.BackgroundColor;
683             }
684             set
685             {
686                 if (null != warningSlidedTrackImage)
687                 {
688                     warningSlidedTrackImage.BackgroundColor = value;
689                 }
690             }
691         }
692
693         /// <summary>
694         /// Gets or sets the Url of the warning thumb image.
695         /// </summary>
696         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
697         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
698         [EditorBrowsable(EditorBrowsableState.Never)]
699         public Selector<string> WarningThumbImageUrl
700         {
701             get
702             {
703                 return warningThumbImageUrlSelector;
704             }
705             set
706             {
707                 if (value == null || thumbImage == null)
708                 {
709                     throw new NullReferenceException("Slider.WarningThumbImageUrl is null");
710                 }
711                 else
712                 {
713                     warningThumbImageUrlSelector = value;
714                 }
715             }
716         }
717
718         /// <summary>
719         /// Gets or sets the color of the warning thumb image object.
720         /// </summary>
721         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
722         [EditorBrowsable(EditorBrowsableState.Never)]
723         public Color WarningThumbColor
724         {
725             get
726             {
727                 return warningThumbColor;
728             }
729             set
730             {
731                 warningThumbColor = value;
732             }
733         }
734
735         /// <summary>
736         /// Gets or sets the resource url of the low indicator image object.
737         /// </summary>
738         /// <since_tizen> 6 </since_tizen>
739         public string LowIndicatorImageURL
740         {
741             get
742             {
743                 return lowIndicatorImage?.ResourceUrl;
744             }
745             set
746             {
747                 if (null == lowIndicatorImage) lowIndicatorImage = new ImageView();
748                 lowIndicatorImage.ResourceUrl = value;
749             }
750         }
751
752         /// <summary>
753         /// Gets or sets the resource url of the high indicator image object.
754         /// </summary>
755         /// <since_tizen> 6 </since_tizen>
756         public string HighIndicatorImageURL
757         {
758             get
759             {
760                 return highIndicatorImage?.ResourceUrl;
761             }
762             set
763             {
764                 if (null == highIndicatorImage) highIndicatorImage = new ImageView();
765                 highIndicatorImage.ResourceUrl = value;
766             }
767         }
768
769         /// <summary>
770         /// Gets or sets the text content of the low indicator text object.
771         /// </summary>
772         /// <since_tizen> 6 </since_tizen>
773         public string LowIndicatorTextContent
774         {
775             get
776             {
777                 return lowIndicatorText?.Text;
778             }
779             set
780             {
781                 if (null != lowIndicatorText)
782                 {
783                     lowIndicatorText.Text = value;
784                 }
785             }
786         }
787
788         /// <summary>
789         /// Gets or sets the text content of the high indicator text object.
790         /// </summary>
791         /// <since_tizen> 6 </since_tizen>
792         public string HighIndicatorTextContent
793         {
794             get
795             {
796                 return highIndicatorText?.Text;
797             }
798             set
799             {
800                 if (null != highIndicatorText)
801                 {
802                     highIndicatorText.Text = value;
803                 }
804             }
805         }
806
807         /// <summary>
808         /// Gets or sets the size of the low indicator object(image or text).
809         /// </summary>
810         /// <since_tizen> 6 </since_tizen>
811         public Size LowIndicatorSize
812         {
813             get
814             {
815                 return lowIndicatorSize;
816             }
817             set
818             {
819                 lowIndicatorSize = value;
820                 UpdateLowIndicatorSize();
821                 UpdateBgTrackSize();
822                 UpdateBgTrackPosition();
823                 UpdateValue();
824             }
825         }
826
827         /// <summary>
828         /// Gets or sets the size of the high indicator object(image or text).
829         /// </summary>
830         /// <since_tizen> 6 </since_tizen>
831         public Size HighIndicatorSize
832         {
833             get
834             {
835                 return highIndicatorText?.Size;
836             }
837             set
838             {
839                 if (null != highIndicatorText)
840                 {
841                     highIndicatorText.Size = value;
842                 }
843             }
844         }
845
846         /// <summary>
847         /// Gets or sets the value of the space between track and indicator.
848         /// </summary>
849         /// <since_tizen> 6 </since_tizen>
850         public uint SpaceBetweenTrackAndIndicator
851         {
852             get
853             {
854                 return (uint)GetValue(SpaceBetweenTrackAndIndicatorProperty);
855             }
856             set
857             {
858                 SetValue(SpaceBetweenTrackAndIndicatorProperty, value);
859             }
860         }
861
862         /// <summary>
863         /// Flag to decide whether the value indicator is shown
864         /// </summary>
865         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
866         [EditorBrowsable(EditorBrowsableState.Never)]
867         public bool IsValueShown
868         {
869             get
870             {
871                 return (bool)GetValue(IsValueShownProperty);
872             }
873             set
874             {
875                 SetValue(IsValueShownProperty, value);
876             }
877         }
878
879         /// <summary>
880         /// Gets or sets the text of value indicator.
881         /// </summary>
882         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
883         [EditorBrowsable(EditorBrowsableState.Never)]
884         public string ValueIndicatorText
885         {
886             get
887             {
888                 return (string)GetValue(ValueIndicatorTextProperty);
889             }
890             set
891             {
892                 SetValue(ValueIndicatorTextProperty, value);
893             }
894         }
895
896         /// <summary>
897         /// Gets or sets the size of the value indicator image object.
898         /// </summary>
899         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
900         [EditorBrowsable(EditorBrowsableState.Never)]
901         public Size ValueIndicatorSize
902         {
903             get
904             {
905                 return valueIndicatorImage?.Size;
906             }
907             set
908             {
909                 if (null != valueIndicatorImage)
910                 {
911                     valueIndicatorImage.Size = value;
912                 }
913             }
914         }
915
916         /// <summary>
917         /// Gets or sets the resource url of the value indicator image object.
918         /// </summary>
919         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
920         [EditorBrowsable(EditorBrowsableState.Never)]
921         public string ValueIndicatorUrl
922         {
923             get
924             {
925                 return valueIndicatorImage?.ResourceUrl;
926             }
927             set
928             {
929                 if (null != valueIndicatorImage)
930                 {
931                     valueIndicatorImage.ResourceUrl = value;
932                 }
933             }
934         }
935
936         /// <summary>
937         /// Flag to decide whether the thumb snap to the nearest discrete value when the user drags the thumb or taps.
938         ///
939         /// The default value is false.
940         /// </summary>
941         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
942         [EditorBrowsable(EditorBrowsableState.Never)]
943         public bool IsDiscrete { get; set; } = false;
944
945         /// <summary>
946         /// Gets or sets the discrete value of slider.
947         ///
948         /// The discrete value is evenly spaced between MinValue and MaxValue.
949         /// For example, MinValue is 0, MaxValue is 100, and DiscreteValue is 20.
950         /// Then, the thumb can only go to 0, 20, 40, 60, 80, and 100.
951         /// The default is 0.
952         /// </summary>
953         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
954         [EditorBrowsable(EditorBrowsableState.Never)]
955         public float DiscreteValue
956         {
957             get
958             {
959                 return discreteValue;
960             }
961             set
962             {
963                 discreteValue = value;
964                 UpdateValue();
965             }
966         }
967
968         private Extents spaceBetweenTrackAndIndicator
969         {
970             get
971             {
972                 if (null == spaceTrackIndicator)
973                 {
974                     spaceTrackIndicator = new Extents((ushort start, ushort end, ushort top, ushort bottom) =>
975                     {
976                         Extents extents = new Extents(start, end, top, bottom);
977                         spaceTrackIndicator.CopyFrom(extents);
978                     }, 0, 0, 0, 0);
979                 }
980
981                 return spaceTrackIndicator;
982             }
983         }
984
985         private IndicatorType privateIndicatorType
986         {
987             get
988             {
989                 return indicatorType;
990             }
991             set
992             {
993                 if (indicatorType == value)
994                 {
995                     return;
996                 }
997                 indicatorType = value;
998                 RelayoutBaseComponent(false);
999                 UpdateBgTrackSize();
1000                 UpdateBgTrackPosition();
1001                 UpdateValue();
1002             }
1003         }
1004
1005         private uint privateTrackThickness
1006         {
1007             get
1008             {
1009                 return trackThickness ?? 0;
1010             }
1011             set
1012             {
1013                 trackThickness = value;
1014                 if (bgTrackImage != null)
1015                 {
1016                     if (direction == DirectionType.Horizontal)
1017                     {
1018                         bgTrackImage.SizeHeight = (float)trackThickness.Value;
1019                     }
1020                     else if (direction == DirectionType.Vertical)
1021                     {
1022                         bgTrackImage.SizeWidth = (float)trackThickness.Value;
1023                     }
1024                 }
1025                 if (slidedTrackImage != null)
1026                 {
1027                     if (direction == DirectionType.Horizontal)
1028                     {
1029                         slidedTrackImage.SizeHeight = (float)trackThickness.Value;
1030                     }
1031                     else if (direction == DirectionType.Vertical)
1032                     {
1033                         slidedTrackImage.SizeWidth = (float)trackThickness.Value;
1034                     }
1035                 }
1036                 if (warningTrackImage != null)
1037                 {
1038                     if (direction == DirectionType.Horizontal)
1039                     {
1040                         warningTrackImage.SizeHeight = (float)trackThickness.Value;
1041                     }
1042                     else if (direction == DirectionType.Vertical)
1043                     {
1044                         warningTrackImage.SizeWidth = (float)trackThickness.Value;
1045                     }
1046                 }
1047                 if (warningSlidedTrackImage != null)
1048                 {
1049                     if (direction == DirectionType.Horizontal)
1050                     {
1051                         warningSlidedTrackImage.SizeHeight = (float)trackThickness.Value;
1052                     }
1053                     else if (direction == DirectionType.Vertical)
1054                     {
1055                         warningSlidedTrackImage.SizeWidth = (float)trackThickness.Value;
1056                     }
1057                 }
1058             }
1059         }
1060
1061         private uint privateSpaceBetweenTrackAndIndicator
1062         {
1063             get
1064             {
1065                 return privateTrackPadding.Start;
1066             }
1067             set
1068             {
1069                 ushort val = (ushort)value;
1070                 privateTrackPadding = new Extents(val, val, val, val);
1071             }
1072         }
1073
1074         private Extents privateTrackPadding
1075         {
1076             get
1077             {
1078                 return spaceBetweenTrackAndIndicator;
1079             }
1080             set
1081             {
1082                 spaceBetweenTrackAndIndicator.CopyFrom(value);
1083                 UpdateComponentByIndicatorTypeChanged();
1084                 UpdateBgTrackSize();
1085                 UpdateBgTrackPosition();
1086                 UpdateValue();
1087             }
1088         }
1089
1090         /// <summary>
1091         /// Focus gained callback.
1092         /// </summary>
1093         /// <since_tizen> 8 </since_tizen>
1094         public override void OnFocusGained()
1095         {
1096             //State = ControlStates.Focused;
1097             UpdateState(true, isPressed);
1098             base.OnFocusGained();
1099         }
1100
1101         /// <summary>
1102         /// Focus Lost callback.
1103         /// </summary>
1104         /// <since_tizen> 8 </since_tizen>
1105         public override void OnFocusLost()
1106         {
1107             //State = ControlStates.Normal;
1108             UpdateState(false, isPressed);
1109             base.OnFocusLost();
1110         }
1111
1112         /// <summary>
1113         /// Apply style to scrollbar.
1114         /// </summary>
1115         /// <param name="viewStyle">The style to apply.</param>
1116         /// <since_tizen> 8 </since_tizen>
1117         public override void ApplyStyle(ViewStyle viewStyle)
1118         {
1119             base.ApplyStyle(viewStyle);
1120
1121             SliderStyle sliderStyle = viewStyle as SliderStyle;
1122
1123             if (null != sliderStyle?.Progress)
1124             {
1125                 CreateSlidedTrack().ApplyStyle(sliderStyle.Progress);
1126             }
1127
1128             if (null != sliderStyle?.LowIndicator)
1129             {
1130                 CreateLowIndicatorText().ApplyStyle(sliderStyle.LowIndicator);
1131             }
1132
1133             if (null != sliderStyle?.HighIndicator)
1134             {
1135                 CreateHighIndicatorText().ApplyStyle(sliderStyle.HighIndicator);
1136             }
1137
1138             if (null != sliderStyle?.Track)
1139             {
1140                 CreateBackgroundTrack().ApplyStyle(sliderStyle.Track);
1141             }
1142
1143             if (null != sliderStyle?.Thumb)
1144             {
1145                 CreateThumb().ApplyStyle(sliderStyle.Thumb);
1146             }
1147
1148             if (null != sliderStyle?.ValueIndicatorText)
1149             {
1150                 CreateValueIndicatorText().ApplyStyle(sliderStyle.ValueIndicatorText);
1151             }
1152
1153             if (null != sliderStyle?.ValueIndicatorImage)
1154             {
1155                 CreateValueIndicator().ApplyStyle(sliderStyle.ValueIndicatorImage);
1156             }
1157
1158             if (null != sliderStyle?.WarningTrack)
1159             {
1160                 CreateWarningTrack().ApplyStyle(sliderStyle.WarningTrack);
1161             }
1162
1163             if (null != sliderStyle?.WarningProgress)
1164             {
1165                 CreateWarningSlidedTrack().ApplyStyle(sliderStyle.WarningProgress);
1166             }
1167
1168             EnableControlStatePropagation = true;
1169         }
1170
1171         /// <summary>
1172         /// Prevents from showing child widgets in AT-SPI tree.
1173         /// </summary>
1174         [EditorBrowsable(EditorBrowsableState.Never)]
1175         protected override bool AccessibilityShouldReportZeroChildren()
1176         {
1177             return true;
1178         }
1179
1180         /// <summary>
1181         /// Minimum value.
1182         /// </summary>
1183         [EditorBrowsable(EditorBrowsableState.Never)]
1184         protected override double AccessibilityGetMinimum()
1185         {
1186             return (double)MinValue;
1187         }
1188
1189         /// <summary>
1190         /// Current value.
1191         /// </summary>
1192         [EditorBrowsable(EditorBrowsableState.Never)]
1193         protected override double AccessibilityGetCurrent()
1194         {
1195             return (double)CurrentValue;
1196         }
1197
1198         /// <summary>
1199         /// Maximum value.
1200         /// </summary>
1201         [EditorBrowsable(EditorBrowsableState.Never)]
1202         protected override double AccessibilityGetMaximum()
1203         {
1204             return (double)MaxValue;
1205         }
1206
1207         /// <summary>
1208         /// Current value.
1209         /// </summary>
1210         [EditorBrowsable(EditorBrowsableState.Never)]
1211         protected override bool AccessibilitySetCurrent(double value)
1212         {
1213             var f = (float)value;
1214
1215             if (f >= MinValue && f <= MaxValue)
1216             {
1217                 CurrentValue = f;
1218                 if (sliderValueChangedHandler != null)
1219                 {
1220                     sliderValueChangedHandler(this, new SliderValueChangedEventArgs { CurrentValue = f });
1221                 }
1222                 return true;
1223             }
1224
1225             return false;
1226         }
1227
1228         /// <summary>
1229         /// Minimum increment.
1230         /// </summary>
1231         [EditorBrowsable(EditorBrowsableState.Never)]
1232         protected override double AccessibilityGetMinimumIncrement()
1233         {
1234             // FIXME
1235             return (MaxValue - MinValue) / 20.0;
1236         }
1237
1238         /// <summary>
1239         /// Initialize AT-SPI object.
1240         /// </summary>
1241         [EditorBrowsable(EditorBrowsableState.Never)]
1242         public override void OnInitialize()
1243         {
1244             base.OnInitialize();
1245             SetAccessibilityConstructor(Role.Slider, AccessibilityInterface.Value);
1246         }
1247
1248         /// <summary>
1249         /// Get Slider style.
1250         /// </summary>
1251         /// <returns>The default slider style.</returns>
1252         /// <since_tizen> 8 </since_tizen>
1253         protected override ViewStyle CreateViewStyle()
1254         {
1255             return new SliderStyle();
1256         }
1257
1258         /// <summary>
1259         /// Dispose Slider.
1260         /// </summary>
1261         /// <param name="type">Dispose type.</param>
1262         /// <since_tizen> 6 </since_tizen>
1263         protected override void Dispose(DisposeTypes type)
1264         {
1265             if (disposed)
1266             {
1267                 return;
1268             }
1269
1270             if (type == DisposeTypes.Explicit)
1271             {
1272                 if (null != panGestureDetector)
1273                 {
1274                     panGestureDetector.Detach(this);
1275                     panGestureDetector.Detected -= OnPanGestureDetected;
1276                     panGestureDetector.Dispose();
1277                     panGestureDetector = null;
1278                 }
1279
1280                 if (null != thumbImage)
1281                 {
1282                     thumbImage.TouchEvent -= OnTouchEventForThumb;
1283                     Utility.Dispose(thumbImage);
1284                 }
1285                 Utility.Dispose(warningSlidedTrackImage);
1286                 Utility.Dispose(warningTrackImage);
1287                 Utility.Dispose(slidedTrackImage);
1288                 if (null != bgTrackImage)
1289                 {
1290                     bgTrackImage.TouchEvent -= OnTouchEventForBgTrack;
1291                     Utility.Dispose(bgTrackImage);
1292                 }
1293                 Utility.Dispose(lowIndicatorImage);
1294                 Utility.Dispose(highIndicatorImage);
1295                 Utility.Dispose(lowIndicatorText);
1296                 Utility.Dispose(highIndicatorText);
1297                 Utility.Dispose(valueIndicatorImage);
1298                 Utility.Dispose(valueIndicatorText);
1299             }
1300
1301             base.Dispose(type);
1302         }
1303
1304         /// <summary>
1305         /// Update Slider by style.
1306         /// </summary>
1307         /// <since_tizen> 6 </since_tizen>
1308         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
1309         [EditorBrowsable(EditorBrowsableState.Never)]
1310         protected override void OnUpdate()
1311         {
1312             RelayoutBaseComponent();
1313
1314             UpdateComponentByIndicatorTypeChanged();
1315             UpdateBgTrackSize();
1316             UpdateBgTrackPosition();
1317             UpdateWarningTrackSize();
1318             UpdateLowIndicatorSize();
1319             UpdateValue();
1320         }
1321
1322         private void CalculateCurrentValueByGesture(float offset)
1323         {
1324             currentSlidedOffset += offset;
1325
1326             if (currentSlidedOffset <= 0)
1327             {
1328                 this.CurrentValue = minValue;
1329             }
1330             else if (currentSlidedOffset >= BgTrackLength())
1331             {
1332                 this.CurrentValue = maxValue;
1333             }
1334             else
1335             {
1336                 int bgTrackLength = BgTrackLength();
1337                 if (bgTrackLength != 0)
1338                 {
1339                     this.CurrentValue = ((currentSlidedOffset / (float)bgTrackLength) * (float)(maxValue - minValue)) + minValue;
1340                 }
1341             }
1342
1343             if (IsDiscrete)
1344             {
1345                 this.CurrentValue = CalculateDiscreteValue(this.CurrentValue);
1346             }
1347
1348             if (valueChangedHandler != null)
1349             {
1350                 ValueChangedArgs args = new ValueChangedArgs();
1351                 args.CurrentValue = this.CurrentValue;
1352                 valueChangedHandler(this, args);
1353             }
1354
1355             if (sliderValueChangedHandler != null)
1356             {
1357                 SliderValueChangedEventArgs args = new SliderValueChangedEventArgs();
1358                 args.CurrentValue = this.CurrentValue;
1359                 sliderValueChangedHandler(this, args);
1360             }
1361         }
1362
1363         private bool OnTouchEventForBgTrack(object source, TouchEventArgs e)
1364         {
1365             PointStateType state = e.Touch.GetState(0);
1366             if (state == PointStateType.Down)
1367             {
1368                 if (isValueShown)
1369                 {
1370                     valueIndicatorImage.Show();
1371                 }
1372
1373                 Vector2 pos = e.Touch.GetLocalPosition(0);
1374                 CalculateCurrentValueByTouch(pos);
1375                 UpdateValue();
1376                 if (null != slidingFinishedHandler)
1377                 {
1378                     SlidingFinishedArgs args = new SlidingFinishedArgs();
1379                     args.CurrentValue = curValue;
1380                     slidingFinishedHandler(this, args);
1381                 }
1382
1383                 if (null != sliderSlidingFinishedHandler)
1384                 {
1385                     SliderSlidingFinishedEventArgs args = new SliderSlidingFinishedEventArgs();
1386                     args.CurrentValue = curValue;
1387                     sliderSlidingFinishedHandler(this, args);
1388                 }
1389             }
1390             else if (state == PointStateType.Up)
1391             {
1392                 if (isValueShown)
1393                 {
1394                     valueIndicatorImage.Hide();
1395                 }
1396             }
1397             return false;
1398         }
1399
1400         private bool OnTouchEventForThumb(object source, TouchEventArgs e)
1401         {
1402             PointStateType state = e.Touch.GetState(0);
1403             if (state == PointStateType.Down)
1404             {
1405                 UpdateState(isFocused, true);
1406             }
1407             else if (state == PointStateType.Up)
1408             {
1409                 UpdateState(isFocused, false);
1410             }
1411             return true;
1412         }
1413
1414         private void CalculateCurrentValueByTouch(Vector2 pos)
1415         {
1416             int bgTrackLength = BgTrackLength();
1417             if (direction == DirectionType.Horizontal)
1418             {
1419                 currentSlidedOffset = pos.X;
1420             }
1421             else if (direction == DirectionType.Vertical)
1422             {
1423                 currentSlidedOffset = bgTrackLength - pos.Y;
1424             }
1425
1426             if (bgTrackLength != 0)
1427             {
1428                 this.CurrentValue = ((currentSlidedOffset / (float)bgTrackLength) * (maxValue - minValue)) + minValue;
1429
1430                 if (IsDiscrete)
1431                 {
1432                     this.CurrentValue = CalculateDiscreteValue(this.CurrentValue);
1433                 }
1434
1435                 if (null != valueChangedHandler)
1436                 {
1437                     ValueChangedArgs args = new ValueChangedArgs();
1438                     args.CurrentValue = this.CurrentValue;
1439                     valueChangedHandler(this, args);
1440                 }
1441
1442                 if (null != sliderValueChangedHandler)
1443                 {
1444                     SliderValueChangedEventArgs args = new SliderValueChangedEventArgs();
1445                     args.CurrentValue = this.CurrentValue;
1446                     sliderValueChangedHandler(this, args);
1447                 }
1448             }
1449         }
1450
1451         private float CalculateDiscreteValue(float value)
1452         {
1453             return ((float)Math.Round((value / discreteValue)) * discreteValue);
1454         }
1455
1456         private void UpdateState(bool isFocusedNew, bool isPressedNew)
1457         {
1458             if (isFocused == isFocusedNew && isPressed == isPressedNew)
1459             {
1460                 return;
1461             }
1462             if (thumbImage == null || Style == null)
1463             {
1464                 return;
1465             }
1466             isFocused = isFocusedNew;
1467             isPressed = isPressedNew;
1468
1469             if (!isFocused && !isPressed)
1470             {
1471                 ControlState = ControlState.Normal;
1472                 thumbImage.ResourceUrl = thumbImageUrlSelector?.Normal;
1473
1474                 if (stateChangedHandler != null)
1475                 {
1476                     StateChangedArgs args = new StateChangedArgs();
1477                     args.CurrentState = (ControlStates)ControlStates.Normal;
1478                     stateChangedHandler(this, args);
1479                 }
1480             }
1481             else if (isPressed)
1482             {
1483                 ControlState = ControlState.Pressed;
1484                 thumbImage.ResourceUrl = thumbImageUrlSelector?.Pressed;
1485
1486                 if (stateChangedHandler != null)
1487                 {
1488                     StateChangedArgs args = new StateChangedArgs();
1489                     args.CurrentState = (ControlStates)ControlStates.Pressed;
1490                     stateChangedHandler(this, args);
1491                 }
1492             }
1493             else if (!isPressed && isFocused)
1494             {
1495                 ControlState = ControlState.Focused;
1496                 thumbImage.ResourceUrl = thumbImageUrlSelector?.Focused;
1497
1498                 if (stateChangedHandler != null)
1499                 {
1500                     StateChangedArgs args = new StateChangedArgs();
1501                     args.CurrentState = (ControlStates)ControlStates.Focused;
1502                     stateChangedHandler(this, args);
1503                 }
1504             }
1505         }
1506
1507         private void UpdateComponentByIndicatorTypeChanged()
1508         {
1509             IndicatorType type = CurrentIndicatorType();
1510             if (type == IndicatorType.None)
1511             {
1512                 if (lowIndicatorImage != null)
1513                 {
1514                     lowIndicatorImage.Hide();
1515                 }
1516                 if (highIndicatorImage != null)
1517                 {
1518                     highIndicatorImage.Hide();
1519                 }
1520                 if (lowIndicatorText != null)
1521                 {
1522                     lowIndicatorText.Hide();
1523                 }
1524                 if (highIndicatorText != null)
1525                 {
1526                     highIndicatorText.Hide();
1527                 }
1528             }
1529             else if (type == IndicatorType.Image)
1530             {
1531                 if (lowIndicatorImage != null)
1532                 {
1533                     lowIndicatorImage.Show();
1534                 }
1535                 if (highIndicatorImage != null)
1536                 {
1537                     highIndicatorImage.Show();
1538                 }
1539                 if (lowIndicatorText != null)
1540                 {
1541                     lowIndicatorText.Hide();
1542                 }
1543                 if (highIndicatorText != null)
1544                 {
1545                     highIndicatorText.Hide();
1546                 }
1547             }
1548             else if (type == IndicatorType.Text)
1549             {
1550                 if (lowIndicatorText != null)
1551                 {
1552                     lowIndicatorText.Show();
1553                 }
1554                 if (highIndicatorText != null)
1555                 {
1556                     highIndicatorText.Show();
1557                 }
1558                 if (lowIndicatorImage != null)
1559                 {
1560                     lowIndicatorImage.Hide();
1561                 }
1562                 if (highIndicatorImage != null)
1563                 {
1564                     highIndicatorImage.Hide();
1565                 }
1566             }
1567         }
1568
1569         /// <summary>
1570         /// Value Changed event data.
1571         /// </summary>
1572         /// <since_tizen> 6 </since_tizen>
1573         [Obsolete("Deprecated in API8; Will be removed in API10. Please use SliderValueChangedEventArgs instead.")]
1574         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
1575         public class ValueChangedArgs : EventArgs
1576         {
1577             /// <summary>
1578             /// Current value
1579             /// </summary>
1580             /// <since_tizen> 6 </since_tizen>
1581             /// It will be removed in API10
1582             [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
1583             [Obsolete("Deprecated in API8; Will be removed in API10. Please use SliderValueChangedEventArgs.CurrentValue instead.")]
1584             public float CurrentValue;
1585         }
1586
1587         /// <summary>
1588         /// Value Changed event data.
1589         /// </summary>
1590         /// <since_tizen> 6 </since_tizen>
1591         [Obsolete("Deprecated in API8; Will be removed in API10. Please use SliderSlidingFinishedEventArgs instead.")]
1592         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
1593         public class SlidingFinishedArgs : EventArgs
1594         {
1595             /// <summary>
1596             /// Current value
1597             /// </summary>
1598             /// <since_tizen> 6 </since_tizen>
1599             /// It will be removed in API10
1600             [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
1601             [Obsolete("Deprecated in API8; Will be removed in API10. Please use SliderSlidingFinishedEventArgs.CurrentValue instead.")]
1602             public float CurrentValue;
1603         }
1604
1605         /// <summary>
1606         /// State Changed event data.
1607         /// </summary>
1608         /// <since_tizen> 6 </since_tizen>
1609         [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")]
1610         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
1611         public class StateChangedArgs : EventArgs
1612         {
1613             /// <summary>
1614             /// Current state
1615             /// </summary>
1616             /// <since_tizen> 6 </since_tizen>
1617             /// It will be removed in API10
1618             [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
1619             [Obsolete("Deprecated in API8; Will be removed in API10")]
1620             public ControlStates CurrentState;
1621         }
1622     }
1623 }