[NUI] Fix some SVACE issues.
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Slider.cs
1 /*
2  * Copyright(c) 2022 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
18 using System;
19 using System.ComponentModel;
20 using Tizen.NUI.Accessibility;
21 using Tizen.NUI.BaseComponents;
22 using Tizen.NUI.Binding;
23
24 namespace Tizen.NUI.Components
25 {
26     /// <summary>
27     /// Slider value changed event data.
28     /// </summary>
29     /// <since_tizen> 8 </since_tizen>
30     public class SliderValueChangedEventArgs : EventArgs
31     {
32         /// <summary>
33         /// Current Slider value
34         /// </summary>
35         /// <since_tizen> 8 </since_tizen>
36         public float CurrentValue { get; set; }
37     }
38
39     /// <summary>
40     /// Slider sliding started event data.
41     /// </summary>
42     /// <since_tizen> 8 </since_tizen>
43     public class SliderSlidingStartedEventArgs : EventArgs
44     {
45         /// <summary>
46         /// Current Slider value
47         /// </summary>
48         /// <since_tizen> 8 </since_tizen>
49         public float CurrentValue { get; set; }
50     }
51
52     /// <summary>
53     /// Slider sliding finished event data.
54     /// </summary>
55     /// <since_tizen> 8 </since_tizen>
56     public class SliderSlidingFinishedEventArgs : EventArgs
57     {
58         /// <summary>
59         /// Current Slider value
60         /// </summary>
61         /// <since_tizen> 8 </since_tizen>
62         public float CurrentValue { get; set; }
63     }
64
65     /// <summary>
66     /// A slider lets users select a value from a continuous or discrete range of values by moving the slider thumb.
67     /// </summary>
68     /// <since_tizen> 6 </since_tizen>
69     public partial class Slider : Control, IAtspiValue
70     {
71         /// <summary>
72         /// SpaceBetweenTrackAndIndicatorProperty
73         /// </summary>
74         [EditorBrowsable(EditorBrowsableState.Never)]
75         public static readonly BindableProperty IndicatorProperty = BindableProperty.Create(nameof(Indicator), typeof(IndicatorType), typeof(Slider), IndicatorType.None, propertyChanged: (bindable, oldValue, newValue) =>
76         {
77             var instance = (Slider)bindable;
78             if (newValue != null)
79             {
80                 instance.privateIndicatorType = (IndicatorType)newValue;
81             }
82         },
83         defaultValueCreator: (bindable) =>
84         {
85             var instance = (Slider)bindable;
86             return instance.privateIndicatorType;
87         });
88
89         /// <summary>
90         /// SpaceBetweenTrackAndIndicatorProperty
91         /// </summary>
92         [EditorBrowsable(EditorBrowsableState.Never)]
93         public static readonly BindableProperty SpaceBetweenTrackAndIndicatorProperty = BindableProperty.Create(nameof(SpaceBetweenTrackAndIndicator), typeof(uint), typeof(Slider), (uint)0, propertyChanged: (bindable, oldValue, newValue) =>
94         {
95             var instance = (Slider)bindable;
96             if (newValue != null)
97             {
98                 instance.privateSpaceBetweenTrackAndIndicator = (uint)newValue;
99             }
100         },
101         defaultValueCreator: (bindable) =>
102         {
103             var instance = (Slider)bindable;
104             return instance.privateSpaceBetweenTrackAndIndicator;
105         });
106
107         /// <summary>
108         /// TrackThicknessProperty
109         /// </summary>
110         [EditorBrowsable(EditorBrowsableState.Never)]
111         public static readonly BindableProperty TrackThicknessProperty = BindableProperty.Create(nameof(TrackThickness), typeof(uint), typeof(Slider), (uint)0, propertyChanged: (bindable, oldValue, newValue) =>
112         {
113             var instance = (Slider)bindable;
114             if (newValue != null)
115             {
116                 instance.privateTrackThickness = (uint)newValue;
117             }
118         },
119         defaultValueCreator: (bindable) =>
120         {
121             var instance = (Slider)bindable;
122             return instance.privateTrackThickness;
123         });
124
125         /// <summary>
126         /// IsValueShownProperty
127         /// </summary>
128         [EditorBrowsable(EditorBrowsableState.Never)]
129         public static readonly BindableProperty IsValueShownProperty = BindableProperty.Create(nameof(IsValueShown), typeof(bool), typeof(Slider), true, propertyChanged: (bindable, oldValue, newValue) =>
130         {
131             var instance = (Slider)bindable;
132             if (newValue != null)
133             {
134                 bool newValueShown = (bool)newValue;
135                 if (instance.isValueShown != newValueShown)
136                 {
137                     instance.isValueShown = newValueShown;
138                 }
139             }
140         },
141         defaultValueCreator: (bindable) =>
142         {
143             var instance = (Slider)bindable;
144             return instance.isValueShown;
145         });
146
147         /// <summary>
148         /// ValueIndicatorTextProperty
149         /// </summary>
150         [EditorBrowsable(EditorBrowsableState.Never)]
151         public static readonly BindableProperty ValueIndicatorTextProperty = BindableProperty.Create(nameof(ValueIndicatorText), typeof(string), typeof(Slider), string.Empty, propertyChanged: (bindable, oldValue, newValue) =>
152         {
153             var instance = (Slider)bindable;
154             if (newValue != null)
155             {
156                 string newText = (string)newValue;
157                 instance.valueIndicatorText.Text = newText;
158             }
159         },
160         defaultValueCreator: (bindable) =>
161         {
162             var instance = (Slider)bindable;
163             return instance.valueIndicatorText.Text;
164         });
165
166         /// <summary>
167         /// Bindable property of CurrentValue
168         /// <remark>
169         /// Hidden API, used for NUI XAML data binding
170         /// </remark>
171         /// </summary>
172         [EditorBrowsable(EditorBrowsableState.Never)]
173         public static readonly BindableProperty CurrentValueProperty = BindableProperty.Create(nameof(CurrentValue), typeof(float), typeof(Slider), 0.0f, BindingMode.TwoWay,
174             propertyChanged: (bindable, oldValue, newValue) =>
175             {
176                 var instance = (Slider)bindable;
177
178                 if (newValue != null)
179                 {
180                     float value = (float)newValue;
181                     if (value < instance.minValue)
182                     {
183                         instance.curValue = instance.minValue;
184                     }
185                     else if (value > instance.maxValue)
186                     {
187                         instance.curValue = instance.maxValue;
188                     }
189                     else
190                     {
191                         instance.curValue = value;
192                     }
193
194                     instance.sliderValueChangedHandler?.Invoke(instance, new SliderValueChangedEventArgs
195                     {
196                         CurrentValue = instance.curValue
197                     });
198                     if (Accessibility.Accessibility.IsEnabled && instance.IsHighlighted)
199                     {
200                         instance.EmitAccessibilityEvent(AccessibilityPropertyChangeEvent.Value);
201                     }
202                     instance.UpdateValue();
203                 }
204             },
205             defaultValueCreator: (bindable) =>
206             {
207                 var instance = (Slider)bindable;
208                 return instance.curValue;
209             }
210         );
211
212         static Slider() { }
213
214         /// <summary>
215         /// The constructor of the Slider class.
216         /// </summary>
217         /// <since_tizen> 6 </since_tizen>
218         public Slider()
219         {
220             Focusable = true;
221             Initialize();
222         }
223
224         /// <summary>
225         /// The constructor of the Slider class with specific style.
226         /// </summary>
227         /// <param name="style">The string to initialize the Slider</param>
228         /// <since_tizen> 8 </since_tizen>
229         public Slider(string style) : base(style)
230         {
231             Focusable = true;
232             Initialize();
233         }
234
235         /// <summary>
236         /// The constructor of the Slider class with specific style.
237         /// </summary>
238         /// <param name="sliderStyle">The style object to initialize the Slider</param>
239         /// <since_tizen> 8 </since_tizen>
240         public Slider(SliderStyle sliderStyle) : base(sliderStyle)
241         {
242             Focusable = true;
243             Initialize();
244         }
245
246         /// <summary>
247         /// The value changed event handler.
248         /// </summary>
249         /// <since_tizen> 8 </since_tizen>
250         public event EventHandler<SliderValueChangedEventArgs> ValueChanged
251         {
252             add
253             {
254                 sliderValueChangedHandler += value;
255             }
256             remove
257             {
258                 sliderValueChangedHandler -= value;
259             }
260         }
261
262         /// <summary>
263         /// The sliding started event handler.
264         /// </summary>
265         /// <since_tizen> 8 </since_tizen>
266         public event EventHandler<SliderSlidingStartedEventArgs> SlidingStarted
267         {
268             add
269             {
270                 sliderSlidingStartedHandler += value;
271             }
272             remove
273             {
274                 sliderSlidingStartedHandler -= value;
275             }
276         }
277
278         /// <summary>
279         /// The sliding finished event handler.
280         /// </summary>
281         /// <since_tizen> 8 </since_tizen>
282         public event EventHandler<SliderSlidingFinishedEventArgs> SlidingFinished
283         {
284             add
285             {
286                 sliderSlidingFinishedHandler += value;
287             }
288             remove
289             {
290                 sliderSlidingFinishedHandler -= value;
291             }
292         }
293
294         /// <summary>
295         /// The direction type of slider.
296         /// </summary>
297         /// <since_tizen> 6 </since_tizen>
298         public enum DirectionType
299         {
300             /// <summary>
301             /// The Horizontal type.
302             /// </summary>
303             /// <since_tizen> 6 </since_tizen>
304             Horizontal,
305
306             /// <summary>
307             /// The Vertical type.
308             /// </summary>
309             /// <since_tizen> 6 </since_tizen>
310             Vertical
311         }
312
313         /// <summary>
314         /// The indicator type of slider.
315         /// </summary>
316         /// <since_tizen> 6 </since_tizen>
317         public enum IndicatorType
318         {
319             /// <summary> Only contains slider bar.</summary>
320             /// <since_tizen> 6 </since_tizen>
321             None,
322
323             /// <summary> Contains slider bar, IndicatorImage.</summary>
324             /// <since_tizen> 6 </since_tizen>
325             Image,
326
327             /// <summary> Contains slider bar, IndicatorText.</summary>
328             /// <since_tizen> 6 </since_tizen>
329             Text
330         }
331
332         /// <summary>
333         /// Return currently applied style.
334         /// </summary>
335         /// <remarks>
336         /// Modifying contents in style may cause unexpected behaviour.
337         /// </remarks>
338         /// <since_tizen> 8 </since_tizen>
339         public SliderStyle Style => (SliderStyle)(ViewStyle as SliderStyle)?.Clone();
340
341         /// <summary>
342         /// Gets or sets the direction type of slider.
343         /// </summary>
344         /// <since_tizen> 6 </since_tizen>
345         public DirectionType Direction
346         {
347             get
348             {
349                 return (DirectionType)GetValue(DirectionProperty);
350             }
351             set
352             {
353                 SetValue(DirectionProperty, value);
354                 NotifyPropertyChanged();
355             }
356         }
357         private DirectionType InternalDirection
358         {
359             get
360             {
361                 return direction;
362             }
363             set
364             {
365                 if (direction == value)
366                 {
367                     return;
368                 }
369                 direction = value;
370                 RelayoutBaseComponent(false);
371                 UpdateBgTrackSize();
372                 UpdateBgTrackPosition();
373                 UpdateWarningTrackSize();
374                 UpdateValue();
375             }
376         }
377
378         /// <summary>
379         /// Gets or sets the indicator type, arrow or sign.
380         /// </summary>
381         /// <since_tizen> 6 </since_tizen>
382         public IndicatorType Indicator
383         {
384             get
385             {
386                 return (IndicatorType)GetValue(IndicatorProperty);
387             }
388             set
389             {
390                 SetValue(IndicatorProperty, value);
391             }
392         }
393
394         /// <summary>
395         /// Gets or sets the minimum value of slider.
396         /// </summary>
397         /// <since_tizen> 6 </since_tizen>
398         public float MinValue
399         {
400             get
401             {
402                 return (float)GetValue(MinValueProperty);
403             }
404             set
405             {
406                 SetValue(MinValueProperty, value);
407                 NotifyPropertyChanged();
408             }
409         }
410         private float InternalMinValue
411         {
412             get
413             {
414                 return minValue;
415             }
416             set
417             {
418                 minValue = value;
419                 UpdateValue();
420             }
421         }
422
423         /// <summary>
424         /// Gets or sets the maximum value of slider.
425         /// </summary>
426         /// <since_tizen> 6 </since_tizen>
427         public float MaxValue
428         {
429             get
430             {
431                 return (float)GetValue(MaxValueProperty);
432             }
433             set
434             {
435                 SetValue(MaxValueProperty, value);
436                 NotifyPropertyChanged();
437             }
438         }
439         private float InternalMaxValue
440         {
441             get
442             {
443                 return maxValue;
444             }
445             set
446             {
447                 maxValue = value;
448                 UpdateValue();
449             }
450         }
451
452         /// <summary>
453         /// Gets or sets the current value of slider.
454         /// </summary>
455         /// <since_tizen> 6 </since_tizen>
456         public float CurrentValue
457         {
458             get
459             {
460                 return (float)GetValue(CurrentValueProperty);
461             }
462             set
463             {
464                 SetValue(CurrentValueProperty, value);
465             }
466         }
467
468         /// <summary>
469         /// Gets or sets the size of the thumb image object.
470         /// </summary>
471         /// <since_tizen> 6 </since_tizen>
472         public Size ThumbSize
473         {
474             get
475             {
476                 return GetValue(ThumbSizeProperty) as Size;
477             }
478             set
479             {
480                 SetValue(ThumbSizeProperty, value);
481                 NotifyPropertyChanged();
482             }
483         }
484         private Size InternalThumbSize
485         {
486             get
487             {
488                 return thumbImage?.Size;
489             }
490             set
491             {
492                 if (null != thumbImage)
493                 {
494                     thumbImage.Size = value;
495                     thumbSize = value;
496                 }
497             }
498         }
499
500         /// <summary>
501         /// Gets or sets the resource url of the thumb image object.
502         ///
503         /// Please use ThumbImageUrl property.
504         /// </summary>
505         /// <since_tizen> 6 </since_tizen>
506         public string ThumbImageURL
507         {
508             get
509             {
510                 return GetValue(ThumbImageURLProperty) as string;
511             }
512             set
513             {
514                 SetValue(ThumbImageURLProperty, value);
515                 NotifyPropertyChanged();
516             }
517         }
518         private string InternalThumbImageURL
519         {
520             get
521             {
522                 return thumbImage?.ResourceUrl;
523             }
524             set
525             {
526                 if (null != thumbImage)
527                 {
528                     thumbImage.ResourceUrl = value;
529                     thumbImageUrl = value;
530                 }
531             }
532         }
533
534         /// <summary>
535         /// Gets or sets the resource url selector of the thumb image object.
536         /// Getter returns copied selector value if exist, null otherwise.
537         ///
538         /// Please use ThumbImageUrl property.
539         /// </summary>
540         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
541         /// <since_tizen> 6 </since_tizen>
542         public StringSelector ThumbImageURLSelector
543         {
544             get
545             {
546                 return GetValue(ThumbImageURLSelectorProperty) as StringSelector;
547             }
548             set
549             {
550                 SetValue(ThumbImageURLSelectorProperty, value);
551                 NotifyPropertyChanged();
552             }
553         }
554         private StringSelector InternalThumbImageURLSelector
555         {
556             get
557             {
558                 Selector<string> resourceUrlSelector = thumbImage?.ResourceUrlSelector;
559                 if(resourceUrlSelector != null)
560                 {
561                     return new StringSelector(resourceUrlSelector);
562                 }
563                 return null;
564             }
565             set
566             {
567                 if (value == null || thumbImage == null)
568                 {
569                     throw new NullReferenceException("Slider.ThumbImageURLSelector is null");
570                 }
571                 else
572                 {
573                     thumbImage.ResourceUrlSelector = value;
574                 }
575             }
576         }
577
578         /// <summary>
579         /// Gets or sets the Url of the thumb image.
580         /// </summary>
581         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
582         /// <since_tizen> 9 </since_tizen>
583         public Selector<string> ThumbImageUrl
584         {
585             get
586             {
587                 return GetValue(ThumbImageUrlProperty) as Selector<string>;
588             }
589             set
590             {
591                 SetValue(ThumbImageUrlProperty, value);
592                 NotifyPropertyChanged();
593             }
594         }
595         private Selector<string> InternalThumbImageUrl
596         {
597             get
598             {
599                 if (thumbImage == null)
600                 {
601                     return null;
602                 }
603                 else
604                 {
605                     return thumbImage.ResourceUrlSelector;
606                 }
607             }
608             set
609             {
610                 if (value == null || thumbImage == null)
611                 {
612                     throw new NullReferenceException("Slider.ThumbImageUrl is null");
613                 }
614                 else
615                 {
616                     thumbImage.ResourceUrlSelector = value;
617                 }
618             }
619         }
620
621         /// <summary>
622         /// Gets or sets the color of the thumb image object.
623         /// </summary>
624         /// <since_tizen> 8 </since_tizen>
625         public Color ThumbColor
626         {
627             get
628             {
629                 return GetValue(ThumbColorProperty) as Color;
630             }
631             set
632             {
633                 SetValue(ThumbColorProperty, value);
634                 NotifyPropertyChanged();
635             }
636         }
637         private Color InternalThumbColor
638         {
639             get
640             {
641                 return thumbColor;
642             }
643             set
644             {
645                 if (null != thumbImage)
646                 {
647                     thumbColor = value;
648
649                     if (thumbImage.ResourceUrl != null)
650                     {
651                         thumbImage.ResourceUrl = null;
652                     }
653
654                     using (PropertyMap map = new PropertyMap())
655                     {
656                         // To remove CA2000 warning messages, use `using` statement.
657                         using (PropertyValue type = new PropertyValue((int)Visual.Type.Color))
658                         {
659                             map.Insert((int)Visual.Property.Type, type);
660                         }
661                         using (PropertyValue color = new PropertyValue(thumbColor))
662                         {
663                             map.Insert((int)ColorVisualProperty.MixColor, color);
664                         }
665                         using (PropertyValue radius = new PropertyValue(0.5f))
666                         {
667                             map.Insert((int)Visual.Property.CornerRadius, radius);
668                         }
669                         using (PropertyValue policyType = new PropertyValue((int)VisualTransformPolicyType.Relative))
670                         {
671                             map.Insert((int)Visual.Property.CornerRadiusPolicy, policyType);
672                         }
673                         thumbImage.Image = map;
674                     }
675                 }
676             }
677         }
678
679         /// <summary>
680         /// Gets or sets the color of the background track image object.
681         /// </summary>
682         /// <since_tizen> 6 </since_tizen>
683         public Color BgTrackColor
684         {
685             get
686             {
687                 return GetValue(BgTrackColorProperty) as Color;
688             }
689             set
690             {
691                 SetValue(BgTrackColorProperty, value);
692                 NotifyPropertyChanged();
693             }
694         }
695         private Color InternalBgTrackColor
696         {
697             get
698             {
699                 return bgTrackImage?.BackgroundColor;
700             }
701             set
702             {
703                 if (null != bgTrackImage)
704                 {
705                     bgTrackImage.BackgroundColor = value;
706                 }
707             }
708         }
709
710         /// <summary>
711         /// Gets or sets the color of the slided track image object.
712         /// </summary>
713         /// <since_tizen> 6 </since_tizen>
714         public Color SlidedTrackColor
715         {
716             get
717             {
718                 return GetValue(SlidedTrackColorProperty) as Color;
719             }
720             set
721             {
722                 SetValue(SlidedTrackColorProperty, value);
723                 NotifyPropertyChanged();
724             }
725         }
726         private Color InternalSlidedTrackColor
727         {
728             get
729             {
730                 return slidedTrackImage?.BackgroundColor;
731             }
732             set
733             {
734                 if (null != slidedTrackImage)
735                 {
736                     slidedTrackImage.BackgroundColor = value;
737                 }
738             }
739         }
740
741         /// <summary>
742         /// Gets or sets the thickness value of the track.
743         /// </summary>
744         /// <since_tizen> 6 </since_tizen>
745         public uint TrackThickness
746         {
747             get
748             {
749                 return (uint)GetValue(TrackThicknessProperty);
750             }
751             set
752             {
753                 SetValue(TrackThicknessProperty, value);
754             }
755         }
756
757         /// <summary>
758         /// Gets or sets the warning start value between minimum value and maximum value of slider.
759         /// </summary>
760         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
761         [EditorBrowsable(EditorBrowsableState.Never)]
762         public float WarningStartValue
763         {
764             get
765             {
766                 return (float)GetValue(WarningStartValueProperty);
767             }
768             set
769             {
770                 SetValue(WarningStartValueProperty, value);
771                 NotifyPropertyChanged();
772             }
773         }
774         private float InternalWarningStartValue
775         {
776             get
777             {
778                 return warningStartValue;
779             }
780             set
781             {
782                 warningStartValue = value;
783                 UpdateValue();
784             }
785         }
786
787         /// <summary>
788         /// Gets or sets the color of the warning track image object.
789         /// </summary>
790         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
791         [EditorBrowsable(EditorBrowsableState.Never)]
792         public Color WarningTrackColor
793         {
794             get
795             {
796                 return GetValue(WarningTrackColorProperty) as Color;
797             }
798             set
799             {
800                 SetValue(WarningTrackColorProperty, value);
801                 NotifyPropertyChanged();
802             }
803         }
804         private Color InternalWarningTrackColor
805         {
806             get
807             {
808                 return warningTrackImage?.BackgroundColor;
809             }
810             set
811             {
812                 if (null != warningTrackImage)
813                 {
814                     warningTrackImage.BackgroundColor = value;
815                 }
816             }
817         }
818
819         /// <summary>
820         /// Gets or sets the color of the warning slided track image object.
821         /// </summary>
822         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
823         [EditorBrowsable(EditorBrowsableState.Never)]
824         public Color WarningSlidedTrackColor
825         {
826             get
827             {
828                 return GetValue(WarningSlidedTrackColorProperty) as Color;
829             }
830             set
831             {
832                 SetValue(WarningSlidedTrackColorProperty, value);
833                 NotifyPropertyChanged();
834             }
835         }
836         private Color InternalWarningSlidedTrackColor
837         {
838             get
839             {
840                 return warningSlidedTrackImage?.BackgroundColor;
841             }
842             set
843             {
844                 if (null != warningSlidedTrackImage)
845                 {
846                     warningSlidedTrackImage.BackgroundColor = value;
847                 }
848             }
849         }
850
851         /// <summary>
852         /// Gets or sets the Url of the warning thumb image.
853         /// </summary>
854         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
855         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
856         [EditorBrowsable(EditorBrowsableState.Never)]
857         public Selector<string> WarningThumbImageUrl
858         {
859             get
860             {
861                 return GetValue(WarningThumbImageUrlProperty) as Selector<string>;
862             }
863             set
864             {
865                 SetValue(WarningThumbImageUrlProperty, value);
866                 NotifyPropertyChanged();
867             }
868         }
869         private Selector<string> InternalWarningThumbImageUrl
870         {
871             get
872             {
873                 return warningThumbImageUrlSelector;
874             }
875             set
876             {
877                 if (value == null || thumbImage == null)
878                 {
879                     throw new NullReferenceException("Slider.WarningThumbImageUrl is null");
880                 }
881                 else
882                 {
883                     warningThumbImageUrlSelector = value;
884                 }
885             }
886         }
887
888         /// <summary>
889         /// Gets or sets the color of the warning thumb image object.
890         /// </summary>
891         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
892         [EditorBrowsable(EditorBrowsableState.Never)]
893         public Color WarningThumbColor
894         {
895             get
896             {
897                 return GetValue(WarningThumbColorProperty) as Color;
898             }
899             set
900             {
901                 SetValue(WarningThumbColorProperty, value);
902                 NotifyPropertyChanged();
903             }
904         }
905         private Color InternalWarningThumbColor
906         {
907             get
908             {
909                 return warningThumbColor;
910             }
911             set
912             {
913                 warningThumbColor = value;
914             }
915         }
916
917         /// <summary>
918         /// Gets or sets the resource url of the low indicator image object.
919         /// </summary>
920         /// <since_tizen> 6 </since_tizen>
921         public string LowIndicatorImageURL
922         {
923             get
924             {
925                 return GetValue(LowIndicatorImageURLProperty) as string;
926             }
927             set
928             {
929                 SetValue(LowIndicatorImageURLProperty, value);
930                 NotifyPropertyChanged();
931             }
932         }
933         private string InternalLowIndicatorImageURL
934         {
935             get
936             {
937                 return lowIndicatorImage?.ResourceUrl;
938             }
939             set
940             {
941                 if (null == lowIndicatorImage)
942                 {
943                     lowIndicatorImage = new ImageView
944                     {
945                         AccessibilityHidden = true,
946                     };
947                 }
948
949                 lowIndicatorImage.ResourceUrl = value;
950             }
951         }
952
953         /// <summary>
954         /// Gets or sets the resource url of the high indicator image object.
955         /// </summary>
956         /// <since_tizen> 6 </since_tizen>
957         public string HighIndicatorImageURL
958         {
959             get
960             {
961                 return GetValue(HighIndicatorImageURLProperty) as string;
962             }
963             set
964             {
965                 SetValue(HighIndicatorImageURLProperty, value);
966                 NotifyPropertyChanged();
967             }
968         }
969         private string InternalHighIndicatorImageURL
970         {
971             get
972             {
973                 return highIndicatorImage?.ResourceUrl;
974             }
975             set
976             {
977                 if (null == highIndicatorImage)
978                 {
979                     highIndicatorImage = new ImageView
980                     {
981                         AccessibilityHidden = true,
982                     };
983                 }
984
985                 highIndicatorImage.ResourceUrl = value;
986             }
987         }
988
989         /// <summary>
990         /// Gets or sets the text content of the low indicator text object.
991         /// </summary>
992         /// <since_tizen> 6 </since_tizen>
993         public string LowIndicatorTextContent
994         {
995             get
996             {
997                 return GetValue(LowIndicatorTextContentProperty) as string;
998             }
999             set
1000             {
1001                 SetValue(LowIndicatorTextContentProperty, value);
1002                 NotifyPropertyChanged();
1003             }
1004         }
1005         private string InternalLowIndicatorTextContent
1006         {
1007             get
1008             {
1009                 return lowIndicatorText?.Text;
1010             }
1011             set
1012             {
1013                 if (null != lowIndicatorText)
1014                 {
1015                     lowIndicatorText.Text = value;
1016                 }
1017             }
1018         }
1019
1020         /// <summary>
1021         /// Gets or sets the text content of the high indicator text object.
1022         /// </summary>
1023         /// <since_tizen> 6 </since_tizen>
1024         public string HighIndicatorTextContent
1025         {
1026             get
1027             {
1028                 return GetValue(HighIndicatorTextContentProperty) as string;
1029             }
1030             set
1031             {
1032                 SetValue(HighIndicatorTextContentProperty, value);
1033                 NotifyPropertyChanged();
1034             }
1035         }
1036         private string InternalHighIndicatorTextContent
1037         {
1038             get
1039             {
1040                 return highIndicatorText?.Text;
1041             }
1042             set
1043             {
1044                 if (null != highIndicatorText)
1045                 {
1046                     highIndicatorText.Text = value;
1047                 }
1048             }
1049         }
1050
1051         /// <summary>
1052         /// Gets or sets the size of the low indicator object(image or text).
1053         /// </summary>
1054         /// <since_tizen> 6 </since_tizen>
1055         public Size LowIndicatorSize
1056         {
1057             get
1058             {
1059                 return GetValue(LowIndicatorSizeProperty) as Size;
1060             }
1061             set
1062             {
1063                 SetValue(LowIndicatorSizeProperty, value);
1064                 NotifyPropertyChanged();
1065             }
1066         }
1067         private Size InternalLowIndicatorSize
1068         {
1069             get
1070             {
1071                 return lowIndicatorSize;
1072             }
1073             set
1074             {
1075                 lowIndicatorSize = value;
1076                 UpdateLowIndicatorSize();
1077                 UpdateBgTrackSize();
1078                 UpdateBgTrackPosition();
1079                 UpdateValue();
1080             }
1081         }
1082
1083         /// <summary>
1084         /// Gets or sets the size of the high indicator object(image or text).
1085         /// </summary>
1086         /// <since_tizen> 6 </since_tizen>
1087         public Size HighIndicatorSize
1088         {
1089             get
1090             {
1091                 return GetValue(HighIndicatorSizeProperty) as Size;
1092             }
1093             set
1094             {
1095                 SetValue(HighIndicatorSizeProperty, value);
1096                 NotifyPropertyChanged();
1097             }
1098         }
1099         private Size InternalHighIndicatorSize
1100         {
1101             get
1102             {
1103                 return highIndicatorSize;
1104             }
1105             set
1106             {
1107                 highIndicatorSize = value;
1108                 UpdateHighIndicatorSize();
1109                 UpdateBgTrackSize();
1110                 UpdateBgTrackPosition();
1111                 UpdateValue();
1112             }
1113         }
1114
1115         /// <summary>
1116         /// Gets or sets the value of the space between track and indicator.
1117         /// </summary>
1118         /// <since_tizen> 6 </since_tizen>
1119         public uint SpaceBetweenTrackAndIndicator
1120         {
1121             get
1122             {
1123                 return (uint)GetValue(SpaceBetweenTrackAndIndicatorProperty);
1124             }
1125             set
1126             {
1127                 SetValue(SpaceBetweenTrackAndIndicatorProperty, value);
1128             }
1129         }
1130
1131         /// <summary>
1132         /// Flag to decide whether the value indicator is shown
1133         /// </summary>
1134         /// <since_tizen> 9 </since_tizen>
1135         public bool IsValueShown
1136         {
1137             get
1138             {
1139                 return (bool)GetValue(IsValueShownProperty);
1140             }
1141             set
1142             {
1143                 SetValue(IsValueShownProperty, value);
1144             }
1145         }
1146
1147         /// <summary>
1148         /// Gets or sets the text of value indicator.
1149         /// </summary>
1150         /// <since_tizen> 9 </since_tizen>
1151         public string ValueIndicatorText
1152         {
1153             get
1154             {
1155                 return (string)GetValue(ValueIndicatorTextProperty);
1156             }
1157             set
1158             {
1159                 SetValue(ValueIndicatorTextProperty, value);
1160             }
1161         }
1162
1163         /// <summary>
1164         /// Gets or sets the size of the value indicator image object.
1165         /// </summary>
1166         /// <since_tizen> 9 </since_tizen>
1167         public Size ValueIndicatorSize
1168         {
1169             get
1170             {
1171                 return GetValue(ValueIndicatorSizeProperty) as Size;
1172             }
1173             set
1174             {
1175                 SetValue(ValueIndicatorSizeProperty, value);
1176                 NotifyPropertyChanged();
1177             }
1178         }
1179         private Size InternalValueIndicatorSize
1180         {
1181             get
1182             {
1183                 return valueIndicatorImage?.Size;
1184             }
1185             set
1186             {
1187                 if (null != valueIndicatorImage)
1188                 {
1189                     valueIndicatorImage.Size = value;
1190                 }
1191             }
1192         }
1193
1194         /// <summary>
1195         /// Gets or sets the resource url of the value indicator image object.
1196         /// </summary>
1197         /// <since_tizen> 9 </since_tizen>
1198         public string ValueIndicatorUrl
1199         {
1200             get
1201             {
1202                 return GetValue(ValueIndicatorUrlProperty) as string;
1203             }
1204             set
1205             {
1206                 SetValue(ValueIndicatorUrlProperty, value);
1207                 NotifyPropertyChanged();
1208             }
1209         }
1210         private string InternalValueIndicatorUrl
1211         {
1212             get
1213             {
1214                 return valueIndicatorImage?.ResourceUrl;
1215             }
1216             set
1217             {
1218                 if (null != valueIndicatorImage)
1219                 {
1220                     valueIndicatorImage.ResourceUrl = value;
1221                 }
1222             }
1223         }
1224
1225         /// <summary>
1226         /// Flag to decide whether the thumb snaps to the nearest discrete value when the user drags the thumb or taps.
1227         ///
1228         /// The default value is false.
1229         /// </summary>
1230         /// <since_tizen> 9 </since_tizen>
1231         public bool IsDiscrete
1232         {
1233             get
1234             {
1235                 return (bool)GetValue(IsDiscreteProperty);
1236             }
1237             set
1238             {
1239                 SetValue(IsDiscreteProperty, value);
1240                 NotifyPropertyChanged();
1241             }
1242         }
1243         private bool InternalIsDiscrete { get; set; } = false;
1244
1245         /// <summary>
1246         /// Gets or sets the discrete value of slider.
1247         /// </summary>
1248         /// <remarks>
1249         /// The discrete value is evenly spaced between MinValue and MaxValue.
1250         /// For example, MinValue is 0, MaxValue is 100, and DiscreteValue is 20.
1251         /// Then, the thumb can only go to 0, 20, 40, 60, 80, and 100.
1252         /// The default is 0.
1253         /// </remarks>
1254         /// <since_tizen> 9 </since_tizen>
1255         public float DiscreteValue
1256         {
1257             get
1258             {
1259                 return (float)GetValue(DiscreteValueProperty);
1260             }
1261             set
1262             {
1263                 SetValue(DiscreteValueProperty, value);
1264                 NotifyPropertyChanged();
1265             }
1266         }
1267         private float InternalDiscreteValue
1268         {
1269             get
1270             {
1271                 return discreteValue;
1272             }
1273             set
1274             {
1275                 discreteValue = value;
1276                 UpdateValue();
1277             }
1278         }
1279
1280         private Extents spaceBetweenTrackAndIndicator
1281         {
1282             get
1283             {
1284                 if (null == spaceTrackIndicator)
1285                 {
1286                     spaceTrackIndicator = new Extents((ushort start, ushort end, ushort top, ushort bottom) =>
1287                     {
1288                         Extents extents = new Extents(start, end, top, bottom);
1289                         spaceTrackIndicator.CopyFrom(extents);
1290                     }, 0, 0, 0, 0);
1291                 }
1292
1293                 return spaceTrackIndicator;
1294             }
1295         }
1296
1297         private IndicatorType privateIndicatorType
1298         {
1299             get
1300             {
1301                 return indicatorType;
1302             }
1303             set
1304             {
1305                 if (indicatorType == value)
1306                 {
1307                     return;
1308                 }
1309                 indicatorType = value;
1310                 RelayoutBaseComponent(false);
1311                 UpdateBgTrackSize();
1312                 UpdateBgTrackPosition();
1313                 UpdateValue();
1314             }
1315         }
1316
1317         private uint privateTrackThickness
1318         {
1319             get
1320             {
1321                 return trackThickness ?? 0;
1322             }
1323             set
1324             {
1325                 trackThickness = value;
1326                 if (bgTrackImage != null)
1327                 {
1328                     if (direction == DirectionType.Horizontal)
1329                     {
1330                         bgTrackImage.SizeHeight = (float)trackThickness.Value;
1331                     }
1332                     else if (direction == DirectionType.Vertical)
1333                     {
1334                         bgTrackImage.SizeWidth = (float)trackThickness.Value;
1335                     }
1336                 }
1337                 if (slidedTrackImage != null)
1338                 {
1339                     if (direction == DirectionType.Horizontal)
1340                     {
1341                         slidedTrackImage.SizeHeight = (float)trackThickness.Value;
1342                     }
1343                     else if (direction == DirectionType.Vertical)
1344                     {
1345                         slidedTrackImage.SizeWidth = (float)trackThickness.Value;
1346                     }
1347                 }
1348                 if (warningTrackImage != null)
1349                 {
1350                     if (direction == DirectionType.Horizontal)
1351                     {
1352                         warningTrackImage.SizeHeight = (float)trackThickness.Value;
1353                     }
1354                     else if (direction == DirectionType.Vertical)
1355                     {
1356                         warningTrackImage.SizeWidth = (float)trackThickness.Value;
1357                     }
1358                 }
1359                 if (warningSlidedTrackImage != null)
1360                 {
1361                     if (direction == DirectionType.Horizontal)
1362                     {
1363                         warningSlidedTrackImage.SizeHeight = (float)trackThickness.Value;
1364                     }
1365                     else if (direction == DirectionType.Vertical)
1366                     {
1367                         warningSlidedTrackImage.SizeWidth = (float)trackThickness.Value;
1368                     }
1369                 }
1370             }
1371         }
1372
1373         private uint privateSpaceBetweenTrackAndIndicator
1374         {
1375             get
1376             {
1377                 return privateTrackPadding.Start;
1378             }
1379             set
1380             {
1381                 ushort val = (ushort)value;
1382                 privateTrackPadding = new Extents(val, val, val, val);
1383             }
1384         }
1385
1386         private Extents privateTrackPadding
1387         {
1388             get
1389             {
1390                 return spaceBetweenTrackAndIndicator;
1391             }
1392             set
1393             {
1394                 spaceBetweenTrackAndIndicator.CopyFrom(value);
1395                 UpdateComponentByIndicatorTypeChanged();
1396                 UpdateBgTrackSize();
1397                 UpdateBgTrackPosition();
1398                 UpdateValue();
1399             }
1400         }
1401
1402         /// <summary>
1403         /// Focus gained callback.
1404         /// </summary>
1405         /// <since_tizen> 8 </since_tizen>
1406         public override void OnFocusGained()
1407         {
1408             //State = ControlStates.Focused;
1409             UpdateState(true, isPressed);
1410             base.OnFocusGained();
1411         }
1412
1413         /// <summary>
1414         /// Focus Lost callback.
1415         /// </summary>
1416         /// <since_tizen> 8 </since_tizen>
1417         public override void OnFocusLost()
1418         {
1419             //State = ControlStates.Normal;
1420             UpdateState(false, isPressed);
1421             base.OnFocusLost();
1422         }
1423
1424         private bool editMode = false;
1425         private View recoverIndicator;
1426         private View editModeIndicator;
1427
1428         /// <inheritdoc/>
1429         [EditorBrowsable(EditorBrowsableState.Never)]
1430         public override bool OnKeyboardEnter()
1431         {
1432             if (!IsEnabled)
1433             {
1434                 return false;
1435             }
1436             if (editMode)
1437             {
1438                 //set editMode false (toggle the mode)
1439                 editMode = false;
1440                 FocusManager.Instance.FocusIndicator = recoverIndicator;
1441             }
1442             else
1443             {
1444                 //set editMode true (toggle the mode)
1445                 editMode = true;
1446                 if (editModeIndicator == null)
1447                 {
1448                     editModeIndicator = new View()
1449                     {
1450                         PositionUsesPivotPoint = true,
1451                         PivotPoint = new Position(0, 0, 0),
1452                         WidthResizePolicy = ResizePolicyType.FillToParent,
1453                         HeightResizePolicy = ResizePolicyType.FillToParent,
1454                         BorderlineColor = Color.Red,
1455                         BorderlineWidth = 6.0f,
1456                         BorderlineOffset = -1f,
1457                         BackgroundColor = new Color(0.2f, 0.2f, 0.2f, 0.4f),
1458                         AccessibilityHidden = true,
1459                     };
1460                 }
1461                 recoverIndicator = FocusManager.Instance.FocusIndicator;
1462                 FocusManager.Instance.FocusIndicator = editModeIndicator;
1463             }
1464             UpdateState(true, isPressed);
1465             return true;
1466         }
1467
1468         /// <inheritdoc/>
1469         [EditorBrowsable(EditorBrowsableState.Never)]
1470         public override bool OnKey(Key key)
1471         {
1472             if (!IsEnabled || null == key)
1473             {
1474                 return false;
1475             }
1476
1477             if (key.State == Key.StateType.Down)
1478             {
1479                 float valueDiff;
1480                 if (IsDiscrete)
1481                 {
1482                     valueDiff = discreteValue;
1483                 }
1484                 else
1485                 {
1486                     // TODO : Currently we set the velocity of value as 1% hardly.
1487                     // Can we use AccessibilityGetMinimumIncrement?
1488                     valueDiff = (maxValue - minValue) * 0.01f;
1489                 }
1490                 if ((direction == DirectionType.Horizontal && key.KeyPressedName == "Left") ||
1491                     (direction == DirectionType.Vertical && key.KeyPressedName == "Down"))
1492                 {
1493                     if (editMode)
1494                     {
1495                         if (minValue < curValue)
1496                         {
1497                             isPressed = true;
1498                             CurrentValue -= valueDiff;
1499                         }
1500                         return true; // Consumed
1501                     }
1502                 }
1503                 else if ((direction == DirectionType.Horizontal && key.KeyPressedName == "Right") ||
1504                          (direction == DirectionType.Vertical && key.KeyPressedName == "Up"))
1505                 {
1506                     if (editMode)
1507                     {
1508                         if (maxValue > curValue)
1509                         {
1510                             isPressed = true;
1511                             CurrentValue += valueDiff;
1512                         }
1513                         return true; // Consumed
1514                     }
1515                 }
1516             }
1517             else if (key.State == Key.StateType.Up)
1518             {
1519                 isPressed = false;
1520             }
1521
1522             if (key.KeyPressedName == "Up" || key.KeyPressedName == "Right" || key.KeyPressedName == "Down" || key.KeyPressedName == "Left")
1523             {
1524                 if (editMode)
1525                 {
1526                     return true;
1527                 }
1528             }
1529             return false;
1530         }
1531
1532         /// <summary>
1533         /// Apply style to scrollbar.
1534         /// </summary>
1535         /// <param name="viewStyle">The style to apply.</param>
1536         /// <since_tizen> 8 </since_tizen>
1537         public override void ApplyStyle(ViewStyle viewStyle)
1538         {
1539             base.ApplyStyle(viewStyle);
1540
1541             SliderStyle sliderStyle = viewStyle as SliderStyle;
1542
1543             if (null != sliderStyle?.Progress)
1544             {
1545                 CreateSlidedTrack().ApplyStyle(sliderStyle.Progress);
1546             }
1547
1548             if (null != sliderStyle?.LowIndicator)
1549             {
1550                 CreateLowIndicatorText().ApplyStyle(sliderStyle.LowIndicator);
1551             }
1552
1553             if (null != sliderStyle?.HighIndicator)
1554             {
1555                 CreateHighIndicatorText().ApplyStyle(sliderStyle.HighIndicator);
1556             }
1557
1558             if (null != sliderStyle?.LowIndicatorImage)
1559             {
1560                 CreateLowIndicatorImage().ApplyStyle(sliderStyle.LowIndicatorImage);
1561             }
1562
1563             if (null != sliderStyle?.HighIndicatorImage)
1564             {
1565                 CreateHighIndicatorImage().ApplyStyle(sliderStyle.HighIndicatorImage);
1566             }
1567
1568             if (null != sliderStyle?.Track)
1569             {
1570                 CreateBackgroundTrack().ApplyStyle(sliderStyle.Track);
1571             }
1572
1573             if (null != sliderStyle?.Thumb)
1574             {
1575                 CreateThumb().ApplyStyle(sliderStyle.Thumb);
1576             }
1577
1578             if (null != sliderStyle?.ValueIndicatorText)
1579             {
1580                 CreateValueIndicatorText().ApplyStyle(sliderStyle.ValueIndicatorText);
1581             }
1582
1583             if (null != sliderStyle?.ValueIndicatorImage)
1584             {
1585                 CreateValueIndicatorImage().ApplyStyle(sliderStyle.ValueIndicatorImage);
1586             }
1587
1588             if (null != sliderStyle?.WarningTrack)
1589             {
1590                 CreateWarningTrack().ApplyStyle(sliderStyle.WarningTrack);
1591             }
1592
1593             if (null != sliderStyle?.WarningProgress)
1594             {
1595                 CreateWarningSlidedTrack().ApplyStyle(sliderStyle.WarningProgress);
1596             }
1597
1598             EnableControlStatePropagation = true;
1599         }
1600
1601         /// <summary>
1602         /// Gets minimum value for Accessibility.
1603         /// </summary>
1604         [EditorBrowsable(EditorBrowsableState.Never)]
1605         double IAtspiValue.AccessibilityGetMinimum()
1606         {
1607             return (double)MinValue;
1608         }
1609
1610         /// <summary>
1611         /// Gets the current value for Accessibility.
1612         /// </summary>
1613         [EditorBrowsable(EditorBrowsableState.Never)]
1614         double IAtspiValue.AccessibilityGetCurrent()
1615         {
1616             return (double)CurrentValue;
1617         }
1618
1619         /// <summary>
1620         /// Formatted current value.
1621         /// </summary>
1622         [EditorBrowsable(EditorBrowsableState.Never)]
1623         string IAtspiValue.AccessibilityGetValueText()
1624         {
1625             return $"{CurrentValue}";
1626         }
1627
1628         /// <summary>
1629         /// Gets maximum value for Accessibility.
1630         /// </summary>
1631         [EditorBrowsable(EditorBrowsableState.Never)]
1632         double IAtspiValue.AccessibilityGetMaximum()
1633         {
1634             return (double)MaxValue;
1635         }
1636
1637         /// <summary>
1638         /// Sets the current value using Accessibility.
1639         /// </summary>
1640         [EditorBrowsable(EditorBrowsableState.Never)]
1641         bool IAtspiValue.AccessibilitySetCurrent(double value)
1642         {
1643             var current = (float)value;
1644
1645             if (current >= MinValue && current <= MaxValue)
1646             {
1647                 CurrentValue = current;
1648                 return true;
1649             }
1650
1651             return false;
1652         }
1653
1654         /// <summary>
1655         /// Gets minimum increment for Accessibility.
1656         /// </summary>
1657         [EditorBrowsable(EditorBrowsableState.Never)]
1658         double IAtspiValue.AccessibilityGetMinimumIncrement()
1659         {
1660             // FIXME
1661             return (MaxValue - MinValue) / 20.0;
1662         }
1663
1664         /// <summary>
1665         /// Initialize AT-SPI object.
1666         /// </summary>
1667         [EditorBrowsable(EditorBrowsableState.Never)]
1668         public override void OnInitialize()
1669         {
1670             base.OnInitialize();
1671             AccessibilityRole = Role.Slider;
1672         }
1673
1674         /// <summary>
1675         /// Get Slider style.
1676         /// </summary>
1677         /// <returns>The default slider style.</returns>
1678         /// <since_tizen> 8 </since_tizen>
1679         protected override ViewStyle CreateViewStyle()
1680         {
1681             return new SliderStyle();
1682         }
1683
1684         /// <summary>
1685         /// Dispose Slider.
1686         /// </summary>
1687         /// <param name="type">Dispose type.</param>
1688         /// <since_tizen> 6 </since_tizen>
1689         protected override void Dispose(DisposeTypes type)
1690         {
1691             if (disposed)
1692             {
1693                 return;
1694             }
1695
1696             if (type == DisposeTypes.Explicit)
1697             {
1698                 if (null != panGestureDetector)
1699                 {
1700                     panGestureDetector.Detach(this);
1701                     panGestureDetector.Detected -= OnPanGestureDetected;
1702                     panGestureDetector.Dispose();
1703                     panGestureDetector = null;
1704                 }
1705
1706                 if (null != thumbImage)
1707                 {
1708                     thumbImage.TouchEvent -= OnTouchEventForThumb;
1709                     Utility.Dispose(thumbImage);
1710                 }
1711                 Utility.Dispose(warningSlidedTrackImage);
1712                 Utility.Dispose(warningTrackImage);
1713                 Utility.Dispose(slidedTrackImage);
1714                 Utility.Dispose(bgTrackImage);
1715                 Utility.Dispose(lowIndicatorImage);
1716                 Utility.Dispose(highIndicatorImage);
1717                 Utility.Dispose(lowIndicatorText);
1718                 Utility.Dispose(highIndicatorText);
1719                 Utility.Dispose(valueIndicatorImage);
1720                 Utility.Dispose(valueIndicatorText);
1721
1722                 this.TouchEvent -= OnTouchEventForTrack;
1723
1724                 recoverIndicator = null;
1725                 if (editModeIndicator != null)
1726                 {
1727                     editModeIndicator.Dispose();
1728                     editModeIndicator = null;
1729                 }
1730             }
1731
1732             base.Dispose(type);
1733         }
1734
1735         /// <summary>
1736         /// Update Slider by style.
1737         /// </summary>
1738         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
1739         [EditorBrowsable(EditorBrowsableState.Never)]
1740         protected override void OnUpdate()
1741         {
1742             RelayoutBaseComponent();
1743
1744             UpdateComponentByIndicatorTypeChanged();
1745             UpdateBgTrackSize();
1746             UpdateBgTrackPosition();
1747             UpdateWarningTrackSize();
1748             UpdateLowIndicatorSize();
1749             UpdateHighIndicatorSize();
1750             UpdateValue();
1751         }
1752
1753         /// <inheritdoc/>
1754         [EditorBrowsable(EditorBrowsableState.Never)]
1755         protected override void OnEnabled(bool enabled)
1756         {
1757             base.OnEnabled(enabled);
1758             UpdateValue();
1759         }
1760
1761         private void CalculateCurrentValueByGesture(float offset)
1762         {
1763             currentSlidedOffset += offset;
1764
1765             float resultValue = this.CurrentValue;
1766
1767             int bgTrackLength = GetBgTrackLength();
1768             if (bgTrackLength != 0)
1769             {
1770                 resultValue = ((currentSlidedOffset / (float)bgTrackLength) * (float)(maxValue - minValue)) + minValue;
1771             }
1772
1773             if (IsDiscrete)
1774             {
1775                 this.CurrentValue = CalculateDiscreteValue(resultValue);
1776             }
1777             else
1778             {
1779                 this.CurrentValue = resultValue;
1780             }
1781         }
1782
1783         private bool OnTouchEventForTrack(object source, TouchEventArgs e)
1784         {
1785             if (!IsEnabled)
1786             {
1787                 return false;
1788             }
1789
1790             if (this.FocusableInTouch == false && editMode == false)
1791             {
1792                 isFocused = false;
1793             }
1794
1795             PointStateType state = e.Touch.GetState(0);
1796             if (state == PointStateType.Down)
1797             {
1798                 if (isValueShown)
1799                 {
1800                     valueIndicatorImage.Show();
1801                 }
1802
1803                 UpdateState(isFocused, true);
1804
1805                 sliderSlidingStartedHandler?.Invoke(this, new SliderSlidingStartedEventArgs
1806                 {
1807                     CurrentValue = curValue
1808                 });
1809
1810                 Vector2 pos = e.Touch.GetLocalPosition(0);
1811                 CalculateCurrentValueByTouch(pos);
1812                 UpdateValue();
1813             }
1814             else if (state == PointStateType.Up)
1815             {
1816                 if (isValueShown)
1817                 {
1818                     valueIndicatorImage.Hide();
1819                 }
1820
1821                 UpdateState(isFocused, false);
1822
1823                 sliderSlidingFinishedHandler?.Invoke(this, new SliderSlidingFinishedEventArgs
1824                 {
1825                     CurrentValue = curValue
1826                 });
1827             }
1828             return false;
1829         }
1830
1831         private bool OnTouchEventForThumb(object source, TouchEventArgs e)
1832         {
1833             if (this.FocusableInTouch == false && editMode == false)
1834             {
1835                 isFocused = false;
1836             }
1837
1838             PointStateType state = e.Touch.GetState(0);
1839             if (state == PointStateType.Down)
1840             {
1841                 UpdateState(isFocused, true);
1842             }
1843             else if (state == PointStateType.Up)
1844             {
1845                 UpdateState(isFocused, false);
1846             }
1847             return true;
1848         }
1849
1850         private void CalculateCurrentValueByTouch(Vector2 pos)
1851         {
1852             int bgTrackLength = GetBgTrackLength();
1853             if (direction == DirectionType.Horizontal)
1854             {
1855                 currentSlidedOffset = pos.X - GetBgTrackLowIndicatorOffset();
1856             }
1857             else if (direction == DirectionType.Vertical)
1858             {
1859                 currentSlidedOffset = this.Size2D.Height - pos.Y - GetBgTrackLowIndicatorOffset();
1860             }
1861
1862             if (bgTrackLength != 0)
1863             {
1864                 float resultValue = ((currentSlidedOffset / (float)bgTrackLength) * (maxValue - minValue)) + minValue;
1865
1866                 if (IsDiscrete)
1867                 {
1868                     this.CurrentValue = CalculateDiscreteValue(resultValue);
1869                 }
1870                 else
1871                 {
1872                     this.CurrentValue = resultValue;
1873                 }
1874             }
1875         }
1876
1877         private float CalculateDiscreteValue(float value)
1878         {
1879             return ((float)Math.Round((value / discreteValue)) * discreteValue);
1880         }
1881
1882         private void UpdateState(bool isFocusedNew, bool isPressedNew)
1883         {
1884             if (isFocused == isFocusedNew && isPressed == isPressedNew)
1885             {
1886                 return;
1887             }
1888             if (thumbImage == null || Style == null)
1889             {
1890                 return;
1891             }
1892             isFocused = isFocusedNew;
1893             isPressed = isPressedNew;
1894
1895             if (!IsEnabled) // Disabled
1896             {
1897                 ControlState = ControlState.Disabled;
1898             }
1899             else if (!isFocused && !isPressed)
1900             {
1901                 ControlState = ControlState.Normal;
1902             }
1903             else if (isPressed)
1904             {
1905                 ControlState = ControlState.Pressed;
1906             }
1907             else if (!isPressed && isFocused)
1908             {
1909                 ControlState = ControlState.Focused;
1910             }
1911         }
1912
1913         private void UpdateComponentByIndicatorTypeChanged()
1914         {
1915             IndicatorType type = CurrentIndicatorType();
1916             if (type == IndicatorType.None)
1917             {
1918                 if (lowIndicatorImage != null)
1919                 {
1920                     lowIndicatorImage.Hide();
1921                 }
1922                 if (highIndicatorImage != null)
1923                 {
1924                     highIndicatorImage.Hide();
1925                 }
1926                 if (lowIndicatorText != null)
1927                 {
1928                     lowIndicatorText.Hide();
1929                 }
1930                 if (highIndicatorText != null)
1931                 {
1932                     highIndicatorText.Hide();
1933                 }
1934             }
1935             else if (type == IndicatorType.Image)
1936             {
1937                 if (lowIndicatorImage != null)
1938                 {
1939                     lowIndicatorImage.Show();
1940                 }
1941                 if (highIndicatorImage != null)
1942                 {
1943                     highIndicatorImage.Show();
1944                 }
1945                 if (lowIndicatorText != null)
1946                 {
1947                     lowIndicatorText.Hide();
1948                 }
1949                 if (highIndicatorText != null)
1950                 {
1951                     highIndicatorText.Hide();
1952                 }
1953             }
1954             else if (type == IndicatorType.Text)
1955             {
1956                 if (lowIndicatorText != null)
1957                 {
1958                     lowIndicatorText.Show();
1959                 }
1960                 if (highIndicatorText != null)
1961                 {
1962                     highIndicatorText.Show();
1963                 }
1964                 if (lowIndicatorImage != null)
1965                 {
1966                     lowIndicatorImage.Hide();
1967                 }
1968                 if (highIndicatorImage != null)
1969                 {
1970                     highIndicatorImage.Hide();
1971                 }
1972             }
1973         }
1974     }
1975 }