[NUI] Add Value Indicator of Slider (#2533)
[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         [EditorBrowsable(EditorBrowsableState.Never)]
70         public static readonly BindableProperty IndicatorTypeProperty = BindableProperty.Create("IndicatorType", typeof(IndicatorType), typeof(Slider), IndicatorType.None, propertyChanged: (bindable, oldValue, newValue) =>
71         {
72             var instance = (Slider)bindable;
73             if (newValue != null)
74             {
75                 instance.privateIndicatorType = (IndicatorType)newValue;
76             }
77         },
78         defaultValueCreator: (bindable) =>
79         {
80             var instance = (Slider)bindable;
81             return instance.privateIndicatorType;
82         });
83         [EditorBrowsable(EditorBrowsableState.Never)]
84         public static readonly BindableProperty SpaceBetweenTrackAndIndicatorProperty = BindableProperty.Create(nameof(SpaceBetweenTrackAndIndicator), typeof(uint), typeof(Slider), (uint)0, propertyChanged: (bindable, oldValue, newValue) =>
85         {
86             var instance = (Slider)bindable;
87             if (newValue != null)
88             {
89                 instance.privateSpaceBetweenTrackAndIndicator = (uint)newValue;
90             }
91         },
92         defaultValueCreator: (bindable) =>
93         {
94             var instance = (Slider)bindable;
95             return instance.privateSpaceBetweenTrackAndIndicator;
96         });
97         [EditorBrowsable(EditorBrowsableState.Never)]
98         public static readonly BindableProperty TrackThicknessProperty = BindableProperty.Create(nameof(TrackThickness), typeof(uint), typeof(Slider), (uint)0, propertyChanged: (bindable, oldValue, newValue) =>
99         {
100             var instance = (Slider)bindable;
101             if (newValue != null)
102             {
103                 instance.privateTrackThickness = (uint)newValue;
104             }
105         },
106         defaultValueCreator: (bindable) =>
107         {
108             var instance = (Slider)bindable;
109             return instance.privateTrackThickness;
110         });
111         [EditorBrowsable(EditorBrowsableState.Never)]
112         public static readonly BindableProperty IsValueShownProperty = BindableProperty.Create(nameof(IsValueShown), typeof(bool), typeof(Slider), true, propertyChanged: (bindable, oldValue, newValue) =>
113         {
114             var instance = (Slider)bindable;
115             if (newValue != null)
116             {
117                 bool newValueShown = (bool)newValue;
118                 if (instance.isValueShown != newValueShown)
119                 {
120                     instance.isValueShown = newValueShown;
121                 }
122             }
123         },
124         defaultValueCreator: (bindable) =>
125         {
126             var instance = (Slider)bindable;
127             return instance.isValueShown;
128         });
129         [EditorBrowsable(EditorBrowsableState.Never)]
130         public static readonly BindableProperty ValueIndicatorTextProperty = BindableProperty.Create(nameof(ValueIndicatorText), typeof(string), typeof(Slider), string.Empty, propertyChanged: (bindable, oldValue, newValue) =>
131         {
132             var instance = (Slider)bindable;
133             if (newValue != null)
134             {
135                 string newText = (string)newValue;
136                 instance.valueIndicatorText.Text = newText;
137                 if (instance.sliderStyle != null)
138                 {
139                     instance.sliderStyle.ValueIndicatorText.Text = newText;
140                 }
141             }
142         },
143         defaultValueCreator: (bindable) =>
144         {
145             var instance = (Slider)bindable;
146             return instance.valueIndicatorText.Text;
147         });
148
149         static Slider() { }
150
151         /// <summary>
152         /// The constructor of the Slider class.
153         /// </summary>
154         /// <since_tizen> 6 </since_tizen>
155         public Slider()
156         {
157             Initialize();
158         }
159
160         /// <summary>
161         /// The constructor of the Slider class with specific style.
162         /// </summary>
163         /// <param name="style">The string to initialize the Slider</param>
164         /// <since_tizen> 8 </since_tizen>
165         public Slider(string style) : base(style)
166         {
167             Initialize();
168         }
169
170         /// <summary>
171         /// The constructor of the Slider class with specific style.
172         /// </summary>
173         /// <param name="sliderStyle">The style object to initialize the Slider</param>
174         /// <since_tizen> 8 </since_tizen>
175         public Slider(SliderStyle sliderStyle) : base(sliderStyle)
176         {
177             Initialize();
178         }
179
180         /// <summary>
181         /// The value changed event handler.
182         /// </summary>
183         /// <since_tizen> 6 </since_tizen>
184         [Obsolete("Deprecated in API8; Will be removed in API10. Please use ValueChanged event instead.")]
185         public event EventHandler<ValueChangedArgs> ValueChangedEvent
186         {
187             add
188             {
189                 valueChangedHandler += value;
190             }
191             remove
192             {
193                 valueChangedHandler -= value;
194             }
195         }
196
197         /// <summary>
198         /// The sliding finished event handler.
199         /// </summary>
200         /// <since_tizen> 6 </since_tizen>
201         [Obsolete("Deprecated in API8; Will be removed in API10. Please use SlidingFinished event instead.")]
202         public event EventHandler<SlidingFinishedArgs> SlidingFinishedEvent
203         {
204             add
205             {
206                 slidingFinishedHandler += value;
207             }
208             remove
209             {
210                 slidingFinishedHandler -= value;
211             }
212         }
213
214         /// <summary>
215         /// The value changed event handler.
216         /// </summary>
217         /// <since_tizen> 8 </since_tizen>
218         public event EventHandler<SliderValueChangedEventArgs> ValueChanged
219         {
220             add
221             {
222                 sliderValueChangedHandler += value;
223             }
224             remove
225             {
226                 sliderValueChangedHandler -= value;
227             }
228         }
229
230         /// <summary>
231         /// The sliding started event handler.
232         /// </summary>
233         /// <since_tizen> 8 </since_tizen>
234         public event EventHandler<SliderSlidingStartedEventArgs> SlidingStarted
235         {
236             add
237             {
238                 sliderSlidingStartedHandler += value;
239             }
240             remove
241             {
242                 sliderSlidingStartedHandler -= value;
243             }
244         }
245
246         /// <summary>
247         /// The sliding finished event handler.
248         /// </summary>
249         /// <since_tizen> 8 </since_tizen>
250         public event EventHandler<SliderSlidingFinishedEventArgs> SlidingFinished
251         {
252             add
253             {
254                 sliderSlidingFinishedHandler += value;
255             }
256             remove
257             {
258                 sliderSlidingFinishedHandler -= value;
259             }
260         }
261
262         /// <summary>
263         /// The state changed event handler.
264         /// </summary>
265         /// <since_tizen> 6 </since_tizen>
266         [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")]
267         public event EventHandler<StateChangedArgs> StateChangedEvent
268         {
269             add
270             {
271                 stateChangedHandler += value;
272             }
273             remove
274             {
275                 stateChangedHandler -= value;
276             }
277         }
278
279         /// <summary>
280         /// The direction type of slider.
281         /// </summary>
282         /// <since_tizen> 6 </since_tizen>
283         public enum DirectionType
284         {
285             /// <summary>
286             /// The Horizontal type.
287             /// </summary>
288             /// <since_tizen> 6 </since_tizen>
289             Horizontal,
290
291             /// <summary>
292             /// The Vertical type.
293             /// </summary>
294             /// <since_tizen> 6 </since_tizen>
295             Vertical
296         }
297
298         /// <summary>
299         /// The indicator type of slider.
300         /// </summary>
301         /// <since_tizen> 6 </since_tizen>
302         public enum IndicatorType
303         {
304             /// <summary> Only contains slider bar.</summary>
305             /// <since_tizen> 6 </since_tizen>
306             None,
307
308             /// <summary> Contains slider bar, IndicatorImage.</summary>
309             /// <since_tizen> 6 </since_tizen>
310             Image,
311
312             /// <summary> Contains slider bar, IndicatorText.</summary>
313             /// <since_tizen> 6 </since_tizen>
314             Text
315         }
316
317         /// <summary>
318         /// Return a copied Style instance of Slider
319         /// </summary>
320         /// <remarks>
321         /// It returns copied Style instance and changing it does not effect to the Slider.
322         /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
323         /// </remarks>
324         /// <since_tizen> 8 </since_tizen>
325         public new SliderStyle Style
326         {
327             get
328             {
329                 var result = new SliderStyle(sliderStyle);
330                 result.CopyPropertiesFromView(this);
331                 result.Track.CopyPropertiesFromView(bgTrackImage);
332                 result.Progress.CopyPropertiesFromView(slidedTrackImage);
333                 result.Thumb.CopyPropertiesFromView(thumbImage);
334                 result.LowIndicatorImage.CopyPropertiesFromView(lowIndicatorImage);
335                 result.HighIndicatorImage.CopyPropertiesFromView(highIndicatorImage);
336                 result.LowIndicator.CopyPropertiesFromView(lowIndicatorText);
337                 result.HighIndicator.CopyPropertiesFromView(highIndicatorText);
338                 result.ValueIndicatorText.CopyPropertiesFromView(valueIndicatorText);
339                 result.ValueIndicatorImage.CopyPropertiesFromView(valueIndicatorImage);
340                 return result;
341             }
342         }
343
344         /// <summary>
345         /// Return a copied Style instance of Slider
346         /// </summary>
347         private SliderStyle sliderStyle => ViewStyle as SliderStyle;
348
349         /// <summary>
350         /// Gets or sets the direction type of slider.
351         /// </summary>
352         /// <since_tizen> 6 </since_tizen>
353         public DirectionType Direction
354         {
355             get
356             {
357                 return direction;
358             }
359             set
360             {
361                 if (direction == value)
362                 {
363                     return;
364                 }
365                 direction = value;
366                 RelayoutBaseComponent(false);
367                 UpdateBgTrackSize();
368                 UpdateBgTrackPosition();
369                 UpdateValue();
370             }
371         }
372
373         /// <summary>
374         /// Gets or sets the indicator type, arrow or sign.
375         /// </summary>
376         /// <since_tizen> 6 </since_tizen>
377         public IndicatorType Indicator
378         {
379             get
380             {
381                 return (IndicatorType)GetValue(IndicatorTypeProperty);
382             }
383             set
384             {
385                 SetValue(IndicatorTypeProperty, value);
386             }
387         }
388
389         /// <summary>
390         /// Gets or sets the minimum value of slider.
391         /// </summary>
392         /// <since_tizen> 6 </since_tizen>
393         public float MinValue
394         {
395             get
396             {
397                 return minValue;
398             }
399             set
400             {
401                 minValue = value;
402                 UpdateValue();
403             }
404         }
405
406         /// <summary>
407         /// Gets or sets the maximum value of slider.
408         /// </summary>
409         /// <since_tizen> 6 </since_tizen>
410         public float MaxValue
411         {
412             get
413             {
414                 return maxValue;
415             }
416             set
417             {
418                 maxValue = value;
419                 UpdateValue();
420             }
421         }
422
423         /// <summary>
424         /// Gets or sets the current value of slider.
425         /// </summary>
426         /// <since_tizen> 6 </since_tizen>
427         public float CurrentValue
428         {
429             get
430             {
431                 return curValue;
432             }
433             set
434             {
435                 curValue = value;
436                 UpdateValue();
437             }
438         }
439
440         /// <summary>
441         /// Gets or sets the size of the thumb image object.
442         /// </summary>
443         /// <since_tizen> 6 </since_tizen>
444         public Size ThumbSize
445         {
446             get
447             {
448                 return thumbImage?.Size;
449             }
450             set
451             {
452                 if (null != thumbImage)
453                 {
454                     thumbImage.Size = value;
455                     sliderStyle.Thumb.Size = value;
456                 }
457             }
458         }
459
460         /// <summary>
461         /// Gets or sets the resource url of the thumb image object.
462         /// </summary>
463         /// <since_tizen> 6 </since_tizen>
464         public string ThumbImageURL
465         {
466             get
467             {
468                 return thumbImage?.ResourceUrl;
469             }
470             set
471             {
472                 if (null != thumbImage)
473                 {
474                     thumbImage.ResourceUrl = value;
475                     sliderStyle.Thumb.ResourceUrl = value;
476                 }
477             }
478         }
479
480         /// <summary>
481         /// Gets or sets the resource url selector of the thumb image object.
482         /// Getter returns copied selector value if exist, null otherwise.
483         /// </summary>
484         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
485         /// <since_tizen> 6 </since_tizen>
486         public StringSelector ThumbImageURLSelector
487         {
488             get => thumbImage == null ? null : new StringSelector((Selector<string>)thumbImage.GetValue(ImageView.ResourceUrlSelectorProperty));
489             set
490             {
491                 if (value == null || thumbImage == null)
492                 {
493                     throw new NullReferenceException("Slider.ThumbImageURLSelector is null");
494                 }
495                 else
496                 {
497                     thumbImage.SetValue(ImageView.ResourceUrlSelectorProperty, value);
498                 }
499             }
500         }
501
502         /// <summary>
503         /// Gets or sets the color of the thumb image object.
504         /// </summary>
505         /// <since_tizen> 8 </since_tizen>
506         public Color ThumbColor
507         {
508             get
509             {
510                 return thumbImage?.Color;
511             }
512             set
513             {
514                 if (null != thumbImage)
515                 {
516                     thumbImage.Color = value;
517                     sliderStyle.Thumb.Color = value;
518                 }
519             }
520         }
521
522         /// <summary>
523         /// Gets or sets the color of the background track image object.
524         /// </summary>
525         /// <since_tizen> 6 </since_tizen>
526         public Color BgTrackColor
527         {
528             get
529             {
530                 return bgTrackImage?.BackgroundColor;
531             }
532             set
533             {
534                 if (null != bgTrackImage)
535                 {
536                     bgTrackImage.BackgroundColor = value;
537                     sliderStyle.Track.BackgroundColor = value;
538                 }
539             }
540         }
541
542         /// <summary>
543         /// Gets or sets the color of the slided track image object.
544         /// </summary>
545         /// <since_tizen> 6 </since_tizen>
546         public Color SlidedTrackColor
547         {
548             get
549             {
550                 return slidedTrackImage?.BackgroundColor;
551             }
552             set
553             {
554                 if (null != slidedTrackImage)
555                 {
556                     slidedTrackImage.BackgroundColor = value;
557                     sliderStyle.Progress.BackgroundColor = value;
558                 }
559             }
560         }
561
562         /// <summary>
563         /// Gets or sets the thickness value of the track.
564         /// </summary>
565         /// <since_tizen> 6 </since_tizen>
566         public uint TrackThickness
567         {
568             get
569             {
570                 return (uint)GetValue(TrackThicknessProperty);
571             }
572             set
573             {
574                 SetValue(TrackThicknessProperty, value);
575             }
576         }
577
578         /// <summary>
579         /// Gets or sets the resource url of the low indicator image object.
580         /// </summary>
581         /// <since_tizen> 6 </since_tizen>
582         public string LowIndicatorImageURL
583         {
584             get
585             {
586                 return lowIndicatorImage?.ResourceUrl;
587             }
588             set
589             {
590                 if (null == lowIndicatorImage) lowIndicatorImage = new ImageView();
591                 lowIndicatorImage.ResourceUrl = value;
592                 sliderStyle.LowIndicatorImage.ResourceUrl = value;
593             }
594         }
595
596         /// <summary>
597         /// Gets or sets the resource url of the high indicator image object.
598         /// </summary>
599         /// <since_tizen> 6 </since_tizen>
600         public string HighIndicatorImageURL
601         {
602             get
603             {
604                 return highIndicatorImage?.ResourceUrl;
605             }
606             set
607             {
608                 if (null == highIndicatorImage) highIndicatorImage = new ImageView();
609                 highIndicatorImage.ResourceUrl = value;
610                 sliderStyle.HighIndicatorImage.ResourceUrl = value;
611             }
612         }
613
614         /// <summary>
615         /// Gets or sets the text content of the low indicator text object.
616         /// </summary>
617         /// <since_tizen> 6 </since_tizen>
618         public string LowIndicatorTextContent
619         {
620             get
621             {
622                 return lowIndicatorText?.Text;
623             }
624             set
625             {
626                 if (null != lowIndicatorText)
627                 {
628                     lowIndicatorText.Text = value;
629                     sliderStyle.LowIndicator.Text = value;
630                 }
631             }
632         }
633
634         /// <summary>
635         /// Gets or sets the text content of the high indicator text object.
636         /// </summary>
637         /// <since_tizen> 6 </since_tizen>
638         public string HighIndicatorTextContent
639         {
640             get
641             {
642                 return highIndicatorText?.Text;
643             }
644             set
645             {
646                 if (null != highIndicatorText)
647                 {
648                     highIndicatorText.Text = value;
649                     sliderStyle.HighIndicator.Text = value;
650                 }
651             }
652         }
653
654         /// <summary>
655         /// Gets or sets the size of the low indicator object(image or text).
656         /// </summary>
657         /// <since_tizen> 6 </since_tizen>
658         public Size LowIndicatorSize
659         {
660             get
661             {
662                 return lowIndicatorSize;
663             }
664             set
665             {
666                 lowIndicatorSize = value;
667                 UpdateLowIndicatorSize();
668                 UpdateBgTrackSize();
669                 UpdateBgTrackPosition();
670                 UpdateValue();
671             }
672         }
673
674         /// <summary>
675         /// Gets or sets the size of the high indicator object(image or text).
676         /// </summary>
677         /// <since_tizen> 6 </since_tizen>
678         public Size HighIndicatorSize
679         {
680             get
681             {
682                 return highIndicatorText?.Size;
683             }
684             set
685             {
686                 if (null != highIndicatorText)
687                 {
688                     highIndicatorText.Size = value;
689                     sliderStyle.HighIndicator.Size = value;
690                 }
691             }
692         }
693
694         /// <summary>
695         /// Gets or sets the value of the space between track and indicator.
696         /// </summary>
697         /// <since_tizen> 6 </since_tizen>
698         public uint SpaceBetweenTrackAndIndicator
699         {
700             get
701             {
702                 return (uint)GetValue(SpaceBetweenTrackAndIndicatorProperty);
703             }
704             set
705             {
706                 SetValue(SpaceBetweenTrackAndIndicatorProperty, value);
707             }
708         }
709
710         /// <summary>
711         /// Flag to decide whether the value indicator is shown
712         /// </summary>
713         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
714         [EditorBrowsable(EditorBrowsableState.Never)]
715         public bool IsValueShown
716         {
717             get
718             {
719                 return (bool)GetValue(IsValueShownProperty);
720             }
721             set
722             {
723                 SetValue(IsValueShownProperty, value);
724             }
725         }
726
727         /// <summary>
728         /// Gets or sets the text of value indicator.
729         /// </summary>
730         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
731         [EditorBrowsable(EditorBrowsableState.Never)]
732         public string ValueIndicatorText
733         {
734             get
735             {
736                 return (string)GetValue(ValueIndicatorTextProperty);
737             }
738             set
739             {
740                 SetValue(ValueIndicatorTextProperty, value);
741             }
742         }
743
744         /// <summary>
745         /// Gets or sets the size of the value indicator image object.
746         /// </summary>
747         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
748         [EditorBrowsable(EditorBrowsableState.Never)]
749         public Size ValueIndicatorSize
750         {
751             get
752             {
753                 return valueIndicatorImage?.Size;
754             }
755             set
756             {
757                 if (null != valueIndicatorImage)
758                 {
759                     valueIndicatorImage.Size = value;
760                     sliderStyle.ValueIndicatorImage.Size = value;
761                 }
762             }
763         }
764
765         /// <summary>
766         /// Gets or sets the resource url of the value indicator image object.
767         /// </summary>
768         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
769         [EditorBrowsable(EditorBrowsableState.Never)]
770         public string ValueIndicatorUrl
771         {
772             get
773             {
774                 return valueIndicatorImage?.ResourceUrl;
775             }
776             set
777             {
778                 if (null != valueIndicatorImage)
779                 {
780                     valueIndicatorImage.ResourceUrl = value;
781                     sliderStyle.ValueIndicatorImage.ResourceUrl = value;
782                 }
783             }
784         }
785
786         private Extents spaceBetweenTrackAndIndicator
787         {
788             get
789             {
790                 if (null == _spaceBetweenTrackAndIndicator)
791                 {
792                     _spaceBetweenTrackAndIndicator = new Extents((ushort start, ushort end, ushort top, ushort bottom) =>
793                     {
794                         Extents extents = new Extents(start, end, top, bottom);
795                         _spaceBetweenTrackAndIndicator.CopyFrom(extents);
796                     }, 0, 0, 0, 0);
797                 }
798
799                 return _spaceBetweenTrackAndIndicator;
800             }
801         }
802
803         private IndicatorType privateIndicatorType
804         {
805             get
806             {
807                 return indicatorType;
808             }
809             set
810             {
811                 if (indicatorType == value)
812                 {
813                     return;
814                 }
815                 indicatorType = value;
816                 RelayoutBaseComponent(false);
817                 UpdateBgTrackSize();
818                 UpdateBgTrackPosition();
819                 UpdateValue();
820             }
821         }
822
823         private uint privateTrackThickness
824         {
825             get
826             {
827                 return trackThickness ?? 0;
828             }
829             set
830             {
831                 trackThickness = value;
832                 if (bgTrackImage != null)
833                 {
834                     if (direction == DirectionType.Horizontal)
835                     {
836                         bgTrackImage.SizeHeight = (float)trackThickness.Value;
837                     }
838                     else if (direction == DirectionType.Vertical)
839                     {
840                         bgTrackImage.SizeWidth = (float)trackThickness.Value;
841                     }
842                 }
843                 if (slidedTrackImage != null)
844                 {
845                     if (direction == DirectionType.Horizontal)
846                     {
847                         slidedTrackImage.SizeHeight = (float)trackThickness.Value;
848                     }
849                     else if (direction == DirectionType.Vertical)
850                     {
851                         slidedTrackImage.SizeWidth = (float)trackThickness.Value;
852                     }
853                 }
854             }
855         }
856
857         private uint privateSpaceBetweenTrackAndIndicator
858         {
859             get
860             {
861                 return privateTrackPadding.Start;
862             }
863             set
864             {
865                 ushort val = (ushort)value;
866                 privateTrackPadding = new Extents(val, val, val, val);
867             }
868         }
869
870         private Extents privateTrackPadding
871         {
872             get
873             {
874                 return spaceBetweenTrackAndIndicator;
875             }
876             set
877             {
878                 spaceBetweenTrackAndIndicator.CopyFrom(value);
879                 UpdateComponentByIndicatorTypeChanged();
880                 UpdateBgTrackSize();
881                 UpdateBgTrackPosition();
882                 UpdateValue();
883             }
884         }
885
886         /// <summary>
887         /// Focus gained callback.
888         /// </summary>
889         /// <since_tizen> 8 </since_tizen>
890         public override void OnFocusGained()
891         {
892             //State = ControlStates.Focused;
893             UpdateState(true, isPressed);
894             base.OnFocusGained();
895         }
896
897         /// <summary>
898         /// Focus Lost callback.
899         /// </summary>
900         /// <since_tizen> 8 </since_tizen>
901         public override void OnFocusLost()
902         {
903             //State = ControlStates.Normal;
904             UpdateState(false, isPressed);
905             base.OnFocusLost();
906         }
907
908         /// <summary>
909         /// Apply style to scrollbar.
910         /// </summary>
911         /// <param name="viewStyle">The style to apply.</param>
912         /// <since_tizen> 8 </since_tizen>
913         public override void ApplyStyle(ViewStyle viewStyle)
914         {
915             base.ApplyStyle(viewStyle);
916
917             SliderStyle sliderStyle = viewStyle as SliderStyle;
918
919             if (null != sliderStyle?.Progress)
920             {
921                 CreateSlidedTrack().ApplyStyle(sliderStyle.Progress);
922             }
923
924             if (null != sliderStyle?.LowIndicator)
925             {
926                 CreateLowIndicatorText().ApplyStyle(sliderStyle.LowIndicator);
927             }
928
929             if (null != sliderStyle?.HighIndicator)
930             {
931                 CreateHighIndicatorText().ApplyStyle(sliderStyle.HighIndicator);
932             }
933
934             if (null != sliderStyle?.Track)
935             {
936                 CreateBackgroundTrack().ApplyStyle(sliderStyle.Track);
937             }
938
939             if (null != sliderStyle?.Thumb)
940             {
941                 CreateThumb().ApplyStyle(sliderStyle.Thumb);
942             }
943
944             if (null != sliderStyle?.ValueIndicatorText)
945             {
946                 CreateValueIndicatorText().ApplyStyle(sliderStyle.ValueIndicatorText);
947             }
948
949             if (null != sliderStyle?.ValueIndicatorImage)
950             {
951                 CreateValueIndicator().ApplyStyle(sliderStyle.ValueIndicatorImage);
952             }
953
954             EnableControlStatePropagation = true;
955         }
956
957         /// <summary>
958         /// Get Slider style.
959         /// </summary>
960         /// <returns>The default slider style.</returns>
961         /// <since_tizen> 8 </since_tizen>
962         protected override ViewStyle CreateViewStyle()
963         {
964             return new SliderStyle();
965         }
966
967         /// <summary>
968         /// Dispose Slider.
969         /// </summary>
970         /// <param name="type">Dispose type.</param>
971         /// <since_tizen> 6 </since_tizen>
972         protected override void Dispose(DisposeTypes type)
973         {
974             if (disposed)
975             {
976                 return;
977             }
978
979             if (type == DisposeTypes.Explicit)
980             {
981                 if (null != panGestureDetector)
982                 {
983                     panGestureDetector.Detach(this);
984                     panGestureDetector.Detected -= OnPanGestureDetected;
985                     panGestureDetector.Dispose();
986                     panGestureDetector = null;
987                 }
988
989                 if (null != thumbImage)
990                 {
991                     thumbImage.TouchEvent -= OnTouchEventForThumb;
992                     Utility.Dispose(thumbImage);
993                 }
994                 Utility.Dispose(slidedTrackImage);
995                 if (null != bgTrackImage)
996                 {
997                     bgTrackImage.TouchEvent -= OnTouchEventForBgTrack;
998                     Utility.Dispose(bgTrackImage);
999                 }
1000                 Utility.Dispose(lowIndicatorImage);
1001                 Utility.Dispose(highIndicatorImage);
1002                 Utility.Dispose(lowIndicatorText);
1003                 Utility.Dispose(highIndicatorText);
1004                 Utility.Dispose(valueIndicatorImage);
1005                 Utility.Dispose(valueIndicatorText);
1006             }
1007
1008             base.Dispose(type);
1009         }
1010
1011         /// <summary>
1012         /// Update Slider by style.
1013         /// </summary>
1014         /// <since_tizen> 6 </since_tizen>
1015         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
1016         [EditorBrowsable(EditorBrowsableState.Never)]
1017         protected override void OnUpdate()
1018         {
1019             RelayoutBaseComponent();
1020
1021             UpdateComponentByIndicatorTypeChanged();
1022             UpdateBgTrackSize();
1023             UpdateBgTrackPosition();
1024             UpdateLowIndicatorSize();
1025             UpdateValue();
1026         }
1027
1028         private void CalculateCurrentValueByGesture(float offset)
1029         {
1030             currentSlidedOffset += offset;
1031
1032             if (currentSlidedOffset <= 0)
1033             {
1034                 curValue = minValue;
1035             }
1036             else if (currentSlidedOffset >= BgTrackLength())
1037             {
1038                 curValue = maxValue;
1039             }
1040             else
1041             {
1042                 int bgTrackLength = BgTrackLength();
1043                 if (bgTrackLength != 0)
1044                 {
1045                     curValue = ((currentSlidedOffset / (float)bgTrackLength) * (float)(maxValue - minValue)) + minValue;
1046                 }
1047             }
1048             if (valueChangedHandler != null)
1049             {
1050                 ValueChangedArgs args = new ValueChangedArgs();
1051                 args.CurrentValue = curValue;
1052                 valueChangedHandler(this, args);
1053             }
1054
1055             if (sliderValueChangedHandler != null)
1056             {
1057                 SliderValueChangedEventArgs args = new SliderValueChangedEventArgs();
1058                 args.CurrentValue = curValue;
1059                 sliderValueChangedHandler(this, args);
1060             }
1061         }
1062
1063         private bool OnTouchEventForBgTrack(object source, TouchEventArgs e)
1064         {
1065             PointStateType state = e.Touch.GetState(0);
1066             if (state == PointStateType.Down)
1067             {
1068                 if (isValueShown)
1069                 {
1070                     valueIndicatorImage.Show();
1071                 }
1072
1073                 Vector2 pos = e.Touch.GetLocalPosition(0);
1074                 CalculateCurrentValueByTouch(pos);
1075                 UpdateValue();
1076                 if (null != slidingFinishedHandler)
1077                 {
1078                     SlidingFinishedArgs args = new SlidingFinishedArgs();
1079                     args.CurrentValue = curValue;
1080                     slidingFinishedHandler(this, args);
1081                 }
1082
1083                 if (null != sliderSlidingFinishedHandler)
1084                 {
1085                     SliderSlidingFinishedEventArgs args = new SliderSlidingFinishedEventArgs();
1086                     args.CurrentValue = curValue;
1087                     sliderSlidingFinishedHandler(this, args);
1088                 }
1089             }
1090             else if (state == PointStateType.Up)
1091             {
1092                 if (isValueShown)
1093                 {
1094                     valueIndicatorImage.Hide();
1095                 }
1096             }
1097             return false;
1098         }
1099
1100         private bool OnTouchEventForThumb(object source, TouchEventArgs e)
1101         {
1102             PointStateType state = e.Touch.GetState(0);
1103             if (state == PointStateType.Down)
1104             {
1105                 UpdateState(isFocused, true);
1106             }
1107             else if (state == PointStateType.Up)
1108             {
1109                 UpdateState(isFocused, false);
1110             }
1111             return true;
1112         }
1113
1114         private void CalculateCurrentValueByTouch(Vector2 pos)
1115         {
1116             int bgTrackLength = BgTrackLength();
1117             if (direction == DirectionType.Horizontal)
1118             {
1119                 currentSlidedOffset = pos.X;
1120             }
1121             else if (direction == DirectionType.Vertical)
1122             {
1123                 currentSlidedOffset = bgTrackLength - pos.Y;
1124             }
1125
1126             if (bgTrackLength != 0)
1127             {
1128                 curValue = ((currentSlidedOffset / (float)bgTrackLength) * (maxValue - minValue)) + minValue;
1129                 if (null != valueChangedHandler)
1130                 {
1131                     ValueChangedArgs args = new ValueChangedArgs();
1132                     args.CurrentValue = curValue;
1133                     valueChangedHandler(this, args);
1134                 }
1135
1136                 if (null != sliderValueChangedHandler)
1137                 {
1138                     SliderValueChangedEventArgs args = new SliderValueChangedEventArgs();
1139                     args.CurrentValue = curValue;
1140                     sliderValueChangedHandler(this, args);
1141                 }
1142             }
1143         }
1144
1145         private void UpdateState(bool isFocusedNew, bool isPressedNew)
1146         {
1147             if (isFocused == isFocusedNew && isPressed == isPressedNew)
1148             {
1149                 return;
1150             }
1151             if (thumbImage == null || Style == null)
1152             {
1153                 return;
1154             }
1155             isFocused = isFocusedNew;
1156             isPressed = isPressedNew;
1157
1158             if (!isFocused && !isPressed)
1159             {
1160                 ControlState = ControlState.Normal;
1161                 if (stateChangedHandler != null)
1162                 {
1163                     StateChangedArgs args = new StateChangedArgs();
1164                     args.CurrentState = (ControlStates)ControlStates.Normal;
1165                     stateChangedHandler(this, args);
1166                 }
1167             }
1168             else if (isPressed)
1169             {
1170                 ControlState = ControlState.Pressed;
1171
1172                 if (stateChangedHandler != null)
1173                 {
1174                     StateChangedArgs args = new StateChangedArgs();
1175                     args.CurrentState = (ControlStates)ControlStates.Pressed;
1176                     stateChangedHandler(this, args);
1177                 }
1178             }
1179             else if (!isPressed && isFocused)
1180             {
1181                 ControlState = ControlState.Focused;
1182
1183                 if (stateChangedHandler != null)
1184                 {
1185                     StateChangedArgs args = new StateChangedArgs();
1186                     args.CurrentState = (ControlStates)ControlStates.Focused;
1187                     stateChangedHandler(this, args);
1188                 }
1189             }
1190         }
1191
1192         private void UpdateComponentByIndicatorTypeChanged()
1193         {
1194             IndicatorType type = CurrentIndicatorType();
1195             if (type == IndicatorType.None)
1196             {
1197                 if (lowIndicatorImage != null)
1198                 {
1199                     lowIndicatorImage.Hide();
1200                 }
1201                 if (highIndicatorImage != null)
1202                 {
1203                     highIndicatorImage.Hide();
1204                 }
1205                 if (lowIndicatorText != null)
1206                 {
1207                     lowIndicatorText.Hide();
1208                 }
1209                 if (highIndicatorText != null)
1210                 {
1211                     highIndicatorText.Hide();
1212                 }
1213             }
1214             else if (type == IndicatorType.Image)
1215             {
1216                 if (lowIndicatorImage != null)
1217                 {
1218                     lowIndicatorImage.Show();
1219                 }
1220                 if (highIndicatorImage != null)
1221                 {
1222                     highIndicatorImage.Show();
1223                 }
1224                 if (lowIndicatorText != null)
1225                 {
1226                     lowIndicatorText.Hide();
1227                 }
1228                 if (highIndicatorText != null)
1229                 {
1230                     highIndicatorText.Hide();
1231                 }
1232             }
1233             else if (type == IndicatorType.Text)
1234             {
1235                 if (lowIndicatorText != null)
1236                 {
1237                     lowIndicatorText.Show();
1238                 }
1239                 if (highIndicatorText != null)
1240                 {
1241                     highIndicatorText.Show();
1242                 }
1243                 if (lowIndicatorImage != null)
1244                 {
1245                     lowIndicatorImage.Hide();
1246                 }
1247                 if (highIndicatorImage != null)
1248                 {
1249                     highIndicatorImage.Hide();
1250                 }
1251             }
1252         }
1253
1254         /// <summary>
1255         /// Value Changed event data.
1256         /// </summary>
1257         /// <since_tizen> 6 </since_tizen>
1258         [Obsolete("Deprecated in API8; Will be removed in API10. Please use SliderValueChangedEventArgs instead.")]
1259         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
1260         public class ValueChangedArgs : EventArgs
1261         {
1262             /// <summary>
1263             /// Curren value
1264             /// </summary>
1265             /// <since_tizen> 6 </since_tizen>
1266             /// It will be removed in API10
1267             [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
1268             [Obsolete("Deprecated in API8; Will be removed in API10. Please use SliderValueChangedEventArgs.CurrentValue instead.")]
1269             public float CurrentValue;
1270         }
1271
1272         /// <summary>
1273         /// Value Changed event data.
1274         /// </summary>
1275         /// <since_tizen> 6 </since_tizen>
1276         [Obsolete("Deprecated in API8; Will be removed in API10. Please use SliderSlidingFinishedEventArgs instead.")]
1277         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
1278         public class SlidingFinishedArgs : EventArgs
1279         {
1280             /// <summary>
1281             /// Curren value
1282             /// </summary>
1283             /// <since_tizen> 6 </since_tizen>
1284             /// It will be removed in API10
1285             [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
1286             [Obsolete("Deprecated in API8; Will be removed in API10. Please use SliderSlidingFinishedEventArgs.CurrentValue instead.")]
1287             public float CurrentValue;
1288         }
1289
1290         /// <summary>
1291         /// State Changed event data.
1292         /// </summary>
1293         /// <since_tizen> 6 </since_tizen>
1294         [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")]
1295         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
1296         public class StateChangedArgs : EventArgs
1297         {
1298             /// <summary>
1299             /// Curent state
1300             /// </summary>
1301             /// <since_tizen> 6 </since_tizen>
1302             /// It will be removed in API10
1303             [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
1304             [Obsolete("Deprecated in API8; Will be removed in API10")]
1305             public ControlStates CurrentState;
1306         }
1307     }
1308 }