[NUI] Slider track make correct value.
[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 GetBgTrackLength()
572         {
573             int bgTrackLength = 0;
574
575             int lowIndicatorOffset = GetBgTrackLowIndicatorOffset();
576             int highIndicatorOffet = GetBgTrackHighIndicatorOffset();
577
578             if (direction == DirectionType.Horizontal)
579             {
580                 bgTrackLength = this.Size2D.Width - lowIndicatorOffset - highIndicatorOffet;
581             }
582             else if (direction == DirectionType.Vertical)
583             {
584                 bgTrackLength = this.Size2D.Height - lowIndicatorOffset - highIndicatorOffet;
585             }
586
587             return bgTrackLength;
588         }
589
590         /// <summary>
591         /// Get offset value of bgtrack's low indicator side.
592         /// </summary>
593         private int GetBgTrackLowIndicatorOffset()
594         {
595             int bgTrackLowIndicatorOffset = 0;
596             IndicatorType type = CurrentIndicatorType();
597
598             if (type == IndicatorType.None)
599             {
600                 if (direction == DirectionType.Horizontal)
601                 {
602                     bgTrackLowIndicatorOffset = (int)(thumbImage.Size.Width * 0.5f);
603                 }
604                 else if (direction == DirectionType.Vertical)
605                 {
606                     bgTrackLowIndicatorOffset = (int)(thumbImage.Size.Height * 0.5f);
607                 }
608             }
609             else if (type == IndicatorType.Image || type == IndicatorType.Text)
610             {// <lowIndicatorImage or Text> <spaceBetweenTrackAndIndicator> <bgTrack>
611                 Size lowIndicatorSize = (type == IndicatorType.Image) ? LowIndicatorImageSize() : LowIndicatorTextSize();
612                 int curSpace = (int)CurrentSpaceBetweenTrackAndIndicator();
613                 if (direction == DirectionType.Horizontal)
614                 {
615                     bgTrackLowIndicatorOffset = ((lowIndicatorSize.Width == 0) ? (0) : ((int)(curSpace + lowIndicatorSize.Width)));
616                 }
617                 else if (direction == DirectionType.Vertical)
618                 {
619                     bgTrackLowIndicatorOffset = ((lowIndicatorSize.Height == 0) ? (0) : ((int)(curSpace + lowIndicatorSize.Height)));
620                 }
621             }
622             return bgTrackLowIndicatorOffset;
623         }
624
625         /// <summary>
626         /// Get offset value of bgtrack's high indicator side.
627         /// </summary>
628         private int GetBgTrackHighIndicatorOffset()
629         {
630             int bgTrackHighIndicatorOffset = 0;
631             IndicatorType type = CurrentIndicatorType();
632
633             if (type == IndicatorType.None)
634             {
635                 if (direction == DirectionType.Horizontal)
636                 {
637                     bgTrackHighIndicatorOffset = (int)(thumbImage.Size.Width * 0.5f);
638                 }
639                 else if (direction == DirectionType.Vertical)
640                 {
641                     bgTrackHighIndicatorOffset = (int)(thumbImage.Size.Height * 0.5f);
642                 }
643             }
644             else if (type == IndicatorType.Image || type == IndicatorType.Text)
645             {// <bgTrack> <spaceBetweenTrackAndIndicator> <highIndicatorImage or Text>
646                 Size highIndicatorSize = (type == IndicatorType.Image) ? HighIndicatorImageSize() : HighIndicatorTextSize();
647                 int curSpace = (int)CurrentSpaceBetweenTrackAndIndicator();
648                 if (direction == DirectionType.Horizontal)
649                 {
650                     bgTrackHighIndicatorOffset = ((highIndicatorSize.Width == 0) ? (0) : ((int)(curSpace + highIndicatorSize.Width)));
651                 }
652                 else if (direction == DirectionType.Vertical)
653                 {
654                     bgTrackHighIndicatorOffset = ((highIndicatorSize.Height == 0) ? (0) : ((int)(curSpace + highIndicatorSize.Height)));
655                 }
656             }
657             return bgTrackHighIndicatorOffset;
658         }
659
660         private void UpdateLowIndicatorSize()
661         {
662             if (lowIndicatorSize != null)
663             {
664                 if (lowIndicatorImage != null)
665                 {
666                     lowIndicatorImage.Size = lowIndicatorSize;
667                 }
668                 if (lowIndicatorText != null)
669                 {
670                     lowIndicatorText.Size = lowIndicatorSize;
671                 }
672             }
673             else
674             {
675                 if (lowIndicatorImage != null && lowIndicatorImage.Size != null)
676                 {
677                     lowIndicatorImage.Size = lowIndicatorSize ?? (ViewStyle as SliderStyle)?.LowIndicatorImage.Size;
678                 }
679                 if (lowIndicatorText != null && lowIndicatorText.Size != null)
680                 {
681                     lowIndicatorText.Size = lowIndicatorSize ?? (ViewStyle as SliderStyle)?.LowIndicator.Size;
682                 }
683             }
684         }
685
686         private void UpdateHighIndicatorSize()
687         {
688             if (highIndicatorSize != null)
689             {
690                 if (highIndicatorImage != null)
691                 {
692                     highIndicatorImage.Size = highIndicatorSize;
693                 }
694                 if (highIndicatorText != null)
695                 {
696                     highIndicatorText.Size = highIndicatorSize;
697                 }
698             }
699             else
700             {
701                 if (highIndicatorImage != null && highIndicatorImage.Size != null)
702                 {
703                     highIndicatorImage.Size = highIndicatorSize ?? (ViewStyle as SliderStyle)?.HighIndicatorImage.Size;
704                 }
705                 if (highIndicatorText != null && highIndicatorText.Size != null)
706                 {
707                     highIndicatorText.Size = highIndicatorSize ?? (ViewStyle as SliderStyle)?.HighIndicator.Size;
708                 }
709             }
710         }
711
712         private void UpdateBgTrackSize()
713         {
714             if (bgTrackImage == null)
715             {
716                 return;
717             }
718             int curTrackThickness = (int)CurrentTrackThickness();
719             int bgTrackLength = GetBgTrackLength();
720             if (direction == DirectionType.Horizontal)
721             {
722                 bgTrackImage.Size2D = new Size2D(bgTrackLength, curTrackThickness);
723             }
724             else if (direction == DirectionType.Vertical)
725             {
726                 bgTrackImage.Size2D = new Size2D(curTrackThickness, bgTrackLength);
727             }
728         }
729
730         private void UpdateBgTrackPosition()
731         {
732             if (bgTrackImage == null)
733             {
734                 return;
735             }
736
737             int lowIndicatorOffset = GetBgTrackLowIndicatorOffset();
738             int highIndicatorOffet = GetBgTrackHighIndicatorOffset();
739
740             if (direction == DirectionType.Horizontal)
741             {
742                 bgTrackImage.Position2D = new Position2D((lowIndicatorOffset - highIndicatorOffet) / 2, 0);
743             }
744             else if (direction == DirectionType.Vertical)
745             {
746                 bgTrackImage.Position2D = new Position2D(0, (highIndicatorOffet - lowIndicatorOffset) / 2);
747             }
748         }
749
750         private void UpdateValue()
751         {
752             if (slidedTrackImage == null)
753             {
754                 return;
755             }
756             if (curValue < minValue || curValue > maxValue || minValue >= maxValue)
757             {
758                 return;
759             }
760
761             float ratio = 0;
762             ratio = (float)(curValue - minValue) / (float)(maxValue - minValue);
763
764             uint curTrackThickness = CurrentTrackThickness();
765
766             if (direction == DirectionType.Horizontal)
767             {
768                 if (LayoutDirection == ViewLayoutDirectionType.RTL)
769                 {
770                     ratio = 1.0f - ratio;
771                 }
772                 float slidedTrackLength = (float)GetBgTrackLength() * ratio;
773                 slidedTrackImage.Size2D = new Size2D((int)(slidedTrackLength + round), (int)curTrackThickness); //Add const round to reach Math.Round function.
774                 thumbImage.Position = new Position(slidedTrackImage.Size2D.Width, 0);
775                 thumbImage.RaiseToTop();
776
777                 if (isValueShown)
778                 {
779                     valueIndicatorImage.Position = new Position(slidedTrackImage.Size2D.Width, 0);
780                 }
781             }
782             else if (direction == DirectionType.Vertical)
783             {
784                 float slidedTrackLength = (float)GetBgTrackLength() * ratio;
785                 slidedTrackImage.Size2D = new Size2D((int)curTrackThickness, (int)(slidedTrackLength + round)); //Add const round to reach Math.Round function.
786                 thumbImage.Position = new Position(0, -slidedTrackImage.Size2D.Height);
787                 thumbImage.RaiseToTop();
788
789                 if (isValueShown)
790                 {
791                     valueIndicatorImage.Position = new Position(0, -(slidedTrackImage.Size2D.Height + thumbImage.Size.Height / 2));
792                 }
793             }
794
795             // Update the track and thumb when the value is over warning value.
796             if (curValue >= warningStartValue)
797             {
798                 if (direction == DirectionType.Horizontal)
799                 {
800                     warningSlidedTrackImage.Size2D = new Size2D((int)(((curValue - warningStartValue) / 100) * this.Size2D.Width), (int)curTrackThickness);
801                 }
802                 else if (direction == DirectionType.Vertical)
803                 {
804                     warningSlidedTrackImage.Size2D = new Size2D((int)curTrackThickness, (int)(((curValue - warningStartValue) / 100) * this.Size2D.Height));
805                 }
806
807                 if (warningThumbColor != null && thumbImage.Color.NotEqualTo(warningThumbColor))
808                 {
809                     thumbImage.Color = warningThumbColor;
810                 }
811                 if (warningThumbImageUrl != null && !thumbImage.ResourceUrl.Equals(warningThumbImageUrl))
812                 {
813                     thumbImage.ResourceUrl = warningThumbImageUrl;
814                 }
815             }
816             else
817             {
818                 warningSlidedTrackImage.Size2D = new Size2D(0, 0);
819                 if (warningThumbColor != null && thumbImage.Color.EqualTo(warningThumbColor))
820                 {
821                     thumbImage.Color = thumbColor;
822                 }
823                 if (warningThumbImageUrl != null && thumbImage.ResourceUrl.Equals(warningThumbImageUrl))
824                 {
825                     thumbImage.ResourceUrl = thumbImageUrl;
826                 }
827             }
828         }
829
830         private uint CurrentTrackThickness()
831         {
832             uint curTrackThickness = 0;
833             if (trackThickness != null)
834             {
835                 curTrackThickness = trackThickness.Value;
836             }
837             else
838             {
839                 if (ViewStyle is SliderStyle sliderStyle && sliderStyle.TrackThickness != null)
840                 {
841                     curTrackThickness = sliderStyle.TrackThickness.Value;
842                 }
843             }
844             return curTrackThickness;
845         }
846
847         private uint CurrentSpaceBetweenTrackAndIndicator()
848         {
849             uint curSpace = 0;
850             if (spaceBetweenTrackAndIndicator != null)
851             {
852                 curSpace = spaceBetweenTrackAndIndicator.Start;
853             }
854             else
855             {
856                 if (ViewStyle is SliderStyle sliderStyle && sliderStyle.TrackPadding != null)
857                 {
858                     curSpace = sliderStyle.TrackPadding.Start;
859                 }
860             }
861             return curSpace;
862         }
863
864         private void UpdateWarningTrackSize()
865         {
866             if (warningTrackImage == null)
867             {
868                 return;
869             }
870
871             int curTrackThickness = (int)CurrentTrackThickness();
872             float warningTrackLength = maxValue - warningStartValue;
873             if (direction == DirectionType.Horizontal)
874             {
875                 warningTrackLength = (warningTrackLength / 100) * this.Size2D.Width;
876                 warningTrackImage.Size2D = new Size2D((int)warningTrackLength, curTrackThickness);
877             }
878             else if (direction == DirectionType.Vertical)
879             {
880                 warningTrackLength = (warningTrackLength / 100) * this.Size2D.Height;
881                 warningTrackImage.Size2D = new Size2D(curTrackThickness, (int)warningTrackLength);
882             }
883         }
884
885         private IndicatorType CurrentIndicatorType()
886         {
887             IndicatorType type = IndicatorType.None;
888             if (ViewStyle is SliderStyle sliderStyle)
889             {
890                 type = (IndicatorType)sliderStyle.IndicatorType;
891             }
892             return type;
893         }
894
895         private Size LowIndicatorImageSize()
896         {
897             Size size = new Size(0, 0);
898             if (lowIndicatorSize != null)
899             {
900                 size = lowIndicatorSize;
901             }
902             else
903             {
904                 if (ViewStyle is SliderStyle sliderStyle && sliderStyle.LowIndicatorImage != null && sliderStyle.LowIndicatorImage.Size != null)
905                 {
906                     size = sliderStyle.LowIndicatorImage.Size;
907                 }
908             }
909             return size;
910         }
911
912         private Size HighIndicatorImageSize()
913         {
914             Size size = new Size(0, 0);
915             if (highIndicatorSize != null)
916             {
917                 size = highIndicatorSize;
918             }
919             else
920             {
921                 if (ViewStyle is SliderStyle sliderStyle && sliderStyle.HighIndicatorImage != null && sliderStyle.HighIndicatorImage.Size != null)
922                 {
923                     size = sliderStyle.HighIndicatorImage.Size;
924                 }
925             }
926             return size;
927         }
928
929         private Size LowIndicatorTextSize()
930         {
931             Size size = new Size(0, 0);
932             if (lowIndicatorSize != null)
933             {
934                 size = lowIndicatorSize;
935             }
936             else
937             {
938                 if (ViewStyle is SliderStyle sliderStyle && sliderStyle.LowIndicator != null && sliderStyle.LowIndicator.Size != null)
939                 {
940                     size = sliderStyle.LowIndicator.Size;
941                 }
942             }
943             return size;
944         }
945
946         private Size HighIndicatorTextSize()
947         {
948             Size size = new Size(0, 0);
949             if (highIndicatorSize != null)
950             {
951                 size = highIndicatorSize;
952             }
953             else
954             {
955                 if (ViewStyle is SliderStyle sliderStyle && sliderStyle.HighIndicator != null && sliderStyle.HighIndicator.Size != null)
956                 {
957                     size = sliderStyle.HighIndicator.Size;
958                 }
959             }
960             return size;
961         }
962     }
963 }