[NUI] Refactor NUI Components (#1159)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Progress.cs
1 /*
2  * Copyright(c) 2019 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 using System;
18 using Tizen.NUI.BaseComponents;
19 using Tizen.NUI.Binding;
20 using System.ComponentModel;
21
22 namespace Tizen.NUI.Components
23 {
24     /// <summary>
25     /// The Progress class of nui component. It's used to show the ongoing status with a long narrow bar.
26     /// </summary>
27     /// <since_tizen> 6 </since_tizen>
28     public class Progress : Control
29     {
30         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
31         [EditorBrowsable(EditorBrowsableState.Never)]
32         public static readonly BindableProperty MaxValueProperty = BindableProperty.Create("MaxValue", typeof(float), typeof(Progress), default(float), propertyChanged: (bindable, oldValue, newValue) =>
33         {
34             var instance = (Progress)bindable;
35             if (newValue != null)
36             {
37                 instance.maxValue = (float)newValue;
38                 instance.UpdateValue();
39             }
40         },
41         defaultValueCreator: (bindable) =>
42         {
43             var instance = (Progress)bindable;
44             return instance.maxValue;
45         });
46
47         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
48         [EditorBrowsable(EditorBrowsableState.Never)]
49         public static readonly BindableProperty MinValueProperty = BindableProperty.Create("MinValue", typeof(float), typeof(Progress), default(float), propertyChanged: (bindable, oldValue, newValue) =>
50         {
51             var instance = (Progress)bindable;
52             if (newValue != null)
53             {
54                 instance.minValue = (float)newValue;
55                 instance.UpdateValue();
56             }
57         },
58         defaultValueCreator: (bindable) =>
59         {
60             var instance = (Progress)bindable;
61             return instance.minValue;
62         });
63
64         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
65         [EditorBrowsable(EditorBrowsableState.Never)]
66         public static readonly BindableProperty CurrentValueProperty = BindableProperty.Create("currentValue", typeof(float), typeof(Progress), default(float), propertyChanged: (bindable, oldValue, newValue) =>
67         {
68             var instance = (Progress)bindable;
69             if (newValue != null)
70             {
71                 if ((float)newValue > instance.maxValue || (float)newValue < instance.minValue)
72                 {
73                     return;
74                 }
75                 instance.currentValue = (float)newValue;
76                 instance.UpdateValue();
77             }
78         },
79         defaultValueCreator: (bindable) =>
80         {
81             var instance = (Progress)bindable;
82             return instance.currentValue;
83         });
84
85         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
86         [EditorBrowsable(EditorBrowsableState.Never)]
87         public static readonly BindableProperty BufferValueProperty = BindableProperty.Create("bufferValue", typeof(float), typeof(Progress), default(float), propertyChanged: (bindable, oldValue, newValue) =>
88         {
89             var instance = (Progress)bindable;
90             if (newValue != null)
91             {
92                 if ((float)newValue > instance.maxValue || (float)newValue < instance.minValue)
93                 {
94                     return;
95                 }
96                 instance.bufferValue = (float)newValue;
97                 instance.UpdateValue();
98             }
99         },
100         defaultValueCreator: (bindable) =>
101         {
102             var instance = (Progress)bindable;
103             return instance.bufferValue;
104         });
105
106         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
107         [EditorBrowsable(EditorBrowsableState.Never)]
108         public static readonly BindableProperty ProgressStateProperty = BindableProperty.Create("state", typeof(ProgressStatusType), typeof(Progress), ProgressStatusType.Indeterminate, propertyChanged: (bindable, oldValue, newValue) =>
109         {
110             var instance = (Progress)bindable;
111             if (newValue != null)
112             {
113                 instance.state = (ProgressStatusType)newValue;
114                 instance.UpdateStates();
115             }
116         },
117         defaultValueCreator: (bindable) =>
118         {
119             var instance = (Progress)bindable;
120             return instance.state;
121         });
122
123         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
124         [EditorBrowsable(EditorBrowsableState.Never)]
125         protected ProgressStatusType state = ProgressStatusType.Indeterminate;
126
127         private const float round = 0.5f;
128         private ImageView trackImage = null;
129         private ImageView progressImage = null;
130         private ImageView bufferImage = null;
131         private float maxValue = 100;
132         private float minValue = 0;
133         private float currentValue = 0;
134         private float bufferValue = 0;
135
136         /// <summary>
137         /// The constructor of Progress
138         /// </summary>
139         /// <since_tizen> 6 </since_tizen>
140         public Progress() : base()
141         {
142             Initialize();
143         }
144
145         /// <summary>
146         /// The constructor of the Progress class with specific style.
147         /// </summary>
148         /// <param name="style">style name</param>
149         /// <since_tizen> 6 </since_tizen>
150         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
151         [EditorBrowsable(EditorBrowsableState.Never)]
152         public Progress(string style) : base(style)
153         {
154             Initialize();
155         }
156
157         /// <summary>
158         /// The constructor of the Progress class with specific Attributes.
159         /// </summary>
160         /// <param name="progressStyle">The Attributes object to initialize the Progress.</param>
161         /// <since_tizen> 6 </since_tizen>
162         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
163         [EditorBrowsable(EditorBrowsableState.Never)]
164         public Progress(ProgressStyle progressStyle) : base(progressStyle)
165         {
166             Initialize();
167         }
168
169         /// <summary>
170         /// The status type of the Progress.
171         /// </summary>
172         /// <since_tizen> 6 </since_tizen>
173         public enum ProgressStatusType
174         {
175             /// <summary>
176             /// Show TrackImage
177             /// </summary>
178             /// <since_tizen> 6 </since_tizen>
179             Buffering,
180
181             /// <summary>
182             /// Show ProgressImage
183             /// </summary>
184             /// <since_tizen> 6 </since_tizen>
185             Determinate,
186
187             /// <summary>
188             /// Show LoadingImage
189             /// </summary>
190             /// <since_tizen> 6 </since_tizen>
191             Indeterminate
192         }
193
194         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
195         [EditorBrowsable(EditorBrowsableState.Never)]
196         public new ProgressStyle Style => ViewStyle as ProgressStyle;
197
198         /// <summary>
199         /// The property to get/set Track image object URL of the Progress.
200         /// </summary>
201         /// <since_tizen> 6 </since_tizen>
202         public string TrackImageURL
203         {
204             get
205             {
206                 return Style.Track?.ResourceUrl?.All;
207             }
208             set
209             {
210                 //CreateTrackImageAttributes();
211                 if (Style.Track.ResourceUrl == null)
212                 {
213                     Style.Track.ResourceUrl = new StringSelector();
214                 }
215                 Style.Track.ResourceUrl.All = value;
216                 //RelayoutRequest();
217             }
218         }
219
220         /// <summary>
221         /// The property to get/set Progress object image URL of the Progress.
222         /// </summary>
223         /// <since_tizen> 6 </since_tizen>
224         public string ProgressImageURL
225         {
226             get
227             {
228                 return Style.Progress?.ResourceUrl?.All;
229             }
230             set
231             {
232                 //CreateProgressImageAttributes();
233                 if (Style.Progress.ResourceUrl == null)
234                 {
235                     Style.Progress.ResourceUrl = new StringSelector();
236                 }
237                 Style.Progress.ResourceUrl.All = value;
238                 //RelayoutRequest();
239             }
240         }
241
242         /// <summary>
243         /// The property to get/set Buffer object image resource URL of the Progress.
244         /// </summary>
245         /// <since_tizen> 6 </since_tizen>
246         public string BufferImageURL
247         {
248             get
249             {
250                 return Style.Buffer?.ResourceUrl?.All;
251             }
252             set
253             {
254                 //CreateBufferImageAttributes();
255                 if (Style.Buffer.ResourceUrl == null)
256                 {
257                     Style.Buffer.ResourceUrl = new StringSelector();
258                 }
259                 Style.Buffer.ResourceUrl.All = value;
260                 RelayoutRequest();
261             }
262         }
263
264         /// <summary>
265         /// The property to get/set Track object color of the Progress.
266         /// </summary>
267         /// <since_tizen> 6 </since_tizen>
268         public Color TrackColor
269         {
270             get
271             {
272                 return Style.Track?.BackgroundColor?.All;
273             }
274             set
275             {
276                 //CreateTrackImageAttributes();
277                 if (Style.Track.BackgroundColor == null)
278                 {
279                     Style.Track.BackgroundColor = new ColorSelector();
280                 }
281                 Style.Track.BackgroundColor.All = value;
282                 //RelayoutRequest();
283             }
284         }
285
286         /// <summary>
287         /// The property to get/set Progress object color of the Progress.
288         /// </summary>
289         /// <since_tizen> 6 </since_tizen>
290         public Color ProgressColor
291         {
292             get
293             {
294                 return Style.Progress?.BackgroundColor?.All;
295             }
296             set
297             {
298                 //CreateProgressImageAttributes();
299                 if (null == Style.Progress.BackgroundColor)
300                 {
301                     Style.Progress.BackgroundColor = new ColorSelector();
302                 }
303                 Style.Progress.BackgroundColor.All = value;
304                 //RelayoutRequest();
305             }
306         }
307
308         /// <summary>
309         /// The property to get/set Buffer object color of the Progress.
310         /// </summary>
311         /// <since_tizen> 6 </since_tizen>
312         public Color BufferColor
313         {
314             get
315             {
316                 return Style.Buffer?.BackgroundColor?.All;
317             }
318             set
319             {
320                 //CreateBufferImageAttributes();
321                 if (null == Style.Buffer.BackgroundColor)
322                 {
323                     Style.Buffer.BackgroundColor = new ColorSelector();
324                 }
325                 Style.Buffer.BackgroundColor.All = value;
326                 //RelayoutRequest();
327             }
328         }
329
330         /// <summary>
331         /// The property to get/set the maximum value of the Progress.
332         /// </summary>
333         /// <since_tizen> 6 </since_tizen>
334         public float MaxValue
335         {
336             get
337             {
338                 return (float)GetValue(MaxValueProperty);
339             }
340             set
341             {
342                 SetValue(MaxValueProperty, value);
343             }
344         }
345
346         /// <summary>
347         /// The property to get/set the minim value of the Progress.
348         /// </summary>
349         /// <since_tizen> 6 </since_tizen>
350         public float MinValue
351         {
352             get
353             {
354                 return (float)GetValue(MinValueProperty);
355             }
356             set
357             {
358                 SetValue(MinValueProperty, value);
359             }
360         }
361
362         /// <summary>
363         /// The property to get/set the current value of the Progress.
364         /// </summary>
365         /// <since_tizen> 6 </since_tizen>
366         public float CurrentValue
367         {
368             get
369             {
370                 return (float)GetValue(CurrentValueProperty);
371             }
372             set
373             {
374                 SetValue(CurrentValueProperty, value);
375             }
376         }
377
378         /// <summary>
379         /// The property to get/set the buffer value of the Progress.
380         /// </summary>
381         /// <since_tizen> 6 </since_tizen>
382         public float BufferValue
383         {
384             get
385             {
386                 return (float)GetValue(BufferValueProperty);
387             }
388             set
389             {
390                 SetValue(BufferValueProperty, value);
391             }
392         }
393
394         /// <summary>
395         /// Gets or sets state of progress.
396         /// </summary>
397         /// <since_tizen> 6 </since_tizen>
398         public ProgressStatusType ProgressState
399         {
400             get
401             {
402                 return (ProgressStatusType)GetValue(ProgressStateProperty);
403             }
404             set
405             {
406                 SetValue(ProgressStateProperty, value);
407             }
408         }
409
410         /// <summary>
411         /// Dispose Progress and all children on it.
412         /// </summary>
413         /// <param name="type">Dispose type.</param>
414         /// <since_tizen> 6 </since_tizen>
415         protected override void Dispose(DisposeTypes type)
416         {
417             if (disposed)
418             {
419                 return;
420             }
421
422             if (type == DisposeTypes.Explicit)
423             {
424                 //Called by User
425                 //Release your own managed resources here.
426                 //You should release all of your own disposable objects here.
427                 Utility.Dispose(trackImage);
428                 Utility.Dispose(progressImage);
429                 Utility.Dispose(bufferImage);
430             }
431
432             //You must call base.Dispose(type) just before exit.
433             base.Dispose(type);
434         }
435
436         /// <summary>
437         /// Theme change callback when theme is changed, this callback will be trigger.
438         /// </summary>
439         /// <param name="sender">serder object</param>
440         /// <param name="e">ThemeChangeEventArgs</param>
441         /// <since_tizen> 6 </since_tizen>
442         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
443         [EditorBrowsable(EditorBrowsableState.Never)]
444         protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
445         {
446             ProgressStyle tempStyle = StyleManager.Instance.GetAttributes(style) as ProgressStyle;
447             if (null != tempStyle)
448             {
449                 Style.CopyFrom(tempStyle);
450                 RelayoutRequest();
451             }
452         }
453
454         /// <summary>
455         /// Change Image status. It can be override.
456         /// </summary>
457         /// <since_tizen> 6 </since_tizen>
458         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
459         [EditorBrowsable(EditorBrowsableState.Never)]
460         protected virtual void UpdateStates()
461         {
462             ChangeImageState(state);
463         }
464
465         /// <summary>
466         /// Update progress value
467         /// </summary>
468         /// <since_tizen> 6 </since_tizen>
469         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
470         [EditorBrowsable(EditorBrowsableState.Never)]
471         protected virtual void UpdateValue()
472         {
473             if (null == trackImage || null == progressImage)
474             {
475                 return;
476             }
477
478             if (minValue >= maxValue || currentValue < minValue || currentValue > maxValue)
479             {
480                 return;
481             }
482
483             float width = this.SizeWidth;
484             float height = this.SizeHeight;
485             float progressRatio = (float)(currentValue - minValue) / (float)(maxValue - minValue);
486             float progressWidth = width * progressRatio;
487             progressImage.Size2D = new Size2D((int)(progressWidth + round), (int)height); //Add const round to reach Math.Round function.
488             if (null != bufferImage)
489             {
490                 if (bufferValue < minValue || bufferValue > maxValue)
491                 {
492                     return;
493                 }
494
495                 float bufferRatio = (float)(bufferValue - minValue) / (float)(maxValue - minValue);
496                 float bufferWidth = width * bufferRatio;
497                 bufferImage.Size2D = new Size2D((int)(bufferWidth + round), (int)height); //Add const round to reach Math.Round function.
498             }
499         }
500
501         /// <summary>
502         /// Get Progress attribues.
503         /// </summary>
504         /// <since_tizen> 6 </since_tizen>
505         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
506         [EditorBrowsable(EditorBrowsableState.Never)]
507         protected override ViewStyle GetViewStyle()
508         {
509             return new ProgressStyle();
510         }
511
512         /// <summary>
513         /// Change Image status
514         /// </summary>
515         /// <since_tizen> 6 </since_tizen>
516         /// <param name="statusType">New status type</param>
517         protected void ChangeImageState(ProgressStatusType statusType)
518         {
519             if (state == ProgressStatusType.Buffering)
520             {
521                 bufferImage.Show();
522                 progressImage.Hide();
523             }
524             else if (state == ProgressStatusType.Determinate)
525             {
526                 bufferImage.Hide();
527                 progressImage.Show();
528                 UpdateValue();
529             }
530             else
531             {
532                 bufferImage.Hide();
533                 progressImage.Hide();
534             }
535         }
536
537         private void Initialize()
538         {
539             // create necessary components
540             InitializeTrack();
541             InitializeBuffer();
542             InitializeProgress();
543         }
544
545         private void InitializeTrack()
546         {
547             if (null == trackImage)
548             {
549                 trackImage = new ImageView
550                 {
551                     WidthResizePolicy = ResizePolicyType.FillToParent,
552                     HeightResizePolicy = ResizePolicyType.FillToParent,
553                     PositionUsesPivotPoint = true,
554                     ParentOrigin = NUI.ParentOrigin.TopLeft,
555                     PivotPoint = NUI.PivotPoint.TopLeft
556                 };
557                 Add(trackImage);
558                 trackImage.ApplyStyle(Style.Track);
559             }
560         }
561
562         private void InitializeProgress()
563         {
564             if (null == progressImage)
565             {
566                 progressImage = new ImageView
567                 {
568                     WidthResizePolicy = ResizePolicyType.FillToParent,
569                     HeightResizePolicy = ResizePolicyType.FillToParent,
570                     PositionUsesPivotPoint = true,
571                     ParentOrigin = Tizen.NUI.ParentOrigin.TopLeft,
572                     PivotPoint = Tizen.NUI.PivotPoint.TopLeft
573                 };
574                 Add(progressImage);
575                 progressImage.ApplyStyle(Style.Progress);
576             }
577         }
578
579         private void InitializeBuffer()
580         {
581             if (null == bufferImage)
582             {
583                 bufferImage = new ImageView
584                 {
585                     WidthResizePolicy = ResizePolicyType.FillToParent,
586                     HeightResizePolicy = ResizePolicyType.FillToParent,
587                     PositionUsesPivotPoint = true,
588                     ParentOrigin = Tizen.NUI.ParentOrigin.TopLeft,
589                     PivotPoint = Tizen.NUI.PivotPoint.TopLeft
590                 };
591                 Add(bufferImage);
592                 bufferImage.ApplyStyle(Style.Buffer);
593             }
594         }
595     }
596 }