5b18b4af6506cc1ac2bc37d91ffdb0c76157ab20
[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         /// Change Image status. It can be override.
430         /// </summary>
431         /// <since_tizen> 6 </since_tizen>
432         /// This needs to be considered more if public-open is necessary.
433         [EditorBrowsable(EditorBrowsableState.Never)]
434         private void UpdateStates()
435         {
436             ChangeImageState(state);
437         }
438
439         /// <summary>
440         /// Update progress value
441         /// </summary>
442         /// <since_tizen> 6 </since_tizen>
443         /// This needs to be considered more if public-open is necessary.
444         [EditorBrowsable(EditorBrowsableState.Never)]
445         private void UpdateValue()
446         {
447             if (null == trackImage || null == progressImage)
448             {
449                 return;
450             }
451
452             if (minValue >= maxValue || currentValue < minValue || currentValue > maxValue)
453             {
454                 return;
455             }
456
457             float width = this.SizeWidth;
458             float height = this.SizeHeight;
459             float progressRatio = (float)(currentValue - minValue) / (float)(maxValue - minValue);
460             float progressWidth = width * progressRatio;
461             progressImage.Size2D = new Size2D((int)(progressWidth + round), (int)height); //Add const round to reach Math.Round function.
462             if (null != bufferImage)
463             {
464                 if (bufferValue < minValue || bufferValue > maxValue)
465                 {
466                     return;
467                 }
468
469                 float bufferRatio = (float)(bufferValue - minValue) / (float)(maxValue - minValue);
470                 float bufferWidth = width * bufferRatio;
471                 bufferImage.Size2D = new Size2D((int)(bufferWidth + round), (int)height); //Add const round to reach Math.Round function.
472             }
473         }
474
475         /// <summary>
476         /// Get Progress style.
477         /// </summary>
478         /// <returns>The default progress style.</returns>
479         /// <since_tizen> 8 </since_tizen>
480         protected override ViewStyle CreateViewStyle()
481         {
482             return new ProgressStyle();
483         }
484
485         /// <summary>
486         /// Change Image status
487         /// </summary>
488         /// <since_tizen> 6 </since_tizen>
489         /// <param name="statusType">New status type</param>
490         protected void ChangeImageState(ProgressStatusType statusType)
491         {
492             if (state == ProgressStatusType.Buffering)
493             {
494                 bufferImage.Show();
495                 progressImage.Hide();
496             }
497             else if (state == ProgressStatusType.Determinate)
498             {
499                 bufferImage.Show();
500                 progressImage.Show();
501                 UpdateValue();
502             }
503             else
504             {
505                 bufferImage.Hide();
506                 progressImage.Hide();
507             }
508         }
509
510         private void Initialize()
511         {
512             // create necessary components
513             InitializeTrack();
514             InitializeBuffer();
515             InitializeProgress();
516         }
517
518         private void InitializeTrack()
519         {
520             if (null == trackImage)
521             {
522                 trackImage = new ImageView
523                 {
524                     WidthResizePolicy = ResizePolicyType.FillToParent,
525                     HeightResizePolicy = ResizePolicyType.FillToParent,
526                     PositionUsesPivotPoint = true,
527                     ParentOrigin = NUI.ParentOrigin.TopLeft,
528                     PivotPoint = NUI.PivotPoint.TopLeft
529                 };
530                 Add(trackImage);
531                 trackImage.ApplyStyle(progressStyle.Track);
532             }
533         }
534
535         private void InitializeProgress()
536         {
537             if (null == progressImage)
538             {
539                 progressImage = new ImageView
540                 {
541                     WidthResizePolicy = ResizePolicyType.FillToParent,
542                     HeightResizePolicy = ResizePolicyType.FillToParent,
543                     PositionUsesPivotPoint = true,
544                     ParentOrigin = Tizen.NUI.ParentOrigin.TopLeft,
545                     PivotPoint = Tizen.NUI.PivotPoint.TopLeft
546                 };
547                 Add(progressImage);
548                 progressImage.ApplyStyle(progressStyle.Progress);
549             }
550         }
551
552         private void InitializeBuffer()
553         {
554             if (null == bufferImage)
555             {
556                 bufferImage = new ImageView
557                 {
558                     WidthResizePolicy = ResizePolicyType.FillToParent,
559                     HeightResizePolicy = ResizePolicyType.FillToParent,
560                     PositionUsesPivotPoint = true,
561                     ParentOrigin = Tizen.NUI.ParentOrigin.TopLeft,
562                     PivotPoint = Tizen.NUI.PivotPoint.TopLeft
563                 };
564                 Add(bufferImage);
565                 bufferImage.ApplyStyle(progressStyle.Buffer);
566             }
567         }
568     }
569 }