2 * Copyright(c) 2022 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 System.Collections.Generic;
19 using System.ComponentModel;
20 using System.Diagnostics;
21 using Tizen.NUI.BaseComponents;
22 using Tizen.NUI.Binding;
23 using Tizen.NUI.Accessibility;
25 namespace Tizen.NUI.Components
28 /// The Loading class of nui component. It's used to indicate informs users of the ongoing operation.
31 /// The Loading is created as `LottieAnimationView` first.
32 /// When the user sets ImageArray separately, the image is changed to `ImageVisual`.
34 /// <since_tizen> 6 </since_tizen>
35 public class Loading : Control
38 /// ImageArrayProperty
40 [EditorBrowsable(EditorBrowsableState.Never)]
41 public static readonly BindableProperty ImageArrayProperty = BindableProperty.Create(nameof(ImageArray), typeof(string[]), typeof(Loading), null, propertyChanged: (bindable, oldValue, newValue) =>
43 var instance = (Loading)bindable;
46 instance.InternalImageArray = newValue as string[];
49 defaultValueCreator: (bindable) =>
51 var instance = (Loading)bindable;
52 return instance.InternalImageArray;
55 /// <summary>The ImageList bindable property.</summary>
56 [EditorBrowsable(EditorBrowsableState.Never)]
57 public static readonly BindableProperty ImageListProperty = BindableProperty.Create(nameof(ImageList), typeof(IList<string>), typeof(Loading), null, propertyChanged: (bindable, oldValue, newValue) =>
59 Debug.Assert(((Loading)bindable).imageVisual != null);
61 var newList = newValue as List<string>;
62 ((Loading)bindable).imageVisual.URLS = newList == null ? new List<string>() : newList;
64 defaultValueCreator: (bindable) =>
66 Debug.Assert(((Loading)bindable).imageVisual != null);
67 return ((Loading)bindable).imageVisual.URLS;
69 /// <summary>The lottie resource url bindable property.</summary>
70 [EditorBrowsable(EditorBrowsableState.Never)]
71 public static readonly BindableProperty LottieResourceUrlProperty = BindableProperty.Create(nameof(LottieResourceUrl), typeof(string), typeof(Loading), null, propertyChanged: (bindable, oldValue, newValue) =>
73 var instance = (Loading)bindable;
74 instance.RemoveImageVisual();
75 instance.EnsureLottieView(newValue as string ?? string.Empty);
77 defaultValueCreator: (bindable) =>
79 var lottie = ((Loading)bindable).defaultLottieView;
80 return lottie == null ? string.Empty : lottie.URL;
82 /// <summary>The Size bindable property.</summary>
83 [EditorBrowsable(EditorBrowsableState.Never)]
84 public new static readonly BindableProperty SizeProperty = BindableProperty.Create(nameof(Size), typeof(Size), typeof(Loading), new Size(0, 0), propertyChanged: (bindable, oldValue, newValue) =>
86 var instance = (Loading)bindable;
89 Size size = (Size)newValue;
90 ((View)bindable).Size = size;
93 defaultValueCreator: (bindable) =>
95 var instance = (View)bindable;
98 /// <summary>The FrameRate bindable property.</summary>
99 [EditorBrowsable(EditorBrowsableState.Never)]
100 public static readonly BindableProperty FrameRateProperty = BindableProperty.Create(nameof(FrameRate), typeof(int), typeof(Loading), (int)(1000 / 16.6f), propertyChanged: (bindable, oldValue, newValue) =>
102 var instance = (Loading)bindable;
103 instance.frameRate = (int)newValue;
104 if (0 != instance.frameRate && instance.imageVisual != null) //It will crash if 0
106 instance.imageVisual.FrameDelay = instance.frameRate;
109 defaultValueCreator: (bindable) =>
111 return ((Loading)bindable).frameRate;
114 private const string ImageVisualName = "loadingImageVisual";
115 private AnimatedImageVisual imageVisual = null;
116 private LottieAnimationView defaultLottieView = null;
117 private int frameRate = (int)(1000 / 16.6f);
118 private const float defaultFrameDelay = 16.6f;
119 private static readonly string lottieResource = FrameworkInformation.ResourcePath + "IoT_loading_circle_light.json";
123 /// Actions value to Play animated images.
125 private static int ActionPlay = Interop.AnimatedImageView.AnimatedImageVisualActionPlayGet();
128 /// Actions value to Pause animated images.
130 private static int ActionPause = Interop.AnimatedImageView.AnimatedImageVisualActionPauseGet();
133 /// Actions value to Stop animated images.
135 private static int ActionStop = Interop.AnimatedImageView.AnimatedImageVisualActionStopGet();
140 /// The constructor of Loading.
142 /// <since_tizen> 6 </since_tizen>
143 public Loading() : base()
149 /// Constructor of the Loading class with special style.
151 /// <param name="style">The string to initialize the Loading.</param>
152 /// <since_tizen> 8 </since_tizen>
153 public Loading(string style) : base(style)
159 /// The constructor of the Loading class with specific style.
161 /// <param name="loadingStyle">The style object to initialize the Loading.</param>
162 /// <since_tizen> 8 </since_tizen>
163 public Loading(LoadingStyle loadingStyle) : base(loadingStyle)
169 /// Return currently applied style.
172 /// Modifying contents in style may cause unexpected behaviour.
174 /// <since_tizen> 8 </since_tizen>
175 public LoadingStyle Style => (LoadingStyle)(ViewStyle as LoadingStyle)?.Clone();
178 /// Gets or sets loading image resource array.
179 /// The mutually exclusive with "LottieResourceUrl".
181 /// <since_tizen> 6 </since_tizen>
182 public string[] ImageArray
186 return GetValue(ImageArrayProperty) as string[];
193 SetValue(ImageArrayProperty, value);
194 NotifyPropertyChanged();
197 private string[] InternalImageArray
199 get => (GetValue(ImageListProperty) as List<string>)?.ToArray() ?? null;
200 set => SetValue(ImageListProperty, value == null ? new List<string>() : new List<string>((string[])value));
204 /// Gets loading image resource array.
206 [EditorBrowsable(EditorBrowsableState.Never)]
207 public IList<string> ImageList
211 return GetValue(ImageListProperty) as List<string>;
216 /// Gets or sets an lottie resource url.
217 /// The mutually exclusive with "ImageArray".
219 [EditorBrowsable(EditorBrowsableState.Never)]
220 public string LottieResourceUrl
222 get => GetValue(LottieResourceUrlProperty) as string;
223 set => SetValue(LottieResourceUrlProperty, value);
227 /// Gets or sets loading size.
229 /// <since_tizen> 6 </since_tizen>
234 return (Size)GetValue(SizeProperty);
238 SetValue(SizeProperty, value);
243 /// Gets or sets frame rate of loading.
245 /// <since_tizen> 6 </since_tizen>
250 return (int)GetValue(FrameRateProperty);
254 if (defaultLottieView != null)
256 Tizen.Log.Error("NUI", "Cannot set the frame rate to Lottie Animation. If you want to control it, please set `ImageArray` together.\n");
258 SetValue(FrameRateProperty, value);
263 [EditorBrowsable(EditorBrowsableState.Never)]
264 public override void OnInitialize()
267 AccessibilityRole = Role.ProgressBar;
269 EnsureLottieView(lottieResource);
271 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Trait, "Loading");
275 [EditorBrowsable(EditorBrowsableState.Never)]
276 public override void ApplyStyle(ViewStyle viewStyle)
278 base.ApplyStyle(viewStyle);
280 if (viewStyle is LoadingStyle loadingStyle)
282 if (loadingStyle.Images != null)
284 ImageArray = loadingStyle.Images;
287 if (loadingStyle.LoadingSize != null)
289 Size = loadingStyle.LoadingSize;
295 /// Get Loading style.
297 /// <returns>The default loading style.</returns>
298 /// <since_tizen> 8 </since_tizen>
299 protected override ViewStyle CreateViewStyle()
301 return new LoadingStyle();
307 /// <param name="type">Dispose type.</param>
308 /// <since_tizen> 6 </since_tizen>
309 protected override void Dispose(DisposeTypes type)
316 if (type == DisposeTypes.Explicit)
319 //Release your own managed resources here.
320 //You should release all of your own disposable objects here.
321 RemoveVisual("loadingImageVisual");
323 if (defaultLottieView != null)
325 Utility.Dispose(defaultLottieView);
326 defaultLottieView = null;
330 //You must call base.Dispose(type) just before exit.
335 /// Play Loading Animation.
337 /// <since_tizen> 10 </since_tizen>
340 if (defaultLottieView != null)
342 defaultLottieView.Play();
346 PropertyValue attributes = new PropertyValue(0);
347 this.DoAction(imageVisual.VisualIndex, ActionPlay, attributes);
348 attributes.Dispose();
353 /// Pause Loading Animation.
355 /// <since_tizen> 10 </since_tizen>
358 if (defaultLottieView != null)
360 defaultLottieView.Pause();
364 PropertyValue attributes = new PropertyValue(0);
365 this.DoAction(imageVisual.VisualIndex, ActionPause, attributes);
366 attributes.Dispose();
371 /// Stop Loading Animation.
373 /// <since_tizen> 10 </since_tizen>
376 if (defaultLottieView != null)
378 defaultLottieView.Stop();
382 PropertyValue attributes = new PropertyValue(0);
383 this.DoAction(imageVisual.VisualIndex, ActionStop, attributes);
384 attributes.Dispose();
388 private void Initialize()
390 AccessibilityHighlightable = true;
393 private void EnsureLottieView(string url)
395 if (defaultLottieView != null)
397 if (defaultLottieView.URL == url) return;
398 defaultLottieView.Stop();
400 else Add(defaultLottieView = new LottieAnimationView() { LoopCount = -1 });
402 defaultLottieView.URL = url;
403 defaultLottieView.Play();
406 private void RemoveLottieView()
408 if (defaultLottieView == null) return;
409 defaultLottieView.Stop();
410 defaultLottieView.Dispose();
411 defaultLottieView = null;
414 private void EnsureImageVisual()
416 if (imageVisual == null)
418 imageVisual = new AnimatedImageVisual()
420 URLS = new List<string>(),
421 FrameDelay = defaultFrameDelay,
423 Position = new Vector2(0, 0),
424 Origin = Visual.AlignType.Center,
425 AnchorPoint = Visual.AlignType.Center,
426 SizePolicy = VisualTransformPolicyType.Relative,
427 Size = new Size2D(1, 1)
430 AddVisual(ImageVisualName, imageVisual);
434 private void RemoveImageVisual()
436 if (imageVisual == null) return;
437 RemoveVisual(ImageVisualName);
438 imageVisual.Dispose();