[NUI] Fix Progress and improve Loading
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Progress.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 System.Diagnostics;
21 using Tizen.NUI.Accessibility;
22 using Tizen.NUI.BaseComponents;
23 using Tizen.NUI.Binding;
24
25 namespace Tizen.NUI.Components
26 {
27     /// <summary>
28     /// The Progress class is used to show the ongoing status with a long narrow bar.
29     /// </summary>
30     /// <since_tizen> 6 </since_tizen>
31     public partial class Progress : Control, IAtspiValue
32     {
33         private const int IndeterminateAnimationDuration = 2000;
34
35         /// <summary>
36         /// MaxValueProperty
37         /// </summary>
38         [EditorBrowsable(EditorBrowsableState.Never)]
39         public static readonly BindableProperty MaxValueProperty = BindableProperty.Create(nameof(MaxValue), typeof(float), typeof(Progress), default(float), propertyChanged: (bindable, oldValue, newValue) =>
40         {
41             var instance = (Progress)bindable;
42             if (newValue != null)
43             {
44                 instance.maxValue = (float)newValue;
45                 instance.UpdateValue();
46             }
47         },
48         defaultValueCreator: (bindable) =>
49         {
50             var instance = (Progress)bindable;
51             return instance.maxValue;
52         });
53
54         /// <summary>
55         /// MinValueProperty
56         /// </summary>
57         [EditorBrowsable(EditorBrowsableState.Never)]
58         public static readonly BindableProperty MinValueProperty = BindableProperty.Create(nameof(MinValue), typeof(float), typeof(Progress), default(float), propertyChanged: (bindable, oldValue, newValue) =>
59         {
60             var instance = (Progress)bindable;
61             if (newValue != null)
62             {
63                 instance.minValue = (float)newValue;
64                 instance.UpdateValue();
65             }
66         },
67         defaultValueCreator: (bindable) =>
68         {
69             var instance = (Progress)bindable;
70             return instance.minValue;
71         });
72
73         /// <summary>
74         /// CurrentValueProperty
75         /// </summary>
76         [EditorBrowsable(EditorBrowsableState.Never)]
77         public static readonly BindableProperty CurrentValueProperty = BindableProperty.Create(nameof(CurrentValue), typeof(float), typeof(Progress), default(float), propertyChanged: (bindable, oldValue, newValue) =>
78         {
79             var instance = (Progress)bindable;
80             if (newValue != null)
81             {
82                 if ((float)newValue > instance.maxValue || (float)newValue < instance.minValue)
83                 {
84                     return;
85                 }
86                 instance.currentValue = (float)newValue;
87                 instance.UpdateValue();
88             }
89         },
90         defaultValueCreator: (bindable) =>
91         {
92             var instance = (Progress)bindable;
93             return instance.currentValue;
94         });
95
96         /// <summary>
97         /// BufferValueProperty
98         /// </summary>
99         [EditorBrowsable(EditorBrowsableState.Never)]
100         public static readonly BindableProperty BufferValueProperty = BindableProperty.Create(nameof(BufferValue), typeof(float), typeof(Progress), default(float), propertyChanged: (bindable, oldValue, newValue) =>
101         {
102             var instance = (Progress)bindable;
103             if (newValue != null)
104             {
105                 if ((float)newValue > instance.maxValue || (float)newValue < instance.minValue)
106                 {
107                     return;
108                 }
109                 instance.bufferValue = (float)newValue;
110                 instance.UpdateValue();
111             }
112         },
113         defaultValueCreator: (bindable) =>
114         {
115             var instance = (Progress)bindable;
116             return instance.bufferValue;
117         });
118
119         /// <summary>
120         /// ProgressStateProperty
121         /// </summary>
122         [EditorBrowsable(EditorBrowsableState.Never)]
123         public static readonly BindableProperty ProgressStateProperty = BindableProperty.Create(nameof(ProgressState), typeof(ProgressStatusType), typeof(Progress), ProgressStatusType.Indeterminate, propertyChanged: (bindable, oldValue, newValue) =>
124         {
125             var instance = (Progress)bindable;
126             if (newValue != null)
127             {
128                 instance.state = (ProgressStatusType)newValue;
129                 instance.UpdateStates();
130             }
131         },
132         defaultValueCreator: (bindable) =>
133         {
134             var instance = (Progress)bindable;
135             return instance.state;
136         });
137
138         /// This needs to be considered more if public-open is necessary.
139         private ProgressStatusType state = ProgressStatusType.Determinate;
140
141         private Vector2 size = null;
142         private const float round = 0.5f;
143         private ImageView trackImage = null;
144         private ImageView progressImage = null;
145         private ImageView bufferImage = null;
146         private ImageView indeterminateImage = null;
147         private float maxValue = 100;
148         private float minValue = 0;
149         private float currentValue = 0;
150         private float bufferValue = 0;
151         private Animation indeterminateAnimation = null;
152
153         static Progress() { }
154         /// <summary>
155         /// The constructor of Progress
156         /// </summary>
157         /// <since_tizen> 6 </since_tizen>
158         public Progress() : base()
159         {
160             Initialize();
161         }
162
163         /// <summary>
164         /// The constructor of the Progress class with specific style.
165         /// </summary>
166         /// <param name="style">style name</param>
167         /// <since_tizen> 8 </since_tizen>
168         public Progress(string style) : base(style)
169         {
170             Initialize();
171         }
172
173         /// <summary>
174         /// The constructor of the Progress class with specific style.
175         /// </summary>
176         /// <param name="progressStyle">The style object to initialize the Progress.</param>
177         /// <since_tizen> 8 </since_tizen>
178         public Progress(ProgressStyle progressStyle) : base(progressStyle)
179         {
180             Initialize();
181         }
182
183         /// <summary>
184         /// The status type of the Progress.
185         /// </summary>
186         /// <since_tizen> 6 </since_tizen>
187         public enum ProgressStatusType
188         {
189             /// <summary>
190             /// Show BufferImage
191             /// </summary>
192             /// <since_tizen> 6 </since_tizen>
193             Buffering,
194
195             /// <summary>
196             /// Show ProgressImage and BufferImage
197             /// </summary>
198             /// <since_tizen> 6 </since_tizen>
199             Determinate,
200
201             /// <summary>
202             /// Show TrackImage
203             /// </summary>
204             /// <since_tizen> 6 </since_tizen>
205             Indeterminate
206         }
207
208         /// <summary>
209         /// Return currently applied style.
210         /// </summary>
211         /// <remarks>
212         /// Modifying contents in style may cause unexpected behaviour.
213         /// </remarks>
214         /// <since_tizen> 8 </since_tizen>
215         public ProgressStyle Style => (ProgressStyle)(ViewStyle as ProgressStyle)?.Clone();
216
217         /// <summary>
218         /// The property to get/set Track image object URL of the Progress.
219         /// </summary>
220         /// <since_tizen> 6 </since_tizen>
221         public string TrackImageURL
222         {
223             get
224             {
225                 return GetValue(TrackImageURLProperty) as string;
226             }
227             set
228             {
229                 SetValue(TrackImageURLProperty, value);
230                 NotifyPropertyChanged();
231             }
232         }
233         private string InternalTrackImageURL
234         {
235             get => trackImage.ResourceUrl;
236             set => trackImage.ResourceUrl = value;
237         }
238
239         /// <summary>
240         /// The property to get/set Progress object image URL of the Progress.
241         /// </summary>
242         /// <since_tizen> 6 </since_tizen>
243         public string ProgressImageURL
244         {
245             get
246             {
247                 return GetValue(ProgressImageURLProperty) as string;
248             }
249             set
250             {
251                 SetValue(ProgressImageURLProperty, value);
252                 NotifyPropertyChanged();
253             }
254         }
255         private string InternalProgressImageURL
256         {
257             get => progressImage.ResourceUrl;
258             set => progressImage.ResourceUrl = value;
259         }
260
261         /// <summary>
262         /// The property to get/set Buffer object image resource URL of the Progress.
263         /// </summary>
264         /// <since_tizen> 6 </since_tizen>
265         public string BufferImageURL
266         {
267             get
268             {
269                 return GetValue(BufferImageURLProperty) as string;
270             }
271             set
272             {
273                 SetValue(BufferImageURLProperty, value);
274                 NotifyPropertyChanged();
275             }
276         }
277         private string InternalBufferImageURL
278         {
279             get => bufferImage.ResourceUrl;
280             set => bufferImage.ResourceUrl = value;
281         }
282
283         /// <summary>
284         /// The property to get/set the indeterminate image.
285         /// </summary>
286         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
287         /// <since_tizen> 9 </since_tizen>
288         public string IndeterminateImageUrl
289         {
290             get
291             {
292                 return GetValue(IndeterminateImageUrlProperty) as string;
293             }
294             set
295             {
296                 SetValue(IndeterminateImageUrlProperty, value);
297                 NotifyPropertyChanged();
298             }
299         }
300         private string InternalIndeterminateImageUrl
301         {
302             get
303             {
304                 if (indeterminateImage == null)
305                 {
306                     return null;
307                 }
308                 else
309                 {
310                     return indeterminateImage?.ResourceUrl;
311                 }
312             }
313             set
314             {
315                 if (value == null || indeterminateImage == null)
316                 {
317                     throw new NullReferenceException("Progress.IndeterminateImage is null");
318                 }
319                 else
320                 {
321                     indeterminateImage.ResourceUrl = value;
322                 }
323             }
324         }
325
326         /// <summary>
327         /// The property to get/set Track object color of the Progress.
328         /// </summary>
329         /// <since_tizen> 6 </since_tizen>
330         public Color TrackColor
331         {
332             get
333             {
334                 return GetValue(TrackColorProperty) as Color;
335             }
336             set
337             {
338                 SetValue(TrackColorProperty, value);
339                 NotifyPropertyChanged();
340             }
341         }
342         private Color InternalTrackColor
343         {
344             get => trackImage.BackgroundColor;
345             set => trackImage.BackgroundColor = value;
346         }
347
348         /// <summary>
349         /// The property to get/set Progress object color of the Progress.
350         /// </summary>
351         /// <since_tizen> 6 </since_tizen>
352         public Color ProgressColor
353         {
354             get
355             {
356                 return GetValue(ProgressColorProperty) as Color;
357             }
358             set
359             {
360                 SetValue(ProgressColorProperty, value);
361                 NotifyPropertyChanged();
362             }
363         }
364         private Color InternalProgressColor
365         {
366             get => progressImage.BackgroundColor;
367             set => progressImage.BackgroundColor = value;
368         }
369
370         /// <summary>
371         /// The property to get/set Buffer object color of the Progress.
372         /// </summary>
373         /// <since_tizen> 6 </since_tizen>
374         public Color BufferColor
375         {
376             get
377             {
378                 return GetValue(BufferColorProperty) as Color;
379             }
380             set
381             {
382                 SetValue(BufferColorProperty, value);
383                 NotifyPropertyChanged();
384             }
385         }
386         private Color InternalBufferColor
387         {
388             get => bufferImage.BackgroundColor;
389             set => bufferImage.BackgroundColor = value;
390         }
391
392         /// <summary>
393         /// The property to get/set the maximum value of the Progress.
394         /// </summary>
395         /// <since_tizen> 6 </since_tizen>
396         public float MaxValue
397         {
398             get
399             {
400                 return (float)GetValue(MaxValueProperty);
401             }
402             set
403             {
404                 SetValue(MaxValueProperty, value);
405             }
406         }
407
408         /// <summary>
409         /// The property to get/set the minim value of the Progress.
410         /// </summary>
411         /// <since_tizen> 6 </since_tizen>
412         public float MinValue
413         {
414             get
415             {
416                 return (float)GetValue(MinValueProperty);
417             }
418             set
419             {
420                 SetValue(MinValueProperty, value);
421             }
422         }
423
424         /// <summary>
425         /// The property to get/set the current value of the Progress.
426         /// </summary>
427         /// <since_tizen> 6 </since_tizen>
428         public float CurrentValue
429         {
430             get
431             {
432                 return (float)GetValue(CurrentValueProperty);
433             }
434             set
435             {
436                 SetValue(CurrentValueProperty, value);
437                 if (Accessibility.Accessibility.IsEnabled && IsHighlighted)
438                 {
439                     EmitAccessibilityEvent(AccessibilityPropertyChangeEvent.Value);
440                 }
441             }
442         }
443
444         /// <summary>
445         /// The property to get/set the buffer value of the Progress.
446         /// </summary>
447         /// <since_tizen> 6 </since_tizen>
448         public float BufferValue
449         {
450             get
451             {
452                 return (float)GetValue(BufferValueProperty);
453             }
454             set
455             {
456                 SetValue(BufferValueProperty, value);
457             }
458         }
459
460         /// <summary>
461         /// Gets or sets state of progress.
462         /// </summary>
463         /// <since_tizen> 6 </since_tizen>
464         public ProgressStatusType ProgressState
465         {
466             get
467             {
468                 return (ProgressStatusType)GetValue(ProgressStateProperty);
469             }
470             set
471             {
472                 SetValue(ProgressStateProperty, value);
473             }
474         }
475
476         /// <inheritdoc/>
477         [EditorBrowsable(EditorBrowsableState.Never)]
478         public override void OnInitialize()
479         {
480             base.OnInitialize();
481             AccessibilityRole = Role.ProgressBar;
482             // create necessary components
483             InitializeTrack();
484             InitializeBuffer();
485             InitializeProgress();
486             InitializeIndeterminate();
487
488             indeterminateAnimation?.Stop();
489             indeterminateAnimation = null;
490         }
491
492         /// <inheritdoc/>
493         [EditorBrowsable(EditorBrowsableState.Never)]
494         public override void ApplyStyle(ViewStyle style)
495         {
496             base.ApplyStyle(style);
497
498             if (style is ProgressStyle progressStyle)
499             {
500                 Debug.Assert(trackImage != null);
501                 Debug.Assert(progressImage != null);
502                 Debug.Assert(bufferImage != null);
503                 Debug.Assert(indeterminateImage != null);
504
505                 trackImage.ApplyStyle(progressStyle.Track);
506                 progressImage.ApplyStyle(progressStyle.Progress);
507                 bufferImage.ApplyStyle(progressStyle.Buffer);
508
509                 if (null != indeterminateImage && null != progressStyle.IndeterminateImageUrl)
510                 {
511                     indeterminateImage.ResourceUrl = progressStyle.IndeterminateImageUrl;
512                 }
513             }
514         }
515
516         /// <summary>
517         /// Gets minimum value for Accessibility.
518         /// </summary>
519         [EditorBrowsable(EditorBrowsableState.Never)]
520         double IAtspiValue.AccessibilityGetMinimum()
521         {
522             if (this.ProgressState == Progress.ProgressStatusType.Determinate)
523             {
524                 return (double)MinValue;
525             }
526             else
527             {
528                 return 0.0;
529             }
530         }
531
532         /// <summary>
533         /// Gets the current value for Accessibility.
534         /// </summary>
535         [EditorBrowsable(EditorBrowsableState.Never)]
536         double IAtspiValue.AccessibilityGetCurrent()
537         {
538             if (this.ProgressState == Progress.ProgressStatusType.Determinate)
539             {
540                 return (double)CurrentValue;
541             }
542             else
543             {
544                 return 0.0;
545             }
546         }
547
548         [EditorBrowsable(EditorBrowsableState.Never)]
549         bool IAtspiValue.AccessibilitySetCurrent(double value)
550         {
551             return false;
552         }
553
554         /// <summary>
555         /// Gets maximum value for Accessibility.
556         /// </summary>
557         [EditorBrowsable(EditorBrowsableState.Never)]
558         double IAtspiValue.AccessibilityGetMaximum()
559         {
560             if (this.ProgressState == Progress.ProgressStatusType.Determinate)
561             {
562                 return (double)MaxValue;
563             }
564             else
565             {
566                 return 0.0;
567             }
568         }
569
570         [EditorBrowsable(EditorBrowsableState.Never)]
571         double IAtspiValue.AccessibilityGetMinimumIncrement()
572         {
573             return 0.0;
574         }
575
576         /// <summary>
577         /// Dispose Progress and all children on it.
578         /// </summary>
579         /// <param name="type">Dispose type.</param>
580         /// <since_tizen> 6 </since_tizen>
581         protected override void Dispose(DisposeTypes type)
582         {
583             if (disposed)
584             {
585                 return;
586             }
587
588             if (type == DisposeTypes.Explicit)
589             {
590                 //Called by User
591                 //Release your own managed resources here.
592                 //You should release all of your own disposable objects here.
593                 Utility.Dispose(trackImage);
594                 Utility.Dispose(progressImage);
595                 Utility.Dispose(bufferImage);
596                 Utility.Dispose(indeterminateImage);
597             }
598
599             //You must call base.Dispose(type) just before exit.
600             base.Dispose(type);
601         }
602
603         /// <summary>
604         /// Change Image status. It can be override.
605         /// </summary>
606         /// This needs to be considered more if public-open is necessary.
607         [EditorBrowsable(EditorBrowsableState.Never)]
608         private void UpdateStates()
609         {
610             ChangeImageState(state);
611         }
612
613         /// <inheritdoc/>
614         [EditorBrowsable(EditorBrowsableState.Never)]
615         public override void OnRelayout(Vector2 size, RelayoutContainer container)
616         {
617             if (size == null) return;
618
619             if (size.Equals(this.size))
620             {
621                 return;
622             }
623
624             this.size = new Vector2(size);
625             UpdateValue();
626
627             if (state == ProgressStatusType.Indeterminate) UpdateIndeterminateAnimation();
628         }
629
630         /// <summary>
631         /// Update progress value
632         /// </summary>
633         /// This needs to be considered more if public-open is necessary.
634         [EditorBrowsable(EditorBrowsableState.Never)]
635         private void UpdateValue()
636         {
637             if (null == trackImage || null == progressImage)
638             {
639                 return;
640             }
641
642             if (minValue >= maxValue || currentValue < minValue || currentValue > maxValue)
643             {
644                 return;
645             }
646
647             float width = this.SizeWidth;
648             float height = this.SizeHeight;
649             float progressRatio = (float)(currentValue - minValue) / (float)(maxValue - minValue);
650             float progressWidth = width * progressRatio;
651             progressImage.Size2D = new Size2D((int)(progressWidth + round), (int)height); //Add const round to reach Math.Round function.
652             if (null != bufferImage)
653             {
654                 if (bufferValue < minValue || bufferValue > maxValue)
655                 {
656                     return;
657                 }
658
659                 float bufferRatio = (float)(bufferValue - minValue) / (float)(maxValue - minValue);
660                 float bufferWidth = width * bufferRatio;
661                 bufferImage.Size2D = new Size2D((int)(bufferWidth + round), (int)height); //Add const round to reach Math.Round function.
662             }
663         }
664
665         private Vector4 destinationValue = new Vector4(-1.0f, 0.0f, 10.0f, 1.0f);
666         private Vector4 initialValue = new Vector4(0.0f, 0.0f, 10.0f, 1.0f);
667
668         /// <summary>
669         /// Update Animation for Indeterminate mode.
670         /// </summary>
671         /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
672         [EditorBrowsable(EditorBrowsableState.Never)]
673         private void UpdateIndeterminateAnimation()
674         {
675             if (indeterminateImage == null) return;
676
677             if (indeterminateAnimation == null)
678             {
679                 indeterminateAnimation = new Animation(IndeterminateAnimationDuration);
680             }
681             else
682             {
683                 indeterminateAnimation.Stop();
684                 indeterminateAnimation.Clear();
685             }
686
687             float destination = (this.SizeWidth - indeterminateImage.SizeWidth);
688
689             KeyFrames keyFrames = new KeyFrames();
690             keyFrames.Add(0.0f /*  0%*/, new Position(0, 0));
691             AlphaFunction ease = new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseInOut);
692             keyFrames.Add(0.5f /* 50%*/, new Position(destination, 0), ease);
693             keyFrames.Add(1.0f /*100%*/, new Position(0, 0), ease);
694             ease.Dispose();
695
696             indeterminateAnimation.AnimateBetween(indeterminateImage, "Position", keyFrames);
697             indeterminateAnimation.Looping = true;
698             indeterminateAnimation.Play();
699         }
700
701         /// <summary>
702         /// Get Progress style.
703         /// </summary>
704         /// <returns>The default progress style.</returns>
705         /// <since_tizen> 8 </since_tizen>
706         protected override ViewStyle CreateViewStyle()
707         {
708             return new ProgressStyle();
709         }
710
711         /// <summary>
712         /// Change Image status
713         /// </summary>
714         /// <since_tizen> 6 </since_tizen>
715         /// <param name="statusType">New status type</param>
716         protected void ChangeImageState(ProgressStatusType statusType)
717         {
718             if (!IsEnabled)
719             {
720                 ControlState = ControlState.Disabled;
721
722                 indeterminateAnimation?.Stop();
723                 indeterminateAnimation = null;
724
725                 if (null != indeterminateImage)
726                 {
727                     indeterminateImage.Hide();
728                 }
729                 progressImage.Hide();
730                 bufferImage.Hide();
731                 return;
732             }
733
734             if (statusType == ProgressStatusType.Buffering)
735             {
736                 indeterminateAnimation?.Stop();
737                 indeterminateAnimation = null;
738
739                 if (null != indeterminateImage)
740                 {
741                     indeterminateImage.Hide();
742                 }
743                 progressImage.Hide();
744                 bufferImage.Show();
745             }
746             else if (statusType == ProgressStatusType.Determinate)
747             {
748                 indeterminateAnimation?.Stop();
749                 indeterminateAnimation = null;
750
751                 if (null != indeterminateImage)
752                 {
753                     indeterminateImage.Hide();
754                 }
755                 bufferImage.Hide();
756                 progressImage.Show();
757
758                 UpdateValue();
759             }
760             else if (statusType == ProgressStatusType.Indeterminate)
761             {
762                 bufferImage.Hide();
763                 progressImage.Hide();
764                 if (null != indeterminateImage)
765                 {
766                     indeterminateImage.Show();
767                 }
768
769                 UpdateIndeterminateAnimation();
770             }
771         }
772
773         /// <inheritdoc/>
774         [EditorBrowsable(EditorBrowsableState.Never)]
775         protected override void OnEnabled(bool enabled)
776         {
777             base.OnEnabled(enabled);
778             UpdateStates();
779         }
780
781         private void Initialize()
782         {
783             AccessibilityHighlightable = true;
784         }
785
786         private void InitializeTrack()
787         {
788             if (null == trackImage)
789             {
790                 trackImage = new ImageView
791                 {
792                     WidthResizePolicy = ResizePolicyType.FillToParent,
793                     HeightResizePolicy = ResizePolicyType.FillToParent,
794                     PositionUsesPivotPoint = true,
795                     ParentOrigin = NUI.ParentOrigin.TopLeft,
796                     PivotPoint = NUI.PivotPoint.TopLeft,
797                     AccessibilityHidden = true,
798                 };
799                 Add(trackImage);
800             }
801         }
802
803         private void InitializeProgress()
804         {
805             if (null == progressImage)
806             {
807                 progressImage = new ImageView
808                 {
809                     WidthResizePolicy = ResizePolicyType.FillToParent,
810                     HeightResizePolicy = ResizePolicyType.FillToParent,
811                     PositionUsesPivotPoint = true,
812                     ParentOrigin = Tizen.NUI.ParentOrigin.TopLeft,
813                     PivotPoint = Tizen.NUI.PivotPoint.TopLeft,
814                     AccessibilityHidden = true,
815                 };
816                 Add(progressImage);
817             }
818         }
819
820         private void InitializeBuffer()
821         {
822             if (null == bufferImage)
823             {
824                 bufferImage = new ImageView
825                 {
826                     WidthResizePolicy = ResizePolicyType.FillToParent,
827                     HeightResizePolicy = ResizePolicyType.FillToParent,
828                     PositionUsesPivotPoint = true,
829                     ParentOrigin = Tizen.NUI.ParentOrigin.TopLeft,
830                     PivotPoint = Tizen.NUI.PivotPoint.TopLeft,
831                     AccessibilityHidden = true,
832                 };
833                 Add(bufferImage);
834                 bufferImage.Hide(); // At first, buffer image does not show.
835             }
836         }
837
838         private void InitializeIndeterminate()
839         {
840             indeterminateImage = new ImageView
841             {
842                 Size = new Size(16, 16),
843                 PositionUsesPivotPoint = true,
844                 ParentOrigin = Tizen.NUI.ParentOrigin.CenterLeft,
845                 PivotPoint = Tizen.NUI.PivotPoint.CenterLeft,
846                 AccessibilityHidden = true,
847             };
848             trackImage.Add(indeterminateImage);
849             indeterminateImage.Hide();
850
851             if (state == ProgressStatusType.Indeterminate)
852             {
853                 indeterminateImage.Show();
854             }
855         }
856     }
857 }