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