2 * Copyright(c) 2020 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using Tizen.NUI.BaseComponents;
19 using Tizen.NUI.Binding;
20 using Tizen.NUI.Components;
21 using System.ComponentModel;
23 namespace Tizen.NUI.Wearable
26 /// The CircularProgress class of Wearable is used to show the ongoing status with a circular bar.
27 /// CircularProgress can be counted in its percentage.
29 [EditorBrowsable(EditorBrowsableState.Never)]
30 public class CircularProgress : Control
34 /// <summary>Bindable property of Thickness</summary>
35 [EditorBrowsable(EditorBrowsableState.Never)]
36 public static readonly BindableProperty ThicknessProperty = BindableProperty.Create(nameof(Thickness), typeof(float), typeof(CircularProgress), default(float), propertyChanged: (bindable, oldValue, newValue) =>
38 var instance = ((CircularProgress)bindable);
40 // TODO Set viewStyle.Thickness after style refactoring done.
42 instance.UpdateVisualThickness((float)newValue);
44 defaultValueCreator: (bindable) =>
46 return ((CircularProgressStyle)((CircularProgress)bindable).viewStyle)?.Thickness;
49 /// <summary>Bindable property of MaxValue</summary>
50 [EditorBrowsable(EditorBrowsableState.Never)]
51 public static readonly BindableProperty MaxValueProperty = BindableProperty.Create(nameof(MaxValue), typeof(float), typeof(CircularProgress), default(float), propertyChanged: (bindable, oldValue, newValue) =>
53 var instance = (CircularProgress)bindable;
56 instance.maxValue = (float)newValue;
57 instance.UpdateValue();
60 defaultValueCreator: (bindable) =>
62 var instance = (CircularProgress)bindable;
63 return instance.maxValue;
66 /// <summary>Bindable property of MinValue</summary>
67 [EditorBrowsable(EditorBrowsableState.Never)]
68 public static readonly BindableProperty MinValueProperty = BindableProperty.Create(nameof(MinValue), typeof(float), typeof(CircularProgress), default(float), propertyChanged: (bindable, oldValue, newValue) =>
70 var instance = (CircularProgress)bindable;
73 instance.minValue = (float)newValue;
74 instance.UpdateValue();
77 defaultValueCreator: (bindable) =>
79 var instance = (CircularProgress)bindable;
80 return instance.minValue;
83 /// <summary>Bindable property of CurrentValue</summary>
84 [EditorBrowsable(EditorBrowsableState.Never)]
85 public static readonly BindableProperty CurrentValueProperty = BindableProperty.Create("currentValue", typeof(float), typeof(CircularProgress), default(float), propertyChanged: (bindable, oldValue, newValue) =>
87 var instance = (CircularProgress)bindable;
90 if ((float)newValue > instance.maxValue || (float)newValue < instance.minValue)
94 instance.currentValue = (float)newValue;
95 instance.UpdateValue();
98 defaultValueCreator: (bindable) =>
100 var instance = (CircularProgress)bindable;
101 return instance.currentValue;
104 /// <summary>Bindable property of TrackColor</summary>
105 [EditorBrowsable(EditorBrowsableState.Never)]
106 public static readonly BindableProperty TrackColorProperty = BindableProperty.Create("trackColor", typeof(Color), typeof(CircularProgress), null, propertyChanged: (bindable, oldValue, newValue) =>
108 var instance = (CircularProgress)bindable;
110 // TODO : Set viewStyle.TrackColor after style refactoring done.
112 instance.UpdateTrackVisualColor((Color)newValue);
114 defaultValueCreator: (bindable) =>
116 return ((CircularProgressStyle)((CircularProgress)bindable).viewStyle)?.TrackColor;
119 /// <summary>Bindable property of ProgressColor</summary>
120 [EditorBrowsable(EditorBrowsableState.Never)]
121 public static readonly BindableProperty ProgressColorProperty = BindableProperty.Create("progressColor", typeof(Color), typeof(CircularProgress), null, propertyChanged: (bindable, oldValue, newValue) =>
123 var instance = (CircularProgress)bindable;
125 // TODO : Set viewStyle.ProgressColor after style refactoring done.
127 instance.UpdateProgressVisualColor((Color)newValue);
129 defaultValueCreator: (bindable) =>
131 return ((CircularProgressStyle)((CircularProgress)bindable).viewStyle)?.ProgressColor;
134 /// <summary>Bindable property of IsEnabled</summary>
135 [EditorBrowsable(EditorBrowsableState.Never)]
136 public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(CircularProgress), true, propertyChanged: (bindable, oldValue, newValue) =>
138 var instance = (CircularProgress)bindable;
139 if (newValue != null)
141 instance.privateIsEnabled = (bool)newValue;
144 defaultValueCreator: (bindable) =>
146 var instance = (CircularProgress)bindable;
147 return instance.privateIsEnabled;
150 private static readonly string TrackVisualName = "Track";
151 private static readonly string ProgressVisualName = "Progress";
152 private ArcVisual trackVisual;
153 private ArcVisual progressVisual;
155 private float maxValue = 100;
156 private float minValue = 0;
157 private float currentValue = 0;
158 private bool isEnabled = true;
160 private Animation sweepAngleAnimation;
163 /// Get style of progress.
165 [EditorBrowsable(EditorBrowsableState.Never)]
166 public new CircularProgressStyle Style => ViewStyle as CircularProgressStyle;
173 static CircularProgress() { }
175 /// The constructor of CircularProgress.
176 /// Basically, CircularProgress is for full screen. (360 x 360)
177 /// But, it also can be displayed on the button or the list for small size.
178 /// User can set its size.
180 [EditorBrowsable(EditorBrowsableState.Never)]
181 public CircularProgress() : base(new CircularProgressStyle())
187 /// The constructor of the CircularProgress class with specific style.
189 /// <param name="style">style name</param>
190 [EditorBrowsable(EditorBrowsableState.Never)]
191 public CircularProgress(string style) : base(style)
197 /// The constructor of the CircularProgress class with specific style.
199 /// <param name="progressStyle">The style object to initialize the CircularProgress.</param>
200 [EditorBrowsable(EditorBrowsableState.Never)]
201 public CircularProgress(CircularProgressStyle progressStyle) : base(progressStyle)
206 #endregion Constructors
212 /// The thickness of the track and progress.
214 [EditorBrowsable(EditorBrowsableState.Never)]
215 public float Thickness
219 return (float)GetValue(ThicknessProperty);
223 SetValue(ThicknessProperty, value);
228 /// The property to get/set the maximum value of the CircularProgress.
229 /// The default value is 100.
231 [EditorBrowsable(EditorBrowsableState.Never)]
232 public float MaxValue
236 return (float)GetValue(MaxValueProperty);
240 SetValue(MaxValueProperty, value);
245 /// The property to get/set the minimum value of the CircularProgress.
246 /// The default value is 0.
248 [EditorBrowsable(EditorBrowsableState.Never)]
249 public float MinValue
253 return (float)GetValue(MinValueProperty);
257 SetValue(MinValueProperty, value);
262 /// The property to get/set the current value of the CircularProgress.
263 /// The default value is 0.
265 [EditorBrowsable(EditorBrowsableState.Never)]
266 public float CurrentValue
270 return (float)GetValue(CurrentValueProperty);
274 sweepAngleAnimation = AnimateVisual(progressVisual, "sweepAngle", progressVisual.SweepAngle, 0, 100, AlphaFunction.BuiltinFunctions.EaseIn);
276 SetValue(CurrentValueProperty, value);
283 /// The property to get/set Track object color of the CircularProgress.
285 [EditorBrowsable(EditorBrowsableState.Never)]
286 public Color TrackColor
290 return (Color)GetValue(TrackColorProperty);
294 SetValue(TrackColorProperty, value);
299 /// The property to get/set Progress object color of the CircularProgress.
301 [EditorBrowsable(EditorBrowsableState.Never)]
302 public Color ProgressColor
306 return (Color)GetValue(ProgressColorProperty);
310 SetValue(ProgressColorProperty, value);
315 /// Flag to be enabled or disabled in CircularProgress.
317 [EditorBrowsable(EditorBrowsableState.Never)]
318 public bool IsEnabled
322 return (bool)GetValue(IsEnabledProperty);
326 SetValue(IsEnabledProperty, value);
329 private bool privateIsEnabled
340 UpdateTrackVisualColor(new Color(0.0f, 0.16f, 0.30f, 1.0f)); // #002A4D
344 UpdateTrackVisualColor(new Color(0.25f, 0.25f, 0.25f, 1.0f)); // #404040
349 #endregion Properties
356 /// Dispose Progress and all children on it.
358 /// <param name="type">Dispose type.</param>
359 [EditorBrowsable(EditorBrowsableState.Never)]
360 protected override void Dispose(DisposeTypes type)
367 if (type == DisposeTypes.Explicit)
370 progressVisual = null;
377 /// Update progress value
379 [EditorBrowsable(EditorBrowsableState.Never)]
380 protected virtual void UpdateValue()
382 if (null == trackVisual || null == progressVisual)
387 if (minValue >= maxValue || currentValue < minValue || currentValue > maxValue)
392 HandleProgressVisualVisibility();
394 UpdateProgressVisualSweepAngle();
398 /// Get Progress style.
400 /// <returns>The default progress style.</returns>
401 [EditorBrowsable(EditorBrowsableState.Never)]
402 protected override ViewStyle GetViewStyle()
404 return new CircularProgressStyle();
408 private void Initialize()
410 Size = new Size(360.0f, 360.0f);
412 sweepAngleAnimation?.Stop();
413 sweepAngleAnimation = null;
415 trackVisual = new ArcVisual
417 SuppressUpdateVisual = true,
418 Thickness = this.Thickness,
419 Cap = ArcVisual.CapType.Butt,
420 MixColor = TrackColor,
424 this.AddVisual(TrackVisualName, trackVisual);
426 progressVisual = new ArcVisual
428 SuppressUpdateVisual = true,
429 Thickness = this.Thickness,
430 Cap = ArcVisual.CapType.Butt,
431 MixColor = ProgressColor,
435 this.AddVisual(ProgressVisualName, progressVisual);
437 HandleProgressVisualVisibility();
439 UpdateProgressVisualSweepAngle();
442 private void HandleProgressVisualVisibility()
444 if (minValue == currentValue)
446 progressVisual.Opacity = 0.0f;
450 progressVisual.Opacity = 1.0f;
454 progressVisual.Opacity = 0.6f;
458 private void UpdateVisualThickness(float thickness)
460 if (trackVisual == null)
465 trackVisual.Thickness = thickness;
466 progressVisual.Thickness = thickness;
468 trackVisual.UpdateVisual(true);
469 progressVisual.UpdateVisual(true);
472 private void UpdateProgressVisualSweepAngle()
474 float progressRatio = (float)(currentValue - minValue) / (float)(maxValue - minValue);
475 float progressWidth = 360.0f * progressRatio; // Circle
476 progressVisual.SweepAngle = progressWidth;
478 if (!sweepAngleAnimation)
480 progressVisual.UpdateVisual(true);
484 private void UpdateAnimation()
486 // TODO : Currently not sure which effect is needed.
487 AlphaFunction.BuiltinFunctions builtinAlphaFunction = AlphaFunction.BuiltinFunctions.EaseIn;
489 if (sweepAngleAnimation)
491 sweepAngleAnimation?.Stop();
494 sweepAngleAnimation = AnimateVisual(progressVisual, "sweepAngle", progressVisual.SweepAngle, 0, 100, builtinAlphaFunction);
496 if (sweepAngleAnimation)
498 sweepAngleAnimation.Play();
503 private void UpdateTrackVisualColor(Color trackColor)
505 if (trackVisual == null)
510 trackVisual.MixColor = trackColor;
511 trackVisual.UpdateVisual(true);
514 private void UpdateProgressVisualColor(Color progressColor)
516 if (progressVisual == null)
521 progressVisual.MixColor = progressColor;
522 if( !isEnabled ) // Dim state
524 progressVisual.Opacity = 0.6f;
527 progressVisual.UpdateVisual(true);