bcf477fe6c2afb32228dc2a8aa26240cc22a3038
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Slider.Internal.cs
1 /*
2  * Copyright(c) 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 using System;
19 using System.ComponentModel;
20 using Tizen.NUI.BaseComponents;
21
22 namespace Tizen.NUI.Components
23 {
24     public partial class Slider
25     {
26         // the background track image object
27         private ImageView bgTrackImage = null;
28         // the slided track image object
29         private ImageView slidedTrackImage = null;
30         // the warning track image object
31         private ImageView warningTrackImage = null;
32         // the warning slided track image object
33         private ImageView warningSlidedTrackImage = null;
34         // the thumb image object
35         private ImageView thumbImage = null;
36         // the low indicator image object
37         private ImageView lowIndicatorImage = null;
38         // the high indicator image object
39         private ImageView highIndicatorImage = null;
40         // the low indicator text object
41         private TextLabel lowIndicatorText = null;
42         // the high indicator text object
43         private TextLabel highIndicatorText = null;
44         // the direction type
45         private DirectionType direction = DirectionType.Horizontal;
46         // the indicator type
47         private IndicatorType indicatorType = IndicatorType.None;
48         private const float round = 0.5f;
49         // the minimum value
50         private float minValue = 0;
51         // the maximum value
52         private float maxValue = 100;
53         // the current value
54         private float curValue = 0;
55         // the warning start value
56         private float warningStartValue = 100;
57         // the size of the low indicator
58         private Size lowIndicatorSize = null;
59         // the size of the high indicator
60         private Size highIndicatorSize = null;
61         // the track thickness value
62         private uint? trackThickness = null;
63         // the value of the space between track and indicator object
64         private Extents spaceTrackIndicator = null;
65         // Whether the value indicator is shown or not
66         private bool isValueShown = false;
67         // the value indicator text
68         private TextLabel valueIndicatorText = null;
69         // the value indicator image object
70         private ImageView valueIndicatorImage = null;
71
72         // To store the thumb size of normal state
73         private Size thumbSize = null;
74         // To store the thumb image url of normal state
75         private string thumbImageUrl = null;
76         // To store the thumb color of normal state
77         private Color thumbColor = Color.White;
78         // To store the thumb image url of warning state
79         private string warningThumbImageUrl = null;
80         // To store the thumb image url selector of warning state
81         private Selector<string> warningThumbImageUrlSelector = null;
82         // To store the thumb color of warning state
83         private Color warningThumbColor = null;
84         // the discrete value
85         private float discreteValue = 0;
86
87         private PanGestureDetector panGestureDetector = null;
88         private float currentSlidedOffset;
89         private EventHandler<SliderValueChangedEventArgs> sliderValueChangedHandler;
90         private EventHandler<SliderSlidingStartedEventArgs> sliderSlidingStartedHandler;
91         private EventHandler<SliderSlidingFinishedEventArgs> sliderSlidingFinishedHandler;
92
93         bool isFocused = false;
94         bool isPressed = false;
95
96         private void Initialize()
97         {
98             AccessibilityHighlightable = true;
99
100             currentSlidedOffset = 0;
101             isFocused = false;
102             isPressed = false;
103             LayoutDirectionChanged += OnLayoutDirectionChanged;
104
105             this.TouchEvent += OnTouchEventForTrack;
106             this.GrabTouchAfterLeave = true;
107
108             panGestureDetector = new PanGestureDetector();
109             panGestureDetector.Attach(this);
110             panGestureDetector.Detected += OnPanGestureDetected;
111
112             this.Layout = new LinearLayout()
113             {
114                 LinearOrientation = LinearLayout.Orientation.Horizontal,
115             };
116         }
117
118         private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
119         {
120             RelayoutRequest();
121         }
122
123         private ImageView CreateSlidedTrack()
124         {
125             if (null == slidedTrackImage)
126             {
127                 slidedTrackImage = new ImageView()
128                 {
129                     WidthResizePolicy = ResizePolicyType.Fixed,
130                     HeightResizePolicy = ResizePolicyType.Fixed,
131                     AccessibilityHidden = true,
132                 };
133
134                 if (bgTrackImage != null)
135                 {
136                     bgTrackImage.Add(slidedTrackImage);
137                 }
138             }
139
140             return slidedTrackImage;
141         }
142
143         private ImageView CreateWarningTrack()
144         {
145             if (null == warningTrackImage)
146             {
147                 warningTrackImage = new ImageView()
148                 {
149                     WidthResizePolicy = ResizePolicyType.Fixed,
150                     HeightResizePolicy = ResizePolicyType.Fixed,
151                     AccessibilityHidden = true,
152                 };
153
154                 if (bgTrackImage != null)
155                 {
156                     bgTrackImage.Add(warningTrackImage);
157                 }
158
159                 if (warningSlidedTrackImage != null)
160                 {
161                     warningTrackImage.Add(warningSlidedTrackImage);
162                 }
163
164                 if (slidedTrackImage != null)
165                 {
166                     warningTrackImage.RaiseAbove(slidedTrackImage);
167                 }
168             }
169
170             return warningTrackImage;
171         }
172
173         private ImageView CreateWarningSlidedTrack()
174         {
175             if (null == warningSlidedTrackImage)
176             {
177                 warningSlidedTrackImage = new ImageView()
178                 {
179                     WidthResizePolicy = ResizePolicyType.Fixed,
180                     HeightResizePolicy = ResizePolicyType.Fixed,
181                     AccessibilityHidden = true,
182                 };
183
184                 if (warningTrackImage != null)
185                 {
186                     warningTrackImage.Add(warningSlidedTrackImage);
187                 }
188             }
189
190             return warningSlidedTrackImage;
191         }
192
193         private TextLabel CreateLowIndicatorText()
194         {
195             if (null == lowIndicatorText)
196             {
197                 lowIndicatorText = new TextLabel()
198                 {
199                     WidthResizePolicy = ResizePolicyType.Fixed,
200                     HeightResizePolicy = ResizePolicyType.Fixed,
201                     AccessibilityHidden = true,
202                 };
203                 this.Add(lowIndicatorText);
204             }
205
206             return lowIndicatorText;
207         }
208
209         private TextLabel CreateHighIndicatorText()
210         {
211             if (null == highIndicatorText)
212             {
213                 highIndicatorText = new TextLabel()
214                 {
215                     WidthResizePolicy = ResizePolicyType.Fixed,
216                     HeightResizePolicy = ResizePolicyType.Fixed,
217                     AccessibilityHidden = true,
218                 };
219                 this.Add(highIndicatorText);
220             }
221
222             return highIndicatorText;
223         }
224
225         private ImageView CreateLowIndicatorImage()
226         {
227             if (lowIndicatorImage == null)
228             {
229                 lowIndicatorImage = new ImageView()
230                 {
231                     WidthResizePolicy = ResizePolicyType.Fixed,
232                     HeightResizePolicy = ResizePolicyType.Fixed,
233                     AccessibilityHidden = true,
234                 };
235                 this.Add(lowIndicatorImage);
236             }
237
238             return lowIndicatorImage;
239         }
240
241         private ImageView CreateHighIndicatorImage()
242         {
243             if (highIndicatorImage == null)
244             {
245                 highIndicatorImage = new ImageView()
246                 {
247                     WidthResizePolicy = ResizePolicyType.Fixed,
248                     HeightResizePolicy = ResizePolicyType.Fixed,
249                                         AccessibilityHidden = true,
250                 };
251                 this.Add(highIndicatorImage);
252             }
253
254             return highIndicatorImage;
255         }
256
257
258
259         private ImageView CreateBackgroundTrack()
260         {
261             if (null == bgTrackImage)
262             {
263                 bgTrackImage = new ImageView()
264                 {
265                     WidthResizePolicy = ResizePolicyType.Fixed,
266                     HeightResizePolicy = ResizePolicyType.Fixed,
267                     ParentOrigin = Tizen.NUI.ParentOrigin.Center,
268                     PivotPoint = Tizen.NUI.PivotPoint.Center,
269                     PositionUsesPivotPoint = true,
270                     GrabTouchAfterLeave = true,
271                     AccessibilityHidden = true,
272                 };
273                 this.Add(bgTrackImage);
274
275                 if (null != slidedTrackImage)
276                 {
277                     bgTrackImage.Add(slidedTrackImage);
278                 }
279                 if (null != warningTrackImage)
280                 {
281                     bgTrackImage.Add(warningTrackImage);
282                 }
283                 if (null != thumbImage)
284                 {
285                     bgTrackImage.Add(thumbImage);
286                     thumbImage.RaiseToTop();
287                 }
288             }
289
290             return bgTrackImage;
291         }
292
293         private ImageView CreateThumb()
294         {
295             if (null == thumbImage)
296             {
297                 thumbImage = new ImageView()
298                 {
299                     WidthResizePolicy = ResizePolicyType.Fixed,
300                     HeightResizePolicy = ResizePolicyType.Fixed,
301                     ParentOrigin = NUI.ParentOrigin.Center,
302                     PivotPoint = NUI.PivotPoint.Center,
303                     PositionUsesPivotPoint = true,
304                     EnableControlState = true,
305                     GrabTouchAfterLeave = true,
306                     AccessibilityHidden = true,
307                 };
308                 if (bgTrackImage != null)
309                 {
310                     bgTrackImage.Add(thumbImage);
311                 }
312                 thumbImage.RaiseToTop();
313                 thumbImage.TouchEvent += OnTouchEventForThumb;
314             }
315
316             return thumbImage;
317         }
318
319         private ImageView CreateValueIndicatorImage()
320         {
321             if (valueIndicatorImage == null)
322             {
323                 valueIndicatorImage = new ImageView()
324                 {
325                     PositionUsesPivotPoint = true,
326                     ParentOrigin = Tizen.NUI.ParentOrigin.Center,
327                     PivotPoint = Tizen.NUI.PivotPoint.Center,
328                     WidthResizePolicy = ResizePolicyType.Fixed,
329                     HeightResizePolicy = ResizePolicyType.Fixed,
330                     AccessibilityHidden = true,
331                 };
332                 if (valueIndicatorText != null)
333                 {
334                     valueIndicatorImage.Add(valueIndicatorText);
335                 }
336                 // TODO : ValueIndicator can be a child of Thumb
337                 this.Add(valueIndicatorImage);
338             }
339
340             valueIndicatorImage.Hide();
341             return valueIndicatorImage;
342         }
343
344         private TextLabel CreateValueIndicatorText()
345         {
346             if (null == valueIndicatorText)
347             {
348                 valueIndicatorText = new TextLabel()
349                 {
350                     WidthResizePolicy = ResizePolicyType.Fixed,
351                     HeightResizePolicy = ResizePolicyType.Fixed,
352                     AccessibilityHidden = true,
353                 };
354                 if (valueIndicatorImage != null)
355                 {
356                     valueIndicatorImage.Add(valueIndicatorText);
357                 }
358             }
359
360             return valueIndicatorText;
361         }
362
363         private void OnPanGestureDetected(object source, PanGestureDetector.DetectedEventArgs e)
364         {
365             if (e.PanGesture.State == Gesture.StateType.Started)
366             {
367                 if (direction == DirectionType.Horizontal)
368                 {
369                     currentSlidedOffset = slidedTrackImage.SizeWidth;
370                 }
371                 else if (direction == DirectionType.Vertical)
372                 {
373                     currentSlidedOffset = slidedTrackImage.SizeHeight;
374                 }
375
376                 if (isValueShown)
377                 {
378                     valueIndicatorImage.Show();
379                 }
380
381                 if (null != sliderSlidingStartedHandler)
382                 {
383                     SliderSlidingStartedEventArgs args = new SliderSlidingStartedEventArgs();
384                     args.CurrentValue = curValue;
385                     sliderSlidingStartedHandler(this, args);
386                 }
387                 UpdateState(isFocused, true);
388             }
389
390             if (e.PanGesture.State == Gesture.StateType.Continuing || e.PanGesture.State == Gesture.StateType.Started)
391             {
392                 if (direction == DirectionType.Horizontal)
393                 {
394                     CalculateCurrentValueByGesture(e.PanGesture.Displacement.X);
395                 }
396                 else if (direction == DirectionType.Vertical)
397                 {
398                     CalculateCurrentValueByGesture(-e.PanGesture.Displacement.Y);
399                 }
400                 UpdateState(isFocused, true);
401                 UpdateValue();
402             }
403
404             if (e.PanGesture.State == Gesture.StateType.Finished)
405             {
406                 if (isValueShown)
407                 {
408                     valueIndicatorImage.Hide();
409                 }
410
411                 if (null != sliderSlidingFinishedHandler)
412                 {
413                     SliderSlidingFinishedEventArgs args = new SliderSlidingFinishedEventArgs();
414                     args.CurrentValue = curValue;
415                     sliderSlidingFinishedHandler(this, args);
416                 }
417
418                 UpdateState(isFocused, false);
419             }
420         }
421
422         // Relayout basic component: track, thumb and indicator
423         private void RelayoutBaseComponent(bool isInitial = true)
424         {
425             if (direction == DirectionType.Horizontal)
426             {
427                 if (slidedTrackImage != null)
428                 {
429                     slidedTrackImage.ParentOrigin = NUI.ParentOrigin.CenterLeft;
430                     slidedTrackImage.PivotPoint = NUI.PivotPoint.CenterLeft;
431                     slidedTrackImage.PositionUsesPivotPoint = true;
432                 }
433                 if (warningTrackImage != null)
434                 {
435                     warningTrackImage.ParentOrigin = NUI.ParentOrigin.CenterRight;
436                     warningTrackImage.PivotPoint = NUI.PivotPoint.CenterRight;
437                     warningTrackImage.PositionUsesPivotPoint = true;
438                 }
439                 if (warningSlidedTrackImage != null)
440                 {
441                     warningSlidedTrackImage.ParentOrigin = NUI.ParentOrigin.CenterLeft;
442                     warningSlidedTrackImage.PivotPoint = NUI.PivotPoint.CenterLeft;
443                     warningSlidedTrackImage.PositionUsesPivotPoint = true;
444                 }
445                 if (thumbImage != null)
446                 {
447                     thumbImage.ParentOrigin = NUI.ParentOrigin.CenterLeft;
448                     thumbImage.PivotPoint = NUI.PivotPoint.Center;
449                     thumbImage.PositionUsesPivotPoint = true;
450                 }
451                 if (lowIndicatorImage != null)
452                 {
453                     lowIndicatorImage.ParentOrigin = NUI.ParentOrigin.CenterLeft;
454                     lowIndicatorImage.PivotPoint = NUI.PivotPoint.CenterLeft;
455                     lowIndicatorImage.PositionUsesPivotPoint = true;
456                 }
457                 if (highIndicatorImage != null)
458                 {
459                     highIndicatorImage.ParentOrigin = NUI.ParentOrigin.CenterRight;
460                     highIndicatorImage.PivotPoint = NUI.PivotPoint.CenterRight;
461                     highIndicatorImage.PositionUsesPivotPoint = true;
462                 }
463                 if (lowIndicatorText != null)
464                 {
465                     lowIndicatorText.ParentOrigin = NUI.ParentOrigin.CenterLeft;
466                     lowIndicatorText.PivotPoint = NUI.PivotPoint.CenterLeft;
467                     lowIndicatorText.PositionUsesPivotPoint = true;
468                 }
469                 if (highIndicatorText != null)
470                 {
471                     highIndicatorText.ParentOrigin = NUI.ParentOrigin.CenterRight;
472                     highIndicatorText.PivotPoint = NUI.PivotPoint.CenterRight;
473                     highIndicatorText.PositionUsesPivotPoint = true;
474                 }
475                 if (valueIndicatorImage != null)
476                 {
477                     valueIndicatorImage.ParentOrigin = NUI.ParentOrigin.TopLeft;
478                     valueIndicatorImage.PivotPoint = NUI.PivotPoint.BottomCenter;
479                     valueIndicatorImage.PositionUsesPivotPoint = true;
480                 }
481                 if (valueIndicatorText != null)
482                 {
483                     valueIndicatorText.ParentOrigin = NUI.ParentOrigin.TopCenter;
484                     valueIndicatorText.PivotPoint = NUI.PivotPoint.TopCenter;
485                     valueIndicatorText.PositionUsesPivotPoint = true;
486                     valueIndicatorText.Padding = new Extents(0, 0, 5, 0); // TODO : How to set the text as center
487                 }
488                 if (panGestureDetector != null)
489                 {
490                     if (!isInitial)
491                     {
492                         panGestureDetector.RemoveDirection(PanGestureDetector.DirectionVertical);
493                     }
494                     panGestureDetector.AddDirection(PanGestureDetector.DirectionHorizontal);
495                 }
496             }
497             else if (direction == DirectionType.Vertical)
498             {
499                 if (slidedTrackImage != null)
500                 {
501                     slidedTrackImage.ParentOrigin = NUI.ParentOrigin.BottomCenter;
502                     slidedTrackImage.PivotPoint = NUI.PivotPoint.BottomCenter;
503                     slidedTrackImage.PositionUsesPivotPoint = true;
504                 }
505                 if (warningTrackImage != null)
506                 {
507                     warningTrackImage.ParentOrigin = NUI.ParentOrigin.TopCenter;
508                     warningTrackImage.PivotPoint = NUI.PivotPoint.TopCenter;
509                     warningTrackImage.PositionUsesPivotPoint = true;
510                 }
511                 if (warningSlidedTrackImage != null)
512                 {
513                     warningSlidedTrackImage.ParentOrigin = NUI.ParentOrigin.BottomCenter;
514                     warningSlidedTrackImage.PivotPoint = NUI.PivotPoint.BottomCenter;
515                     warningSlidedTrackImage.PositionUsesPivotPoint = true;
516                 }
517                 if (thumbImage != null)
518                 {
519                     thumbImage.ParentOrigin = NUI.ParentOrigin.BottomCenter;
520                     thumbImage.PivotPoint = NUI.PivotPoint.Center;
521                     thumbImage.PositionUsesPivotPoint = true;
522                 }
523                 if (lowIndicatorImage != null)
524                 {
525                     lowIndicatorImage.ParentOrigin = NUI.ParentOrigin.BottomCenter;
526                     lowIndicatorImage.PivotPoint = NUI.PivotPoint.BottomCenter;
527                     lowIndicatorImage.PositionUsesPivotPoint = true;
528                 }
529                 if (highIndicatorImage != null)
530                 {
531                     highIndicatorImage.ParentOrigin = NUI.ParentOrigin.TopCenter;
532                     highIndicatorImage.PivotPoint = NUI.PivotPoint.TopCenter;
533                     highIndicatorImage.PositionUsesPivotPoint = true;
534                 }
535                 if (lowIndicatorText != null)
536                 {
537                     lowIndicatorText.ParentOrigin = NUI.ParentOrigin.BottomCenter;
538                     lowIndicatorText.PivotPoint = NUI.PivotPoint.BottomCenter;
539                     lowIndicatorText.PositionUsesPivotPoint = true;
540                 }
541                 if (highIndicatorText != null)
542                 {
543                     highIndicatorText.ParentOrigin = NUI.ParentOrigin.TopCenter;
544                     highIndicatorText.PivotPoint = NUI.PivotPoint.TopCenter;
545                     highIndicatorText.PositionUsesPivotPoint = true;
546                 }
547                 if (valueIndicatorImage != null)
548                 {
549                     valueIndicatorImage.ParentOrigin = NUI.ParentOrigin.BottomCenter;
550                     valueIndicatorImage.PivotPoint = NUI.PivotPoint.BottomCenter;
551                     valueIndicatorImage.PositionUsesPivotPoint = true;
552                 }
553                 if (valueIndicatorText != null)
554                 {
555                     valueIndicatorText.ParentOrigin = NUI.ParentOrigin.TopCenter;
556                     valueIndicatorText.PivotPoint = NUI.PivotPoint.TopCenter;
557                     valueIndicatorText.PositionUsesPivotPoint = true;
558                     valueIndicatorText.Padding = new Extents(0, 0, 5, 0); // TODO : How to set the text as center
559                 }
560                 if (panGestureDetector != null)
561                 {
562                     if (!isInitial)
563                     {
564                         panGestureDetector.RemoveDirection(PanGestureDetector.DirectionHorizontal);
565                     }
566                     panGestureDetector.AddDirection(PanGestureDetector.DirectionVertical);
567                 }
568             }
569         }
570
571         private int BgTrackLength()
572         {
573             int bgTrackLength = 0;
574             IndicatorType type = CurrentIndicatorType();
575
576             if (type == IndicatorType.None)
577             {
578                 if (direction == DirectionType.Horizontal)
579                 {
580                     bgTrackLength = this.Size2D.Width - thumbImage.Size2D.Width;
581                 }
582                 else if (direction == DirectionType.Vertical)
583                 {
584                     bgTrackLength = this.Size2D.Height - thumbImage.Size2D.Height;
585                 }
586             }
587             else if (type == IndicatorType.Image)
588             {// <lowIndicatorImage> <spaceBetweenTrackAndIndicator> <bgTrack> <spaceBetweenTrackAndIndicator> <highIndicatorImage>
589                 Size lowIndicatorImageSize = LowIndicatorImageSize();
590                 Size highIndicatorImageSize = HighIndicatorImageSize();
591                 int curSpace = (int)CurrentSpaceBetweenTrackAndIndicator();
592                 if (direction == DirectionType.Horizontal)
593                 {
594                     int lowIndicatorSpace = ((lowIndicatorImageSize.Width == 0) ? (0) : ((int)(curSpace + lowIndicatorImageSize.Width)));
595                     int highIndicatorSpace = ((highIndicatorImageSize.Width == 0) ? (0) : ((int)(curSpace + highIndicatorImageSize.Width)));
596                     bgTrackLength = this.Size2D.Width - lowIndicatorSpace - highIndicatorSpace;
597                 }
598                 else if (direction == DirectionType.Vertical)
599                 {
600                     int lowIndicatorSpace = ((lowIndicatorImageSize.Height == 0) ? (0) : ((int)(curSpace + lowIndicatorImageSize.Height)));
601                     int highIndicatorSpace = ((highIndicatorImageSize.Height == 0) ? (0) : ((int)(curSpace + highIndicatorImageSize.Height)));
602                     bgTrackLength = this.Size2D.Height - lowIndicatorSpace - highIndicatorSpace;
603                 }
604             }
605             else if (type == IndicatorType.Text)
606             {// <lowIndicatorText> <spaceBetweenTrackAndIndicator> <bgTrack> <spaceBetweenTrackAndIndicator> <highIndicatorText>
607                 Size lowIndicatorTextSize = LowIndicatorTextSize();
608                 Size highIndicatorTextSize = HighIndicatorTextSize();
609                 int curSpace = (int)CurrentSpaceBetweenTrackAndIndicator();
610                 if (direction == DirectionType.Horizontal)
611                 {
612                     int lowIndicatorSpace = ((lowIndicatorTextSize.Width == 0) ? (0) : ((int)(curSpace + lowIndicatorTextSize.Width)));
613                     int highIndicatorSpace = ((highIndicatorTextSize.Width == 0) ? (0) : ((int)(curSpace + highIndicatorTextSize.Width)));
614                     bgTrackLength = this.Size2D.Width - lowIndicatorSpace - highIndicatorSpace;
615                 }
616                 else if (direction == DirectionType.Vertical)
617                 {
618                     int lowIndicatorSpace = ((lowIndicatorTextSize.Height == 0) ? (0) : ((int)(curSpace + lowIndicatorTextSize.Height)));
619                     int highIndicatorSpace = ((highIndicatorTextSize.Height == 0) ? (0) : ((int)(curSpace + highIndicatorTextSize.Height)));
620                     bgTrackLength = this.Size2D.Height - lowIndicatorSpace - highIndicatorSpace;
621                 }
622             }
623             return bgTrackLength;
624         }
625
626         private void UpdateLowIndicatorSize()
627         {
628             if (lowIndicatorSize != null)
629             {
630                 if (lowIndicatorImage != null)
631                 {
632                     lowIndicatorImage.Size = lowIndicatorSize;
633                 }
634                 if (lowIndicatorText != null)
635                 {
636                     lowIndicatorText.Size = lowIndicatorSize;
637                 }
638             }
639             else
640             {
641                 if (lowIndicatorImage != null && lowIndicatorImage != null && lowIndicatorImage.Size != null)
642                 {
643                     lowIndicatorImage.Size = lowIndicatorSize ?? (ViewStyle as SliderStyle)?.LowIndicatorImage.Size;
644                 }
645                 if (lowIndicatorText != null && lowIndicatorText != null && lowIndicatorText.Size != null)
646                 {
647                     lowIndicatorText.Size = lowIndicatorSize ?? (ViewStyle as SliderStyle)?.LowIndicator.Size;
648                 }
649             }
650         }
651
652         private void UpdateBgTrackSize()
653         {
654             if (bgTrackImage == null)
655             {
656                 return;
657             }
658             int curTrackThickness = (int)CurrentTrackThickness();
659             int bgTrackLength = BgTrackLength();
660             if (direction == DirectionType.Horizontal)
661             {
662                 bgTrackImage.Size2D = new Size2D(bgTrackLength, curTrackThickness);
663             }
664             else if (direction == DirectionType.Vertical)
665             {
666                 bgTrackImage.Size2D = new Size2D(curTrackThickness, bgTrackLength);
667             }
668         }
669
670         private void UpdateBgTrackPosition()
671         {
672             if (bgTrackImage == null)
673             {
674                 return;
675             }
676             IndicatorType type = CurrentIndicatorType();
677
678             if (type == IndicatorType.None)
679             {
680                 bgTrackImage.Position2D = new Position2D(0, 0);
681             }
682             else if (type == IndicatorType.Image)
683             {
684                 Size lowIndicatorImageSize = LowIndicatorImageSize();
685                 Size highIndicatorImageSize = HighIndicatorImageSize();
686                 int curSpace = (int)CurrentSpaceBetweenTrackAndIndicator();
687                 if (direction == DirectionType.Horizontal)
688                 {
689                     int lowIndicatorSpace = ((lowIndicatorImageSize.Width == 0) ? (0) : ((int)(curSpace + lowIndicatorImageSize.Width)));
690                     int highIndicatorSpace = ((highIndicatorImageSize.Width == 0) ? (0) : ((int)(curSpace + highIndicatorImageSize.Width)));
691                     bgTrackImage.Position2D = new Position2D(lowIndicatorSpace - (lowIndicatorSpace + highIndicatorSpace) / 2, 0);
692                 }
693                 else if (direction == DirectionType.Vertical)
694                 {
695                     int lowIndicatorSpace = ((lowIndicatorImageSize.Height == 0) ? (0) : ((int)(curSpace + lowIndicatorImageSize.Height)));
696                     int highIndicatorSpace = ((highIndicatorImageSize.Height == 0) ? (0) : ((int)(curSpace + highIndicatorImageSize.Height)));
697                     bgTrackImage.Position2D = new Position2D(0, lowIndicatorSpace - (lowIndicatorSpace + highIndicatorSpace) / 2);
698                 }
699             }
700             else if (type == IndicatorType.Text)
701             {
702                 Size lowIndicatorTextSize = LowIndicatorTextSize();
703                 Size highIndicatorTextSize = HighIndicatorTextSize();
704                 int curSpace = (int)CurrentSpaceBetweenTrackAndIndicator();
705                 if (direction == DirectionType.Horizontal)
706                 {
707                     int lowIndicatorSpace = ((lowIndicatorTextSize.Width == 0) ? (0) : ((int)(curSpace + lowIndicatorTextSize.Width)));
708                     int highIndicatorSpace = ((highIndicatorTextSize.Width == 0) ? (0) : ((int)(curSpace + highIndicatorTextSize.Width)));
709                     bgTrackImage.Position2D = new Position2D(lowIndicatorSpace - (lowIndicatorSpace + highIndicatorSpace) / 2, 0);
710                 }
711                 else if (direction == DirectionType.Vertical)
712                 {
713                     int lowIndicatorSpace = ((lowIndicatorTextSize.Height == 0) ? (0) : ((int)(curSpace + lowIndicatorTextSize.Height)));
714                     int highIndicatorSpace = ((highIndicatorTextSize.Height == 0) ? (0) : ((int)(curSpace + highIndicatorTextSize.Height)));
715                     bgTrackImage.Position2D = new Position2D(0, -(lowIndicatorSpace - (lowIndicatorSpace + highIndicatorSpace) / 2));
716                 }
717             }
718         }
719
720         private void UpdateValue()
721         {
722             if (slidedTrackImage == null)
723             {
724                 return;
725             }
726             if (curValue < minValue || curValue > maxValue || minValue >= maxValue)
727             {
728                 return;
729             }
730
731             float ratio = 0;
732             ratio = (float)(curValue - minValue) / (float)(maxValue - minValue);
733
734             uint curTrackThickness = CurrentTrackThickness();
735
736             if (direction == DirectionType.Horizontal)
737             {
738                 if (LayoutDirection == ViewLayoutDirectionType.RTL)
739                 {
740                     ratio = 1.0f - ratio;
741                 }
742                 float slidedTrackLength = (float)BgTrackLength() * ratio;
743                 slidedTrackImage.Size2D = new Size2D((int)(slidedTrackLength + round), (int)curTrackThickness); //Add const round to reach Math.Round function.
744                 thumbImage.Position = new Position(slidedTrackImage.Size2D.Width, 0);
745                 thumbImage.RaiseToTop();
746
747                 if (isValueShown)
748                 {
749                     valueIndicatorImage.Position = new Position(slidedTrackImage.Size2D.Width, 0);
750                 }
751             }
752             else if (direction == DirectionType.Vertical)
753             {
754                 float slidedTrackLength = (float)BgTrackLength() * ratio;
755                 slidedTrackImage.Size2D = new Size2D((int)curTrackThickness, (int)(slidedTrackLength + round)); //Add const round to reach Math.Round function.
756                 thumbImage.Position = new Position(0, -slidedTrackImage.Size2D.Height);
757                 thumbImage.RaiseToTop();
758
759                 if (isValueShown)
760                 {
761                     valueIndicatorImage.Position = new Position(0, -(slidedTrackImage.Size2D.Height + thumbImage.Size.Height / 2));
762                 }
763             }
764
765             // Update the track and thumb when the value is over warning value.
766             if (curValue >= warningStartValue)
767             {
768                 if (direction == DirectionType.Horizontal)
769                 {
770                     warningSlidedTrackImage.Size2D = new Size2D((int)(((curValue - warningStartValue) / 100) * this.Size2D.Width), (int)curTrackThickness);
771                 }
772                 else if (direction == DirectionType.Vertical)
773                 {
774                     warningSlidedTrackImage.Size2D = new Size2D((int)curTrackThickness, (int)(((curValue - warningStartValue) / 100) * this.Size2D.Height));
775                 }
776
777                 if (warningThumbColor != null && thumbImage.Color.NotEqualTo(warningThumbColor))
778                 {
779                     thumbImage.Color = warningThumbColor;
780                 }
781                 if (warningThumbImageUrl != null && !thumbImage.ResourceUrl.Equals(warningThumbImageUrl))
782                 {
783                     thumbImage.ResourceUrl = warningThumbImageUrl;
784                 }
785             }
786             else
787             {
788                 warningSlidedTrackImage.Size2D = new Size2D(0, 0);
789                 if (warningThumbColor != null && thumbImage.Color.EqualTo(warningThumbColor))
790                 {
791                     thumbImage.Color = thumbColor;
792                 }
793                 if (warningThumbImageUrl != null && thumbImage.ResourceUrl.Equals(warningThumbImageUrl))
794                 {
795                     thumbImage.ResourceUrl = thumbImageUrl;
796                 }
797             }
798         }
799
800         private uint CurrentTrackThickness()
801         {
802             uint curTrackThickness = 0;
803             if (trackThickness != null)
804             {
805                 curTrackThickness = trackThickness.Value;
806             }
807             else
808             {
809                 if (ViewStyle is SliderStyle sliderStyle && sliderStyle.TrackThickness != null)
810                 {
811                     curTrackThickness = sliderStyle.TrackThickness.Value;
812                 }
813             }
814             return curTrackThickness;
815         }
816
817         private uint CurrentSpaceBetweenTrackAndIndicator()
818         {
819             uint curSpace = 0;
820             if (spaceBetweenTrackAndIndicator != null)
821             {
822                 curSpace = spaceBetweenTrackAndIndicator.Start;
823             }
824             else
825             {
826                 if (ViewStyle is SliderStyle sliderStyle && sliderStyle.TrackPadding != null)
827                 {
828                     curSpace = sliderStyle.TrackPadding.Start;
829                 }
830             }
831             return curSpace;
832         }
833
834         private void UpdateWarningTrackSize()
835         {
836             if (warningTrackImage == null)
837             {
838                 return;
839             }
840
841             int curTrackThickness = (int)CurrentTrackThickness();
842             float warningTrackLength = maxValue - warningStartValue;
843             if (direction == DirectionType.Horizontal)
844             {
845                 warningTrackLength = (warningTrackLength / 100) * this.Size2D.Width;
846                 warningTrackImage.Size2D = new Size2D((int)warningTrackLength, curTrackThickness);
847             }
848             else if (direction == DirectionType.Vertical)
849             {
850                 warningTrackLength = (warningTrackLength / 100) * this.Size2D.Height;
851                 warningTrackImage.Size2D = new Size2D(curTrackThickness, (int)warningTrackLength);
852             }
853         }
854
855         private IndicatorType CurrentIndicatorType()
856         {
857             IndicatorType type = IndicatorType.None;
858             if (ViewStyle is SliderStyle sliderStyle)
859             {
860                 type = (IndicatorType)sliderStyle.IndicatorType;
861             }
862             return type;
863         }
864
865         private Size LowIndicatorImageSize()
866         {
867             Size size = new Size(0, 0);
868             if (lowIndicatorSize != null)
869             {
870                 size = lowIndicatorSize;
871             }
872             else
873             {
874                 if (ViewStyle is SliderStyle sliderStyle && sliderStyle.LowIndicatorImage != null && sliderStyle.LowIndicatorImage.Size != null)
875                 {
876                     size = sliderStyle.LowIndicatorImage.Size;
877                 }
878             }
879             return size;
880         }
881
882         private Size HighIndicatorImageSize()
883         {
884             Size size = new Size(0, 0);
885             if (highIndicatorSize != null)
886             {
887                 size = highIndicatorSize;
888             }
889             else
890             {
891                 if (ViewStyle is SliderStyle sliderStyle && sliderStyle.HighIndicatorImage != null && sliderStyle.HighIndicatorImage.Size != null)
892                 {
893                     size = sliderStyle.HighIndicatorImage.Size;
894                 }
895             }
896             return size;
897         }
898
899         private Size LowIndicatorTextSize()
900         {
901             Size size = new Size(0, 0);
902             if (lowIndicatorSize != null)
903             {
904                 size = lowIndicatorSize;
905             }
906             else
907             {
908                 if (ViewStyle is SliderStyle sliderStyle && sliderStyle.LowIndicator != null && sliderStyle.LowIndicator.Size != null)
909                 {
910                     size = sliderStyle.LowIndicator.Size;
911                 }
912             }
913             return size;
914         }
915
916         private Size HighIndicatorTextSize()
917         {
918             Size size = new Size(0, 0);
919             if (highIndicatorSize != null)
920             {
921                 size = highIndicatorSize;
922             }
923             else
924             {
925                 if (ViewStyle is SliderStyle sliderStyle && sliderStyle.HighIndicator != null && sliderStyle.HighIndicator.Size != null)
926                 {
927                     size = sliderStyle.HighIndicator.Size;
928                 }
929             }
930             return size;
931         }
932     }
933 }