[NUI] Apply Tizen 7.0 UX on Loading (#4318)
authorSeoyeon2Kim <34738918+Seoyeon2Kim@users.noreply.github.com>
Fri, 22 Jul 2022 11:44:34 +0000 (20:44 +0900)
committerJaehyun Cho <jaehyun0cho@gmail.com>
Mon, 25 Jul 2022 08:33:12 +0000 (17:33 +0900)
- The latest Loading UX has been applied. (Based on API10)
  The image is created as `LottieAnimationView` first.

 - When the user sets ImageArray separately, the image is changed to
  `ImageVisual` as the origin.

Signed-off-by: Seoyeon Kim <seoyeon2.kim@samsung.com>
src/Tizen.NUI.Components/Controls/Loading.cs
src/Tizen.NUI.Components/Style/LoadingStyle.cs
src/Tizen.NUI.Components/res/IoT_loading_circle_light.json [new file with mode: 0755]

index 4e61107..139cd22 100755 (executable)
@@ -27,6 +27,10 @@ namespace Tizen.NUI.Components
     /// <summary>
     /// The Loading class of nui component. It's used to indicate informs users of the ongoing operation.
     /// </summary>
+    /// <remarks>
+    /// The Loading is created as `LottieAnimationView` first.
+    /// When the user sets ImageArray separately, the image is changed to `ImageVisual`.
+    /// </remarks>
     /// <since_tizen> 6 </since_tizen>
     public class Loading : Control
     {
@@ -83,10 +87,8 @@ namespace Tizen.NUI.Components
         public static readonly BindableProperty FrameRateProperty = BindableProperty.Create(nameof(FrameRate), typeof(int), typeof(Loading), (int)(1000 / 16.6f), propertyChanged: (bindable, oldValue, newValue) =>
         {
             var instance = (Loading)bindable;
-            Debug.Assert(instance.imageVisual != null);
-
             instance.frameRate = (int)newValue;
-            if (0 != instance.frameRate) //It will crash if 0
+            if (0 != instance.frameRate && instance.imageVisual != null) //It will crash if 0
             {
                 instance.imageVisual.FrameDelay = instance.frameRate;
             }
@@ -97,7 +99,10 @@ namespace Tizen.NUI.Components
         });
 
         private AnimatedImageVisual imageVisual = null;
+        private LottieAnimationView defaultLottieView = null;
         private int frameRate = (int)(1000 / 16.6f);
+        private const float defaultFrameDelay = 16.6f;
+        private static readonly string lottieResource = FrameworkInformation.ResourcePath + "IoT_loading_circle_light.json";
 
 
         /// <summary>
@@ -167,6 +172,12 @@ namespace Tizen.NUI.Components
             }
             set
             {
+                defaultLottieView?.Stop();
+                defaultLottieView?.Dispose();
+                defaultLottieView = null;
+
+                CreateImageVisual();
+
                 SetValue(ImageArrayProperty, value);
                 NotifyPropertyChanged();
             }
@@ -217,6 +228,10 @@ namespace Tizen.NUI.Components
             }
             set
             {
+                if (defaultLottieView != null)
+                {
+                    Tizen.Log.Error("NUI", "Cannot set the frame rate to Lottie Animation. If you want to control it, please set `ImageArray` together.\n");
+                }
                 SetValue(FrameRateProperty, value);
             }
         }
@@ -228,19 +243,14 @@ namespace Tizen.NUI.Components
             base.OnInitialize();
             AccessibilityRole = Role.ProgressBar;
 
-            imageVisual = new AnimatedImageVisual()
+            defaultLottieView = new LottieAnimationView()
             {
-                URLS = new List<string>(),
-                FrameDelay = 16.6f,
+                URL = lottieResource,
                 LoopCount = -1,
-                Position = new Vector2(0, 0),
-                Origin = Visual.AlignType.Center,
-                AnchorPoint = Visual.AlignType.Center,
-                SizePolicy = VisualTransformPolicyType.Relative,
-                Size = new Size2D(1, 1)
             };
 
-            this.AddVisual("loadingImageVisual", imageVisual);
+            Add(defaultLottieView);
+            defaultLottieView.Play();
 
             AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Trait, "Loading");
         }
