Merge remote-tracking branch 'origin/master' into tizen
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Slider.Internal.cs
1 using System;
2 using System.ComponentModel;
3 using Tizen.NUI.BaseComponents;
4
5 namespace Tizen.NUI.Components
6 {
7     public partial class Slider
8     {
9         // the background track image object
10         private ImageView bgTrackImage = null;
11         // the slided track image object
12         private ImageView slidedTrackImage = null;
13         // the thumb image object
14         private ImageView thumbImage = null;
15         // the low indicator image object
16         private ImageView lowIndicatorImage = null;
17         // the high indicator image object
18         private ImageView highIndicatorImage = null;
19         // the low indicator text object
20         private TextLabel lowIndicatorText = null;
21         // the high indicator text object
22         private TextLabel highIndicatorText = null;
23         // the direction type
24         private DirectionType direction = DirectionType.Horizontal;
25         // the indicator type
26         private IndicatorType indicatorType = IndicatorType.None;
27         private const float round = 0.5f;
28         // the minimum value
29         private float minValue = 0;
30         // the maximum value
31         private float maxValue = 100;
32         // the current value
33         private float curValue = 0;
34         // the size of the low indicator
35         private Size lowIndicatorSize = null;
36         // the size of the high indicator
37         private Size highIndicatorSize = null;
38         // the track thickness value
39         private uint? trackThickness = null;
40         // the value of the space between track and indicator object
41         private Extents _spaceBetweenTrackAndIndicator = null;
42
43         private PanGestureDetector panGestureDetector = null;
44         private float currentSlidedOffset;
45         private EventHandler<ValueChangedArgs> valueChangedHandler;
46         private EventHandler<SlidingFinishedArgs> slidingFinishedHandler;
47         private EventHandler<SliderValueChangedEventArgs> sliderValueChangedHandler;
48         private EventHandler<SliderSlidingFinishedEventArgs> sliderSlidingFinishedHandler;
49         private EventHandler<StateChangedArgs> stateChangedHandler;
50
51         bool isFocused = false;
52         bool isPressed = false;
53
54         private void Initialize()
55         {
56             currentSlidedOffset = 0;
57             isFocused = false;
58             isPressed = false;
59             LayoutDirectionChanged += OnLayoutDirectionChanged;
60         }
61
62         private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
63         {
64             RelayoutRequest();
65         }
66
67         private ImageView CreateSlidedTrack()
68         {
69             if (null == slidedTrackImage)
70             {
71                 slidedTrackImage = new ImageView()
72                 {
73                     WidthResizePolicy = ResizePolicyType.Fixed,
74                     HeightResizePolicy = ResizePolicyType.Fixed
75                 };
76
77                 if (bgTrackImage != null)
78                 {
79                     bgTrackImage.Add(slidedTrackImage);
80                 }
81
82                 if (null != thumbImage)
83                 {
84                     slidedTrackImage.Add(thumbImage);
85                 }
86             }
87
88             return slidedTrackImage;
89         }
90
91         private TextLabel CreateLowIndicatorText()
92         {
93             if (null == lowIndicatorText)
94             {
95                 lowIndicatorText = new TextLabel()
96                 {
97                     WidthResizePolicy = ResizePolicyType.Fixed,
98                     HeightResizePolicy = ResizePolicyType.Fixed
99                 };
100                 this.Add(lowIndicatorText);
101             }
102
103             return lowIndicatorText;
104         }
105
106         private TextLabel CreateHighIndicatorText()
107         {
108             if (null == highIndicatorText)
109             {
110                 highIndicatorText = new TextLabel()
111                 {
112                     WidthResizePolicy = ResizePolicyType.Fixed,
113                     HeightResizePolicy = ResizePolicyType.Fixed
114                 };
115                 this.Add(highIndicatorText);
116             }
117
118             return highIndicatorText;
119         }
120
121         private ImageView CreateBackgroundTrack()
122         {
123             if (null == bgTrackImage)
124             {
125                 bgTrackImage = new ImageView()
126                 {
127                     WidthResizePolicy = ResizePolicyType.Fixed,
128                     HeightResizePolicy = ResizePolicyType.Fixed,
129                     ParentOrigin = Tizen.NUI.ParentOrigin.Center,
130                     PivotPoint = Tizen.NUI.PivotPoint.Center,
131                     PositionUsesPivotPoint = true
132                 };
133                 this.Add(bgTrackImage);
134
135                 if (null != slidedTrackImage)
136                 {
137                     bgTrackImage.Add(slidedTrackImage);
138                 }
139
140                 bgTrackImage.TouchEvent += OnTouchEventForBgTrack;
141             }
142
143             return bgTrackImage;
144         }
145
146         private ImageView CreateThumb()
147         {
148             if (null == thumbImage)
149             {
150                 thumbImage = new ImageView()
151                 {
152                     WidthResizePolicy = ResizePolicyType.Fixed,
153                     HeightResizePolicy = ResizePolicyType.Fixed,
154                     ParentOrigin = NUI.ParentOrigin.Center,
155                     PivotPoint = NUI.PivotPoint.Center,
156                     PositionUsesPivotPoint = true
157                 };
158                 if (slidedTrackImage != null)
159                 {
160                     slidedTrackImage.Add(thumbImage);
161                 }
162                 thumbImage.TouchEvent += OnTouchEventForThumb;
163
164                 panGestureDetector = new PanGestureDetector();
165                 panGestureDetector.Attach(thumbImage);
166                 panGestureDetector.Detected += OnPanGestureDetected;
167             }
168
169             return thumbImage;
170         }
171
172         private void OnPanGestureDetected(object source, PanGestureDetector.DetectedEventArgs e)
173         {
174             if (e.PanGesture.State == Gesture.StateType.Started)
175             {
176                 if (direction == DirectionType.Horizontal)
177                 {
178                     currentSlidedOffset = slidedTrackImage.SizeWidth;
179                 }
180                 else if (direction == DirectionType.Vertical)
181                 {
182                     currentSlidedOffset = slidedTrackImage.SizeHeight;
183                 }
184                 UpdateState(isFocused, true);
185             }
186
187             if (e.PanGesture.State == Gesture.StateType.Continuing || e.PanGesture.State == Gesture.StateType.Started)
188             {
189                 if (direction == DirectionType.Horizontal)
190                 {
191                     CalculateCurrentValueByGesture(e.PanGesture.Displacement.X);
192                 }
193                 else if (direction == DirectionType.Vertical)
194                 {
195                     CalculateCurrentValueByGesture(-e.PanGesture.Displacement.Y);
196                 }
197                 UpdateValue();
198             }
199
200             if (e.PanGesture.State == Gesture.StateType.Finished)
201             {
202                 if (null != slidingFinishedHandler)
203                 {
204                     SlidingFinishedArgs args = new SlidingFinishedArgs();
205                     args.CurrentValue = curValue;
206                     slidingFinishedHandler(this, args);
207                 }
208
209                 if (null != sliderSlidingFinishedHandler)
210                 {
211                     SliderSlidingFinishedEventArgs args = new SliderSlidingFinishedEventArgs();
212                     args.CurrentValue = curValue;
213                     sliderSlidingFinishedHandler(this, args);
214                 }
215
216                 UpdateState(isFocused, false);
217             }
218         }
219
220         // Relayout basic component: track, thumb and indicator
221         private void RelayoutBaseComponent(bool isInitial = true)
222         {
223             if (direction == DirectionType.Horizontal)
224             {
225                 if (slidedTrackImage != null)
226                 {
227                     slidedTrackImage.ParentOrigin = NUI.ParentOrigin.CenterLeft;
228                     slidedTrackImage.PivotPoint = NUI.PivotPoint.CenterLeft;
229                     slidedTrackImage.PositionUsesPivotPoint = true;
230                 }
231                 if (thumbImage != null)
232                 {
233                     thumbImage.ParentOrigin = NUI.ParentOrigin.CenterRight;
234                     thumbImage.PivotPoint = NUI.PivotPoint.Center;
235                     thumbImage.PositionUsesPivotPoint = true;
236                 }
237                 if (lowIndicatorImage != null)
238                 {
239                     lowIndicatorImage.ParentOrigin = NUI.ParentOrigin.CenterLeft;
240                     lowIndicatorImage.PivotPoint = NUI.PivotPoint.CenterLeft;
241                     lowIndicatorImage.PositionUsesPivotPoint = true;
242                 }
243                 if (highIndicatorImage != null)
244                 {
245                     highIndicatorImage.ParentOrigin = NUI.ParentOrigin.CenterRight;
246                     highIndicatorImage.PivotPoint = NUI.PivotPoint.CenterRight;
247                     highIndicatorImage.PositionUsesPivotPoint = true;
248                 }
249                 if (lowIndicatorText != null)
250                 {
251                     lowIndicatorText.ParentOrigin = NUI.ParentOrigin.CenterLeft;
252                     lowIndicatorText.PivotPoint = NUI.PivotPoint.CenterLeft;
253                     lowIndicatorText.PositionUsesPivotPoint = true;
254                 }
255                 if (highIndicatorText != null)
256                 {
257                     highIndicatorText.ParentOrigin = NUI.ParentOrigin.CenterRight;
258                     highIndicatorText.PivotPoint = NUI.PivotPoint.CenterRight;
259                     highIndicatorText.PositionUsesPivotPoint = true;
260                 }
261                 if (panGestureDetector != null)
262                 {
263                     if (!isInitial)
264                     {
265                         panGestureDetector.RemoveDirection(PanGestureDetector.DirectionVertical);
266                     }
267                     panGestureDetector.AddDirection(PanGestureDetector.DirectionHorizontal);
268                 }
269             }
270             else if (direction == DirectionType.Vertical)
271             {
272                 if (slidedTrackImage != null)
273                 {
274                     slidedTrackImage.ParentOrigin = NUI.ParentOrigin.BottomCenter;
275                     slidedTrackImage.PivotPoint = NUI.PivotPoint.BottomCenter;
276                     slidedTrackImage.PositionUsesPivotPoint = true;
277                 }
278                 if (thumbImage != null)
279                 {
280                     thumbImage.ParentOrigin = NUI.ParentOrigin.TopCenter;
281                     thumbImage.PivotPoint = NUI.PivotPoint.Center;
282                     thumbImage.PositionUsesPivotPoint = true;
283                 }
284                 if (lowIndicatorImage != null)
285                 {
286                     lowIndicatorImage.ParentOrigin = NUI.ParentOrigin.BottomCenter;
287                     lowIndicatorImage.PivotPoint = NUI.PivotPoint.BottomCenter;
288                     lowIndicatorImage.PositionUsesPivotPoint = true;
289                 }
290                 if (highIndicatorImage != null)
291                 {
292                     highIndicatorImage.ParentOrigin = NUI.ParentOrigin.TopCenter;
293                     highIndicatorImage.PivotPoint = NUI.PivotPoint.TopCenter;
294                     highIndicatorImage.PositionUsesPivotPoint = true;
295                 }
296                 if (lowIndicatorText != null)
297                 {
298                     lowIndicatorText.ParentOrigin = NUI.ParentOrigin.BottomCenter;
299                     lowIndicatorText.PivotPoint = NUI.PivotPoint.BottomCenter;
300                     lowIndicatorText.PositionUsesPivotPoint = true;
301                 }
302                 if (highIndicatorText != null)
303                 {
304                     highIndicatorText.ParentOrigin = NUI.ParentOrigin.TopCenter;
305                     highIndicatorText.PivotPoint = NUI.PivotPoint.TopCenter;
306                     highIndicatorText.PositionUsesPivotPoint = true;
307                 }
308                 if (panGestureDetector != null)
309                 {
310                     if (!isInitial)
311                     {
312                         panGestureDetector.RemoveDirection(PanGestureDetector.DirectionHorizontal);
313                     }
314                     panGestureDetector.AddDirection(PanGestureDetector.DirectionVertical);
315                 }
316             }
317         }
318
319         private int BgTrackLength()
320         {
321             int bgTrackLength = 0;
322             IndicatorType type = CurrentIndicatorType();
323
324             if (type == IndicatorType.None)
325             {
326                 if (direction == DirectionType.Horizontal)
327                 {
328                     bgTrackLength = this.Size2D.Width;
329                 }
330                 else if (direction == DirectionType.Vertical)
331                 {
332                     bgTrackLength = this.Size2D.Height;
333                 }
334             }
335             else if (type == IndicatorType.Image)
336             {// <lowIndicatorImage> <spaceBetweenTrackAndIndicator> <bgTrack> <spaceBetweenTrackAndIndicator> <highIndicatorImage>
337                 Size lowIndicatorImageSize = LowIndicatorImageSize();
338                 Size highIndicatorImageSize = HighIndicatorImageSize();
339                 int curSpace = (int)CurrentSpaceBetweenTrackAndIndicator();
340                 if (direction == DirectionType.Horizontal)
341                 {
342                     int lowIndicatorSpace = ((lowIndicatorImageSize.Width == 0) ? (0) : ((int)(curSpace + lowIndicatorImageSize.Width)));
343                     int highIndicatorSpace = ((highIndicatorImageSize.Width == 0) ? (0) : ((int)(curSpace + highIndicatorImageSize.Width)));
344                     bgTrackLength = this.Size2D.Width - lowIndicatorSpace - highIndicatorSpace;
345                 }
346                 else if (direction == DirectionType.Vertical)
347                 {
348                     int lowIndicatorSpace = ((lowIndicatorImageSize.Height == 0) ? (0) : ((int)(curSpace + lowIndicatorImageSize.Height)));
349                     int highIndicatorSpace = ((highIndicatorImageSize.Height == 0) ? (0) : ((int)(curSpace + highIndicatorImageSize.Height)));
350                     bgTrackLength = this.Size2D.Height - lowIndicatorSpace - highIndicatorSpace;
351                 }
352             }
353             else if (type == IndicatorType.Text)
354             {// <lowIndicatorText> <spaceBetweenTrackAndIndicator> <bgTrack> <spaceBetweenTrackAndIndicator> <highIndicatorText>
355                 Size lowIndicatorTextSize = LowIndicatorTextSize();
356                 Size highIndicatorTextSize = HighIndicatorTextSize();
357                 int curSpace = (int)CurrentSpaceBetweenTrackAndIndicator();
358                 if (direction == DirectionType.Horizontal)
359                 {
360                     int lowIndicatorSpace = ((lowIndicatorTextSize.Width == 0) ? (0) : ((int)(curSpace + lowIndicatorTextSize.Width)));
361                     int highIndicatorSpace = ((highIndicatorTextSize.Width == 0) ? (0) : ((int)(curSpace + highIndicatorTextSize.Width)));
362                     bgTrackLength = this.Size2D.Width - lowIndicatorSpace - highIndicatorSpace;
363                 }
364                 else if (direction == DirectionType.Vertical)
365                 {
366                     int lowIndicatorSpace = ((lowIndicatorTextSize.Height == 0) ? (0) : ((int)(curSpace + lowIndicatorTextSize.Height)));
367                     int highIndicatorSpace = ((highIndicatorTextSize.Height == 0) ? (0) : ((int)(curSpace + highIndicatorTextSize.Height)));
368                     bgTrackLength = this.Size2D.Height - lowIndicatorSpace - highIndicatorSpace;
369                 }
370             }
371             return bgTrackLength;
372         }
373
374         private void UpdateLowIndicatorSize()
375         {
376             if (lowIndicatorSize != null)
377             {
378                 if (lowIndicatorImage != null)
379                 {
380                     lowIndicatorImage.Size = lowIndicatorSize;
381                 }
382                 if (lowIndicatorText != null)
383                 {
384                     lowIndicatorText.Size = lowIndicatorSize;
385                 }
386             }
387             else
388             {
389                 if (lowIndicatorImage != null && lowIndicatorImage != null && lowIndicatorImage.Size != null)
390                 {
391                     lowIndicatorImage.Size = sliderStyle.LowIndicatorImage.Size;
392                 }
393                 if (lowIndicatorText != null && lowIndicatorText != null && lowIndicatorText.Size != null)
394                 {
395                     lowIndicatorText.Size = sliderStyle.LowIndicator.Size;
396                 }
397             }
398         }
399
400         private void UpdateBgTrackSize()
401         {
402             if (bgTrackImage == null)
403             {
404                 return;
405             }
406             int curTrackThickness = (int)CurrentTrackThickness();
407             int bgTrackLength = BgTrackLength();
408             if (direction == DirectionType.Horizontal)
409             {
410                 bgTrackImage.Size2D = new Size2D(bgTrackLength, curTrackThickness);
411             }
412             else if (direction == DirectionType.Vertical)
413             {
414                 bgTrackImage.Size2D = new Size2D(curTrackThickness, bgTrackLength);
415             }
416         }
417
418         private void UpdateBgTrackPosition()
419         {
420             if (bgTrackImage == null)
421             {
422                 return;
423             }
424             IndicatorType type = CurrentIndicatorType();
425
426             if (type == IndicatorType.None)
427             {
428                 bgTrackImage.Position2D = new Position2D(0, 0);
429             }
430             else if (type == IndicatorType.Image)
431             {
432                 Size lowIndicatorImageSize = LowIndicatorImageSize();
433                 Size highIndicatorImageSize = HighIndicatorImageSize();
434                 int curSpace = (int)CurrentSpaceBetweenTrackAndIndicator();
435                 if (direction == DirectionType.Horizontal)
436                 {
437                     int lowIndicatorSpace = ((lowIndicatorImageSize.Width == 0) ? (0) : ((int)(curSpace + lowIndicatorImageSize.Width)));
438                     int highIndicatorSpace = ((highIndicatorImageSize.Width == 0) ? (0) : ((int)(curSpace + highIndicatorImageSize.Width)));
439                     bgTrackImage.Position2D = new Position2D(lowIndicatorSpace - (lowIndicatorSpace + highIndicatorSpace) / 2, 0);
440                 }
441                 else if (direction == DirectionType.Vertical)
442                 {
443                     int lowIndicatorSpace = ((lowIndicatorImageSize.Height == 0) ? (0) : ((int)(curSpace + lowIndicatorImageSize.Height)));
444                     int highIndicatorSpace = ((highIndicatorImageSize.Height == 0) ? (0) : ((int)(curSpace + highIndicatorImageSize.Height)));
445                     bgTrackImage.Position2D = new Position2D(0, lowIndicatorSpace - (lowIndicatorSpace + highIndicatorSpace) / 2);
446                 }
447             }
448             else if (type == IndicatorType.Text)
449             {
450                 Size lowIndicatorTextSize = LowIndicatorTextSize();
451                 Size highIndicatorTextSize = HighIndicatorTextSize();
452                 int curSpace = (int)CurrentSpaceBetweenTrackAndIndicator();
453                 if (direction == DirectionType.Horizontal)
454                 {
455                     int lowIndicatorSpace = ((lowIndicatorTextSize.Width == 0) ? (0) : ((int)(curSpace + lowIndicatorTextSize.Width)));
456                     int highIndicatorSpace = ((highIndicatorTextSize.Width == 0) ? (0) : ((int)(curSpace + highIndicatorTextSize.Width)));
457                     bgTrackImage.Position2D = new Position2D(lowIndicatorSpace - (lowIndicatorSpace + highIndicatorSpace) / 2, 0);
458                 }
459                 else if (direction == DirectionType.Vertical)
460                 {
461                     int lowIndicatorSpace = ((lowIndicatorTextSize.Height == 0) ? (0) : ((int)(curSpace + lowIndicatorTextSize.Height)));
462                     int highIndicatorSpace = ((highIndicatorTextSize.Height == 0) ? (0) : ((int)(curSpace + highIndicatorTextSize.Height)));
463                     bgTrackImage.Position2D = new Position2D(0, -(lowIndicatorSpace - (lowIndicatorSpace + highIndicatorSpace) / 2));
464                 }
465             }
466         }
467
468         private void UpdateValue()
469         {
470             if (slidedTrackImage == null)
471             {
472                 return;
473             }
474             if (curValue < minValue || curValue > maxValue || minValue >= maxValue)
475             {
476                 return;
477             }
478
479             float ratio = 0;
480             ratio = (float)(curValue - minValue) / (float)(maxValue - minValue);
481
482             uint curTrackThickness = CurrentTrackThickness();
483
484             if (direction == DirectionType.Horizontal)
485             {
486                 if (LayoutDirection == ViewLayoutDirectionType.RTL)
487                 {
488                     ratio = 1.0f - ratio;
489                 }
490                 float slidedTrackLength = (float)BgTrackLength() * ratio;
491                 slidedTrackImage.Size2D = new Size2D((int)(slidedTrackLength + round), (int)curTrackThickness); //Add const round to reach Math.Round function.
492             }
493             else if (direction == DirectionType.Vertical)
494             {
495                 float slidedTrackLength = (float)BgTrackLength() * ratio;
496                 slidedTrackImage.Size2D = new Size2D((int)(curTrackThickness + round), (int)slidedTrackLength); //Add const round to reach Math.Round function.
497             }
498         }
499
500         private uint CurrentTrackThickness()
501         {
502             uint curTrackThickness = 0;
503             if (trackThickness != null)
504             {
505                 curTrackThickness = trackThickness.Value;
506             }
507             else
508             {
509                 if (sliderStyle != null && sliderStyle.TrackThickness != null)
510                 {
511                     curTrackThickness = sliderStyle.TrackThickness.Value;
512                 }
513             }
514             return curTrackThickness;
515         }
516
517         private uint CurrentSpaceBetweenTrackAndIndicator()
518         {
519             uint curSpace = 0;
520             if (spaceBetweenTrackAndIndicator != null)
521             {
522                 curSpace = spaceBetweenTrackAndIndicator.Start;
523             }
524             else
525             {
526                 if (sliderStyle != null && sliderStyle.TrackPadding != null)
527                 {
528                     curSpace = sliderStyle.TrackPadding.Start;
529                 }
530             }
531             return curSpace;
532         }
533
534         private IndicatorType CurrentIndicatorType()
535         {
536             IndicatorType type = IndicatorType.None;
537             if (sliderStyle != null)
538             {
539                 type = (IndicatorType)sliderStyle.IndicatorType;
540             }
541             return type;
542         }
543
544         private Size LowIndicatorImageSize()
545         {
546             Size size = new Size(0, 0);
547             if (lowIndicatorSize != null)
548             {
549                 size = lowIndicatorSize;
550             }
551             else
552             {
553                 if (sliderStyle != null && sliderStyle.LowIndicatorImage != null && sliderStyle.LowIndicatorImage.Size != null)
554                 {
555                     size = sliderStyle.LowIndicatorImage.Size;
556                 }
557             }
558             return size;
559         }
560
561         private Size HighIndicatorImageSize()
562         {
563             Size size = new Size(0, 0);
564             if (highIndicatorSize != null)
565             {
566                 size = highIndicatorSize;
567             }
568             else
569             {
570                 if (sliderStyle != null && sliderStyle.HighIndicatorImage != null && sliderStyle.HighIndicatorImage.Size != null)
571                 {
572                     size = sliderStyle.HighIndicatorImage.Size;
573                 }
574             }
575             return size;
576         }
577
578         private Size LowIndicatorTextSize()
579         {
580             Size size = new Size(0, 0);
581             if (lowIndicatorSize != null)
582             {
583                 size = lowIndicatorSize;
584             }
585             else
586             {
587                 if (sliderStyle != null && sliderStyle.LowIndicator != null && sliderStyle.LowIndicator.Size != null)
588                 {
589                     size = sliderStyle.LowIndicator.Size;
590                 }
591             }
592             return size;
593         }
594
595         private Size HighIndicatorTextSize()
596         {
597             Size size = new Size(0, 0);
598             if (highIndicatorSize != null)
599             {
600                 size = highIndicatorSize;
601             }
602             else
603             {
604                 if (sliderStyle != null && sliderStyle.HighIndicator != null && sliderStyle.HighIndicator.Size != null)
605                 {
606                     size = sliderStyle.HighIndicator.Size;
607                 }
608             }
609             return size;
610         }
611     }
612 }