[NUI] Update some descriptions (#2990)
[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(thumbImage.ResourceUrlSelector);
514             set
515             {
516                 if (value == null || thumbImage == null)
517                 {
518                     throw new NullReferenceException("Slider.ThumbImageURLSelector is null");
519                 }
520                 else
521                 {
522                     thumbImage.ResourceUrlSelector = 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         /// <since_tizen> 9 </since_tizen>
533         public Selector<string> ThumbImageUrl
534         {
535             get
536             {
537                 if (thumbImage == null)
538                 {
539                     return null;
540                 }
541                 else
542                 {
543                     return thumbImage.ResourceUrlSelector;
544                 }
545             }
546             set
547             {
548                 if (value == null || thumbImage == null)
549                 {
550                     throw new NullReferenceException("Slider.ThumbImageUrl is null");
551                 }
552                 else
553                 {
554                     thumbImage.ResourceUrlSelector = value;
555                     thumbImageUrlSelector = value;
556                 }
557             }
558         }
559
560         /// <summary>
561         /// Gets or sets the color of the thumb image object.
562         /// </summary>
563         /// <since_tizen> 8 </since_tizen>
564         public Color ThumbColor
565         {
566             get
567             {
568                 return thumbImage?.Color;
569             }
570             set
571             {
572                 if (null != thumbImage)
573                 {
574                     thumbImage.BackgroundColor = value;
575                     thumbColor = value;
576                 }
577             }
578         }
579
580         /// <summary>
581         /// Gets or sets the color of the background track image object.
582         /// </summary>
583         /// <since_tizen> 6 </since_tizen>
584         public Color BgTrackColor
585         {
586             get
587             {
588                 return bgTrackImage?.BackgroundColor;
589             }
590             set
591             {
592                 if (null != bgTrackImage)
593                 {
594                     bgTrackImage.BackgroundColor = value;
595                 }
596             }
597         }
598
599         /// <summary>
600         /// Gets or sets the color of the slided track image object.
601         /// </summary>
602         /// <since_tizen> 6 </since_tizen>
603         public Color SlidedTrackColor
604         {
605             get
606             {
607                 return slidedTrackImage?.BackgroundColor;
608             }
609             set
610             {
611                 if (null != slidedTrackImage)
612                 {
613                     slidedTrackImage.BackgroundColor = value;
614                 }
615             }
616         }
617
618         /// <summary>
619         /// Gets or sets the thickness value of the track.
620         /// </summary>
621         /// <since_tizen> 6 </since_tizen>
622         public uint TrackThickness
623         {
624             get
625             {
626                 return (uint)GetValue(TrackThicknessProperty);
627             }
628             set
629             {
630                 SetValue(TrackThicknessProperty, value);
631             }
632         }
633
634         /// <summary>
635         /// Gets or sets the warning start value between minimum value and maximum value of slider.
636         /// </summary>
637         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
638         [EditorBrowsable(EditorBrowsableState.Never)]
639         public float WarningStartValue
640         {
641             get
642             {
643                 return warningStartValue;
644             }
645             set
646             {
647                 warningStartValue = value;
648                 UpdateValue();
649             }
650         }
651
652         /// <summary>
653         /// Gets or sets the color of the warning track image object.
654         /// </summary>
655         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
656         [EditorBrowsable(EditorBrowsableState.Never)]
657         public Color WarningTrackColor
658         {
659             get
660             {
661                 return warningTrackImage?.BackgroundColor;
662             }
663             set
664             {
665                 if (null != warningTrackImage)
666                 {
667                     warningTrackImage.BackgroundColor = value;
668                 }
669             }
670         }
671
672         /// <summary>
673         /// Gets or sets the color of the warning slided track image object.
674         /// </summary>
675         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
676         [EditorBrowsable(EditorBrowsableState.Never)]
677         public Color WarningSlidedTrackColor
678         {
679             get
680             {
681                 return warningSlidedTrackImage?.BackgroundColor;
682             }
683             set
684             {
685                 if (null != warningSlidedTrackImage)
686                 {
687                     warningSlidedTrackImage.BackgroundColor = value;
688                 }
689             }
690         }
691
692         /// <summary>
693         /// Gets or sets the Url of the warning thumb image.
694         /// </summary>
695         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
696         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
697         [EditorBrowsable(EditorBrowsableState.Never)]
698         public Selector<string> WarningThumbImageUrl
699         {
700             get
701             {
702                 return warningThumbImageUrlSelector;
703             }
704             set
705             {
706                 if (value == null || thumbImage == null)
707                 {
708                     throw new NullReferenceException("Slider.WarningThumbImageUrl is null");
709                 }
710                 else
711                 {
712                     warningThumbImageUrlSelector = value;
713                 }
714             }
715         }
716
717         /// <summary>
718         /// Gets or sets the color of the warning thumb image object.
719         /// </summary>
720         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
721         [EditorBrowsable(EditorBrowsableState.Never)]
722         public Color WarningThumbColor
723         {
724             get
725             {
726                 return warningThumbColor;
727             }
728             set
729             {
730                 warningThumbColor = value;
731             }
732         }
733
734         /// <summary>
735         /// Gets or sets the resource url of the low indicator image object.
736         /// </summary>
737         /// <since_tizen> 6 </since_tizen>
738         public string LowIndicatorImageURL
739         {
740             get
741             {
742                 return lowIndicatorImage?.ResourceUrl;
743             }
744             set
745             {
746                 if (null == lowIndicatorImage) lowIndicatorImage = new ImageView();
747                 lowIndicatorImage.ResourceUrl = value;
748             }
749         }
750
751         /// <summary>
752         /// Gets or sets the resource url of the high indicator image object.
753         /// </summary>
754         /// <since_tizen> 6 </since_tizen>
755         public string HighIndicatorImageURL
756         {
757             get
758             {
759                 return highIndicatorImage?.ResourceUrl;
760             }
761             set
762             {
763                 if (null == highIndicatorImage) highIndicatorImage = new ImageView();
764                 highIndicatorImage.ResourceUrl = value;
765             }
766         }
767
768         /// <summary>
769         /// Gets or sets the text content of the low indicator text object.
770         /// </summary>
771         /// <since_tizen> 6 </since_tizen>
772         public string LowIndicatorTextContent
773         {
774             get
775             {
776                 return lowIndicatorText?.Text;
777             }
778             set
779             {
780                 if (null != lowIndicatorText)
781                 {
782                     lowIndicatorText.Text = value;
783                 }
784             }
785         }
786
787         /// <summary>
788         /// Gets or sets the text content of the high indicator text object.
789         /// </summary>
790         /// <since_tizen> 6 </since_tizen>
791         public string HighIndicatorTextContent
792         {
793             get
794             {
795                 return highIndicatorText?.Text;
796             }
797             set
798             {
799                 if (null != highIndicatorText)
800                 {
801                     highIndicatorText.Text = value;
802                 }
803             }
804         }
805
806         /// <summary>
807         /// Gets or sets the size of the low indicator object(image or text).
808         /// </summary>
809         /// <since_tizen> 6 </since_tizen>
810         public Size LowIndicatorSize
811         {
812             get
813             {
814                 return lowIndicatorSize;
815             }
816             set
817             {
818                 lowIndicatorSize = value;
819                 UpdateLowIndicatorSize();
820                 UpdateBgTrackSize();
821                 UpdateBgTrackPosition();
822                 UpdateValue();
823             }
824         }
825
826         /// <summary>
827         /// Gets or sets the size of the high indicator object(image or text).
828         /// </summary>
829         /// <since_tizen> 6 </since_tizen>
830         public Size HighIndicatorSize
831         {
832             get
833             {
834                 return highIndicatorText?.Size;
835             }
836             set
837             {
838                 if (null != highIndicatorText)
839                 {
840                     highIndicatorText.Size = value;
841                 }
842             }
843         }
844
845         /// <summary>
846         /// Gets or sets the value of the space between track and indicator.
847         /// </summary>
848         /// <since_tizen> 6 </since_tizen>
849         public uint SpaceBetweenTrackAndIndicator
850         {
851             get
852             {
853                 return (uint)GetValue(SpaceBetweenTrackAndIndicatorProperty);
854             }
855             set
856             {
857                 SetValue(SpaceBetweenTrackAndIndicatorProperty, value);
858             }
859         }
860
861         /// <summary>
862         /// Flag to decide whether the value indicator is shown
863         /// </summary>
864         /// <since_tizen> 9 </since_tizen>
865         public bool IsValueShown
866         {
867             get
868             {
869                 return (bool)GetValue(IsValueShownProperty);
870             }
871             set
872             {
873                 SetValue(IsValueShownProperty, value);
874             }
875         }
876
877         /// <summary>
878         /// Gets or sets the text of value indicator.
879         /// </summary>
880         /// <since_tizen> 9 </since_tizen>
881         public string ValueIndicatorText
882         {
883             get
884             {
885                 return (string)GetValue(ValueIndicatorTextProperty);
886             }
887             set
888             {
889                 SetValue(ValueIndicatorTextProperty, value);
890             }
891         }
892
893         /// <summary>
894         /// Gets or sets the size of the value indicator image object.
895         /// </summary>
896         /// <since_tizen> 9 </since_tizen>
897         public Size ValueIndicatorSize
898         {
899             get
900             {
901                 return valueIndicatorImage?.Size;
902             }
903             set
904             {
905                 if (null != valueIndicatorImage)
906                 {
907                     valueIndicatorImage.Size = value;
908                 }
909             }
910         }
911
912         /// <summary>
913         /// Gets or sets the resource url of the value indicator image object.
914         /// </summary>
915         /// <since_tizen> 9 </since_tizen>
916         public string ValueIndicatorUrl
917         {
918             get
919             {
920                 return valueIndicatorImage?.ResourceUrl;
921             }
922             set
923             {
924                 if (null != valueIndicatorImage)
925                 {
926                     valueIndicatorImage.ResourceUrl = value;
927                 }
928             }
929         }
930
931         /// <summary>
932         /// Flag to decide whether the thumb snap to the nearest discrete value when the user drags the thumb or taps.
933         ///
934         /// The default value is false.
935         /// </summary>
936         /// <since_tizen> 9 </since_tizen>
937         public bool IsDiscrete { get; set; } = false;
938
939         /// <summary>
940         /// Gets or sets the discrete value of slider.
941         /// </summary>
942         /// <remarks>
943         /// The discrete value is evenly spaced between MinValue and MaxValue.
944         /// For example, MinValue is 0, MaxValue is 100, and DiscreteValue is 20.
945         /// Then, the thumb can only go to 0, 20, 40, 60, 80, and 100.
946         /// The default is 0.
947         /// </remarks>
948         /// <since_tizen> 9 </since_tizen>
949         public float DiscreteValue
950         {
951             get
952             {
953                 return discreteValue;
954             }
955             set
956             {
957                 discreteValue = value;
958                 UpdateValue();
959             }
960         }
961
962         private Extents spaceBetweenTrackAndIndicator
963         {
964             get
965             {
966                 if (null == spaceTrackIndicator)
967                 {
968                     spaceTrackIndicator = new Extents((ushort start, ushort end, ushort top, ushort bottom) =>
969                     {
970                         Extents extents = new Extents(start, end, top, bottom);
971                         spaceTrackIndicator.CopyFrom(extents);
972                     }, 0, 0, 0, 0);
973                 }
974
975                 return spaceTrackIndicator;
976             }
977         }
978
979         private IndicatorType privateIndicatorType
980         {
981             get
982             {
983                 return indicatorType;
984             }
985             set
986             {
987                 if (indicatorType == value)
988                 {
989                     return;
990                 }
991                 indicatorType = value;
992                 RelayoutBaseComponent(false);
993                 UpdateBgTrackSize();
994                 UpdateBgTrackPosition();
995                 UpdateValue();
996             }
997         }
998
999         private uint privateTrackThickness
1000         {
1001             get
1002             {
1003                 return trackThickness ?? 0;
1004             }
1005             set
1006             {
1007                 trackThickness = value;
1008                 if (bgTrackImage != null)
1009                 {
1010                     if (direction == DirectionType.Horizontal)
1011                     {
1012                         bgTrackImage.SizeHeight = (float)trackThickness.Value;
1013                     }
1014                     else if (direction == DirectionType.Vertical)
1015                     {
1016                         bgTrackImage.SizeWidth = (float)trackThickness.Value;
1017                     }
1018                 }
1019                 if (slidedTrackImage != null)
1020                 {
1021                     if (direction == DirectionType.Horizontal)
1022                     {
1023                         slidedTrackImage.SizeHeight = (float)trackThickness.Value;
1024                     }
1025                     else if (direction == DirectionType.Vertical)
1026                     {
1027                         slidedTrackImage.SizeWidth = (float)trackThickness.Value;
1028                     }
1029                 }
1030                 if (warningTrackImage != null)
1031                 {
1032                     if (direction == DirectionType.Horizontal)
1033                     {
1034                         warningTrackImage.SizeHeight = (float)trackThickness.Value;
1035                     }
1036                     else if (direction == DirectionType.Vertical)
1037                     {
1038                         warningTrackImage.SizeWidth = (float)trackThickness.Value;
1039                     }
1040                 }
1041                 if (warningSlidedTrackImage != null)
1042                 {
1043                     if (direction == DirectionType.Horizontal)
1044                     {
1045                         warningSlidedTrackImage.SizeHeight = (float)trackThickness.Value;
1046                     }
1047                     else if (direction == DirectionType.Vertical)
1048                     {
1049                         warningSlidedTrackImage.SizeWidth = (float)trackThickness.Value;
1050                     }
1051                 }
1052             }
1053         }
1054
1055         private uint privateSpaceBetweenTrackAndIndicator
1056         {
1057             get
1058             {
1059                 return privateTrackPadding.Start;
1060             }
1061             set
1062             {
1063                 ushort val = (ushort)value;
1064                 privateTrackPadding = new Extents(val, val, val, val);
1065             }
1066         }
1067
1068         private Extents privateTrackPadding
1069         {
1070             get
1071             {
1072                 return spaceBetweenTrackAndIndicator;
1073             }
1074             set
1075             {
1076                 spaceBetweenTrackAndIndicator.CopyFrom(value);
1077                 UpdateComponentByIndicatorTypeChanged();
1078                 UpdateBgTrackSize();
1079                 UpdateBgTrackPosition();
1080                 UpdateValue();
1081             }
1082         }
1083
1084         /// <summary>
1085         /// Focus gained callback.
1086         /// </summary>
1087         /// <since_tizen> 8 </since_tizen>
1088         public override void OnFocusGained()
1089         {
1090             //State = ControlStates.Focused;
1091             UpdateState(true, isPressed);
1092             base.OnFocusGained();
1093         }
1094
1095         /// <summary>
1096         /// Focus Lost callback.
1097         /// </summary>
1098         /// <since_tizen> 8 </since_tizen>
1099         public override void OnFocusLost()
1100         {
1101             //State = ControlStates.Normal;
1102             UpdateState(false, isPressed);
1103             base.OnFocusLost();
1104         }
1105
1106         /// <summary>
1107         /// Apply style to scrollbar.
1108         /// </summary>
1109         /// <param name="viewStyle">The style to apply.</param>
1110         /// <since_tizen> 8 </since_tizen>
1111         public override void ApplyStyle(ViewStyle viewStyle)
1112         {
1113             base.ApplyStyle(viewStyle);
1114
1115             SliderStyle sliderStyle = viewStyle as SliderStyle;
1116
1117             if (null != sliderStyle?.Progress)
1118             {
1119                 CreateSlidedTrack().ApplyStyle(sliderStyle.Progress);
1120             }
1121
1122             if (null != sliderStyle?.LowIndicator)
1123             {
1124                 CreateLowIndicatorText().ApplyStyle(sliderStyle.LowIndicator);
1125             }
1126
1127             if (null != sliderStyle?.HighIndicator)
1128             {
1129                 CreateHighIndicatorText().ApplyStyle(sliderStyle.HighIndicator);
1130             }
1131
1132             if (null != sliderStyle?.Track)
1133             {
1134                 CreateBackgroundTrack().ApplyStyle(sliderStyle.Track);
1135             }
1136
1137             if (null != sliderStyle?.Thumb)
1138             {
1139                 CreateThumb().ApplyStyle(sliderStyle.Thumb);
1140             }
1141
1142             if (null != sliderStyle?.ValueIndicatorText)
1143             {
1144                 CreateValueIndicatorText().ApplyStyle(sliderStyle.ValueIndicatorText);
1145             }
1146
1147             if (null != sliderStyle?.ValueIndicatorImage)
1148             {
1149                 CreateValueIndicator().ApplyStyle(sliderStyle.ValueIndicatorImage);
1150             }
1151
1152             if (null != sliderStyle?.WarningTrack)
1153             {
1154                 CreateWarningTrack().ApplyStyle(sliderStyle.WarningTrack);
1155             }
1156
1157             if (null != sliderStyle?.WarningProgress)
1158             {
1159                 CreateWarningSlidedTrack().ApplyStyle(sliderStyle.WarningProgress);
1160             }
1161
1162             EnableControlStatePropagation = true;
1163         }
1164
1165         /// <summary>
1166         /// Prevents from showing child widgets in AT-SPI tree.
1167         /// </summary>
1168         [EditorBrowsable(EditorBrowsableState.Never)]
1169         protected override bool AccessibilityShouldReportZeroChildren()
1170         {
1171             return true;
1172         }
1173
1174         /// <summary>
1175         /// Minimum value.
1176         /// </summary>
1177         [EditorBrowsable(EditorBrowsableState.Never)]
1178         protected override double AccessibilityGetMinimum()
1179         {
1180             return (double)MinValue;
1181         }
1182
1183         /// <summary>
1184         /// Current value.
1185         /// </summary>
1186         [EditorBrowsable(EditorBrowsableState.Never)]
1187         protected override double AccessibilityGetCurrent()
1188         {
1189             return (double)CurrentValue;
1190         }
1191
1192         /// <summary>
1193         /// Maximum value.
1194         /// </summary>
1195         [EditorBrowsable(EditorBrowsableState.Never)]
1196         protected override double AccessibilityGetMaximum()
1197         {
1198             return (double)MaxValue;
1199         }
1200
1201         /// <summary>
1202         /// Current value.
1203         /// </summary>
1204         [EditorBrowsable(EditorBrowsableState.Never)]
1205         protected override bool AccessibilitySetCurrent(double value)
1206         {
1207             var f = (float)value;
1208
1209             if (f >= MinValue && f <= MaxValue)
1210             {
1211                 CurrentValue = f;
1212                 if (sliderValueChangedHandler != null)
1213                 {
1214                     sliderValueChangedHandler(this, new SliderValueChangedEventArgs { CurrentValue = f });
1215                 }
1216                 return true;
1217             }
1218
1219             return false;
1220         }
1221
1222         /// <summary>
1223         /// Minimum increment.
1224         /// </summary>
1225         [EditorBrowsable(EditorBrowsableState.Never)]
1226         protected override double AccessibilityGetMinimumIncrement()
1227         {
1228             // FIXME
1229             return (MaxValue - MinValue) / 20.0;
1230         }
1231
1232         /// <summary>
1233         /// Initialize AT-SPI object.
1234         /// </summary>
1235         [EditorBrowsable(EditorBrowsableState.Never)]
1236         public override void OnInitialize()
1237         {
1238             base.OnInitialize();
1239             SetAccessibilityConstructor(Role.Slider, AccessibilityInterface.Value);
1240         }
1241
1242         /// <summary>
1243         /// Get Slider style.
1244         /// </summary>
1245         /// <returns>The default slider style.</returns>
1246         /// <since_tizen> 8 </since_tizen>
1247         protected override ViewStyle CreateViewStyle()
1248         {
1249             return new SliderStyle();
1250         }
1251
1252         /// <summary>
1253         /// Dispose Slider.
1254         /// </summary>
1255         /// <param name="type">Dispose type.</param>
1256         /// <since_tizen> 6 </since_tizen>
1257         protected override void Dispose(DisposeTypes type)
1258         {
1259             if (disposed)
1260             {
1261                 return;
1262             }
1263
1264             if (type == DisposeTypes.Explicit)
1265             {
1266                 if (null != panGestureDetector)
1267                 {
1268                     panGestureDetector.Detach(this);
1269                     panGestureDetector.Detected -= OnPanGestureDetected;
1270                     panGestureDetector.Dispose();
1271                     panGestureDetector = null;
1272                 }
1273
1274                 if (null != thumbImage)
1275                 {
1276                     thumbImage.TouchEvent -= OnTouchEventForThumb;
1277                     Utility.Dispose(thumbImage);
1278                 }
1279                 Utility.Dispose(warningSlidedTrackImage);
1280                 Utility.Dispose(warningTrackImage);
1281                 Utility.Dispose(slidedTrackImage);
1282                 if (null != bgTrackImage)
1283                 {
1284                     bgTrackImage.TouchEvent -= OnTouchEventForBgTrack;
1285                     Utility.Dispose(bgTrackImage);
1286                 }
1287                 Utility.Dispose(lowIndicatorImage);
1288                 Utility.Dispose(highIndicatorImage);
1289                 Utility.Dispose(lowIndicatorText);
1290                 Utility.Dispose(highIndicatorText);
1291                 Utility.Dispose(valueIndicatorImage);
1292                 Utility.Dispose(valueIndicatorText);
1293             }
1294
1295             base.Dispose(type);
1296         }
1297
1298         /// <summary>
1299         /// Update Slider by style.
1300         /// </summary>
1301         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
1302         [EditorBrowsable(EditorBrowsableState.Never)]
1303         protected override void OnUpdate()
1304         {
1305             RelayoutBaseComponent();
1306
1307             UpdateComponentByIndicatorTypeChanged();
1308             UpdateBgTrackSize();
1309             UpdateBgTrackPosition();
1310             UpdateWarningTrackSize();
1311             UpdateLowIndicatorSize();
1312             UpdateValue();
1313         }
1314
1315         private void CalculateCurrentValueByGesture(float offset)
1316         {
1317             currentSlidedOffset += offset;
1318
1319             if (currentSlidedOffset <= 0)
1320             {
1321                 this.CurrentValue = minValue;
1322             }
1323             else if (currentSlidedOffset >= BgTrackLength())
1324             {
1325                 this.CurrentValue = maxValue;
1326             }
1327             else
1328             {
1329                 int bgTrackLength = BgTrackLength();
1330                 if (bgTrackLength != 0)
1331                 {
1332                     this.CurrentValue = ((currentSlidedOffset / (float)bgTrackLength) * (float)(maxValue - minValue)) + minValue;
1333                 }
1334             }
1335
1336             if (IsDiscrete)
1337             {
1338                 this.CurrentValue = CalculateDiscreteValue(this.CurrentValue);
1339             }
1340
1341             if (valueChangedHandler != null)
1342             {
1343                 ValueChangedArgs args = new ValueChangedArgs();
1344                 args.CurrentValue = this.CurrentValue;
1345                 valueChangedHandler(this, args);
1346             }
1347
1348             if (sliderValueChangedHandler != null)
1349             {
1350                 SliderValueChangedEventArgs args = new SliderValueChangedEventArgs();
1351                 args.CurrentValue = this.CurrentValue;
1352                 sliderValueChangedHandler(this, args);
1353             }
1354         }
1355
1356         private bool OnTouchEventForBgTrack(object source, TouchEventArgs e)
1357         {
1358             PointStateType state = e.Touch.GetState(0);
1359             if (state == PointStateType.Down)
1360             {
1361                 if (isValueShown)
1362                 {
1363                     valueIndicatorImage.Show();
1364                 }
1365
1366                 Vector2 pos = e.Touch.GetLocalPosition(0);
1367                 CalculateCurrentValueByTouch(pos);
1368                 UpdateValue();
1369                 if (null != slidingFinishedHandler)
1370                 {
1371                     SlidingFinishedArgs args = new SlidingFinishedArgs();
1372                     args.CurrentValue = curValue;
1373                     slidingFinishedHandler(this, args);
1374                 }
1375
1376                 if (null != sliderSlidingFinishedHandler)
1377                 {
1378                     SliderSlidingFinishedEventArgs args = new SliderSlidingFinishedEventArgs();
1379                     args.CurrentValue = curValue;
1380                     sliderSlidingFinishedHandler(this, args);
1381                 }
1382             }
1383             else if (state == PointStateType.Up)
1384             {
1385                 if (isValueShown)
1386                 {
1387                     valueIndicatorImage.Hide();
1388                 }
1389             }
1390             return false;
1391         }
1392
1393         private bool OnTouchEventForThumb(object source, TouchEventArgs e)
1394         {
1395             PointStateType state = e.Touch.GetState(0);
1396             if (state == PointStateType.Down)
1397             {
1398                 UpdateState(isFocused, true);
1399             }
1400             else if (state == PointStateType.Up)
1401             {
1402                 UpdateState(isFocused, false);
1403             }
1404             return true;
1405         }
1406
1407         private void CalculateCurrentValueByTouch(Vector2 pos)
1408         {
1409             int bgTrackLength = BgTrackLength();
1410             if (direction == DirectionType.Horizontal)
1411             {
1412                 currentSlidedOffset = pos.X;
1413             }
1414             else if (direction == DirectionType.Vertical)
1415             {
1416                 currentSlidedOffset = bgTrackLength - pos.Y;
1417             }
1418
1419             if (bgTrackLength != 0)
1420             {
1421                 this.CurrentValue = ((currentSlidedOffset / (float)bgTrackLength) * (maxValue - minValue)) + minValue;
1422
1423                 if (IsDiscrete)
1424                 {
1425                     this.CurrentValue = CalculateDiscreteValue(this.CurrentValue);
1426                 }
1427
1428                 if (null != valueChangedHandler)
1429                 {
1430                     ValueChangedArgs args = new ValueChangedArgs();
1431                     args.CurrentValue = this.CurrentValue;
1432                     valueChangedHandler(this, args);
1433                 }
1434
1435                 if (null != sliderValueChangedHandler)
1436                 {
1437                     SliderValueChangedEventArgs args = new SliderValueChangedEventArgs();
1438                     args.CurrentValue = this.CurrentValue;
1439                     sliderValueChangedHandler(this, args);
1440                 }
1441             }
1442         }
1443
1444         private float CalculateDiscreteValue(float value)
1445         {
1446             return ((float)Math.Round((value / discreteValue)) * discreteValue);
1447         }
1448
1449         private void UpdateState(bool isFocusedNew, bool isPressedNew)
1450         {
1451             if (isFocused == isFocusedNew && isPressed == isPressedNew)
1452             {
1453                 return;
1454             }
1455             if (thumbImage == null || Style == null)
1456             {
1457                 return;
1458             }
1459             isFocused = isFocusedNew;
1460             isPressed = isPressedNew;
1461
1462             if (!isFocused && !isPressed)
1463             {
1464                 ControlState = ControlState.Normal;
1465                 thumbImage.ResourceUrl = thumbImageUrlSelector?.Normal;
1466
1467                 if (stateChangedHandler != null)
1468                 {
1469                     StateChangedArgs args = new StateChangedArgs();
1470                     args.CurrentState = (ControlStates)ControlStates.Normal;
1471                     stateChangedHandler(this, args);
1472                 }
1473             }
1474             else if (isPressed)
1475             {
1476                 ControlState = ControlState.Pressed;
1477                 thumbImage.ResourceUrl = thumbImageUrlSelector?.Pressed;
1478
1479                 if (stateChangedHandler != null)
1480                 {
1481                     StateChangedArgs args = new StateChangedArgs();
1482                     args.CurrentState = (ControlStates)ControlStates.Pressed;
1483                     stateChangedHandler(this, args);
1484                 }
1485             }
1486             else if (!isPressed && isFocused)
1487             {
1488                 ControlState = ControlState.Focused;
1489                 thumbImage.ResourceUrl = thumbImageUrlSelector?.Focused;
1490
1491                 if (stateChangedHandler != null)
1492                 {
1493                     StateChangedArgs args = new StateChangedArgs();
1494                     args.CurrentState = (ControlStates)ControlStates.Focused;
1495                     stateChangedHandler(this, args);
1496                 }
1497             }
1498         }
1499
1500         private void UpdateComponentByIndicatorTypeChanged()
1501         {
1502             IndicatorType type = CurrentIndicatorType();
1503             if (type == IndicatorType.None)
1504             {
1505                 if (lowIndicatorImage != null)
1506                 {
1507                     lowIndicatorImage.Hide();
1508                 }
1509                 if (highIndicatorImage != null)
1510                 {
1511                     highIndicatorImage.Hide();
1512                 }
1513                 if (lowIndicatorText != null)
1514                 {
1515                     lowIndicatorText.Hide();
1516                 }
1517                 if (highIndicatorText != null)
1518                 {
1519                     highIndicatorText.Hide();
1520                 }
1521             }
1522             else if (type == IndicatorType.Image)
1523             {
1524                 if (lowIndicatorImage != null)
1525                 {
1526                     lowIndicatorImage.Show();
1527                 }
1528                 if (highIndicatorImage != null)
1529                 {
1530                     highIndicatorImage.Show();
1531                 }
1532                 if (lowIndicatorText != null)
1533                 {
1534                     lowIndicatorText.Hide();
1535                 }
1536                 if (highIndicatorText != null)
1537                 {
1538                     highIndicatorText.Hide();
1539                 }
1540             }
1541             else if (type == IndicatorType.Text)
1542             {
1543                 if (lowIndicatorText != null)
1544                 {
1545                     lowIndicatorText.Show();
1546                 }
1547                 if (highIndicatorText != null)
1548                 {
1549                     highIndicatorText.Show();
1550                 }
1551                 if (lowIndicatorImage != null)
1552                 {
1553                     lowIndicatorImage.Hide();
1554                 }
1555                 if (highIndicatorImage != null)
1556                 {
1557                     highIndicatorImage.Hide();
1558                 }
1559             }
1560         }
1561
1562         /// <summary>
1563         /// Value Changed event data.
1564         /// </summary>
1565         /// <since_tizen> 6 </since_tizen>
1566         [Obsolete("Deprecated in API8; Will be removed in API10. Please use SliderValueChangedEventArgs instead.")]
1567         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
1568         public class ValueChangedArgs : EventArgs
1569         {
1570             /// <summary>
1571             /// Current value
1572             /// </summary>
1573             /// <since_tizen> 6 </since_tizen>
1574             /// It will be removed in API10
1575             [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
1576             [Obsolete("Deprecated in API8; Will be removed in API10. Please use SliderValueChangedEventArgs.CurrentValue instead.")]
1577             public float CurrentValue;
1578         }
1579
1580         /// <summary>
1581         /// Value Changed event data.
1582         /// </summary>
1583         /// <since_tizen> 6 </since_tizen>
1584         [Obsolete("Deprecated in API8; Will be removed in API10. Please use SliderSlidingFinishedEventArgs instead.")]
1585         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
1586         public class SlidingFinishedArgs : EventArgs
1587         {
1588             /// <summary>
1589             /// Current value
1590             /// </summary>
1591             /// <since_tizen> 6 </since_tizen>
1592             /// It will be removed in API10
1593             [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
1594             [Obsolete("Deprecated in API8; Will be removed in API10. Please use SliderSlidingFinishedEventArgs.CurrentValue instead.")]
1595             public float CurrentValue;
1596         }
1597
1598         /// <summary>
1599         /// State Changed event data.
1600         /// </summary>
1601         /// <since_tizen> 6 </since_tizen>
1602         [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")]
1603         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
1604         public class StateChangedArgs : EventArgs
1605         {
1606             /// <summary>
1607             /// Current state
1608             /// </summary>
1609             /// <since_tizen> 6 </since_tizen>
1610             /// It will be removed in API10
1611             [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
1612             [Obsolete("Deprecated in API8; Will be removed in API10")]
1613             public ControlStates CurrentState;
1614         }
1615     }
1616 }