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