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