@@ -251,13 +261,11 @@ namespace Tizen.NUI.Components
         {
             base.ApplyStyle(viewStyle);
 
-            Debug.Assert(imageVisual != null);
-
             if (viewStyle is LoadingStyle loadingStyle)
             {
                 if (loadingStyle.Images != null)
                 {
-                    imageVisual.URLS = loadingStyle.ImageList as List<string>;
+                    ImageArray = loadingStyle.Images;
                 }
 
                 if (loadingStyle.LoadingSize != null)
@@ -295,6 +303,12 @@ namespace Tizen.NUI.Components
                 //Release your own managed resources here.
                 //You should release all of your own disposable objects here.
                 RemoveVisual("loadingImageVisual");
+
+                if (defaultLottieView != null)
+                {
+                    Utility.Dispose(defaultLottieView);
+                    defaultLottieView = null;
+                }
             }
 
             //You must call base.Dispose(type) just before exit.
@@ -307,9 +321,16 @@ namespace Tizen.NUI.Components
         /// <since_tizen> 10 </since_tizen>
         public void Play()
         {
-            PropertyValue attributes = new PropertyValue(0);
-            this.DoAction(imageVisual.VisualIndex, ActionPlay, attributes);
-            attributes.Dispose();
+            if (defaultLottieView != null)
+            {
+                defaultLottieView.Play();
+            }
+            else
+            {
+                PropertyValue attributes = new PropertyValue(0);
+                this.DoAction(imageVisual.VisualIndex, ActionPlay, attributes);
+                attributes.Dispose();
+            }
         }
 
         /// <summary>
@@ -318,9 +339,16 @@ namespace Tizen.NUI.Components
         /// <since_tizen> 10 </since_tizen>
         public void Pause()
         {
-            PropertyValue attributes = new PropertyValue(0);
-            this.DoAction(imageVisual.VisualIndex, ActionPause, attributes);
-            attributes.Dispose();
+            if (defaultLottieView != null)
+            {
+                defaultLottieView.Pause();
+            }
+            else
+            {
+                PropertyValue attributes = new PropertyValue(0);
+                this.DoAction(imageVisual.VisualIndex, ActionPause, attributes);
+                attributes.Dispose();
+            }
         }
 
         /// <summary>
@@ -329,14 +357,41 @@ namespace Tizen.NUI.Components
         /// <since_tizen> 10 </since_tizen>
         public void Stop()
         {
-            PropertyValue attributes = new PropertyValue(0);
-            this.DoAction(imageVisual.VisualIndex, ActionStop, attributes);
-            attributes.Dispose();
+            if (defaultLottieView != null)
+            {
+                defaultLottieView.Stop();
+            }
+            else
+            {
+                PropertyValue attributes = new PropertyValue(0);
+                this.DoAction(imageVisual.VisualIndex, ActionStop, attributes);
+                attributes.Dispose();
+            }
         }
 
         private void Initialize()
         {
             AccessibilityHighlightable = true;
         }
+
+        private void CreateImageVisual()
+        {
+            if (imageVisual == null)
+            {
+                imageVisual = new AnimatedImageVisual()
+                {
+                    URLS = new List<string>(),
+                    FrameDelay = defaultFrameDelay,
+                    LoopCount = -1,
+                    Position = new Vector2(0, 0),
+                    Origin = Visual.AlignType.Center,
+                    AnchorPoint = Visual.AlignType.Center,
+                    SizePolicy = VisualTransformPolicyType.Relative,
+                    Size = new Size2D(1, 1)
+                };
+
+                AddVisual("loadingImageVisual", imageVisual);
+            }
+        }
     }
 }
index ae77fdd..37ae5c7 100755 (executable)
@@ -62,7 +62,7 @@ namespace Tizen.NUI.Components
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static readonly BindableProperty ImageListProperty = BindableProperty.Create(nameof(ImageList), typeof(IList<string>), typeof(LoadingStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
         {
-            ((LoadingStyle)bindable).images = newValue as List<string>;
+            ((LoadingStyle)bindable).images = newValue == null ? null : newValue as List<string>;
         },
         defaultValueCreator: (bindable) => ((LoadingStyle)bindable).images
         );
@@ -105,10 +105,6 @@ namespace Tizen.NUI.Components
         {
             get
             {
-                if (images == null)
-                {
-                    images = new List<string>();
-                }
                 return GetValue(ImageListProperty) as List<string>;
             }
             internal set => SetValue(ImageListProperty, value);
diff --git a/src/Tizen.NUI.Components/res/IoT_loading_circle_light.json b/src/Tizen.NUI.Components/res/IoT_loading_circle_light.json
new file mode 100755 (executable)
index 0000000..11da9f9
--- /dev/null
@@ -0,0 +1 @@
+{"v":"5.9.0","fr":30,"ip":0,"op":30,"w":200,"h":200,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"LT_small Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0],"e":[-359]},{"t":30}],"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2,"l":2},"a":{"a":0,"k":[100,100,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-14.536,-0.952],[-11.556,-8.867],[-4.682,-13.794],[3.77,-14.07]],"o":[[12.615,-7.283],[14.535,0.953],[11.557,8.868],[4.682,13.793],[0,0]],"v":[[-55.868,-36.091],[-14.226,-45.801],[25.793,-30.739],[50.699,4.018],[52.098,46.753]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.384313755409,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":16,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[119.043,72.309],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"LT_big Outlines","sr":1,"ks":{"o":{"a":0,"k":10,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0],"e":[359]},{"t":30}],"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2,"l":2},"a":{"a":0,"k":[100,100,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[12.112,8.092],[5.574,13.457],[-2.842,14.287],[-10.3,10.3],[-14.287,2.842],[-13.457,-5.574],[-8.093,-12.112],[0,-14.566]],"o":[[-14.567,0],[-12.111,-8.093],[-5.575,-13.458],[2.841,-14.287],[10.3,-10.3],[14.286,-2.842],[13.458,5.574],[8.093,12.111],[0,0]],"v":[[0.714,74.363],[-40.204,61.951],[-67.329,28.898],[-71.521,-13.655],[-51.365,-51.365],[-13.655,-71.521],[28.898,-67.33],[61.951,-40.204],[74.363,0.713]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.384313755409,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":16,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[99.286,99.287],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0}],"markers":[]}