[NUI] BaseComponent: Add RiveAnimationView Component.
authorTaehyub Kim <taehyub.kim@samsung.com>
Mon, 28 Jun 2021 11:32:58 +0000 (20:32 +0900)
committerSangHyeon Jade Lee <dltkdgus1764@gmail.com>
Mon, 5 Jul 2021 09:51:44 +0000 (18:51 +0900)
RiveAnimationView shows and control the rive animations which are vector graphics based animation.
Also RiveAnimationView allows the user interaction and user customizing development
such as runtime animation change, runtime user interaction and runtime vector property change.

Classes
 Tizen.NUI.BaseComponents.RiveAnimationView

Dependency
 dali-csharp-binder: https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-csharp-binder/+/260537/
 dali-extension: https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-extension/+/260151/
 rive-tizen: https://review.tizen.org/gerrit/#/admin/projects/platform/core/uifw/rive-tizen

NUI Example
 test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/RiveAnimationTest.cs

Native Example
 dali-demo: https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-demo/+/260175/

src/Tizen.NUI/src/internal/Interop/Interop.RiveAnimationView.cs [new file with mode: 0755]
src/Tizen.NUI/src/public/BaseComponents/RiveAnimationView.cs [new file with mode: 0755]
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/RiveAnimationTest.cs [new file with mode: 0755]
test/Tizen.NUI.Samples/Tizen.NUI.Samples/res/buggy.riv [new file with mode: 0644]

diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.RiveAnimationView.cs b/src/Tizen.NUI/src/internal/Interop/Interop.RiveAnimationView.cs
new file mode 100755 (executable)
index 0000000..6729f3b
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Tizen.NUI
+{
+    internal static partial class Interop
+    {
+        internal static partial class RiveAnimationView
+        {
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_RiveAnimationView_New__SWIG_0")]
+            public static extern global::System.IntPtr New(string jarg1);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_RiveAnimationView_EnableAnimation")]
+            public static extern void EnableAnimation(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, bool jarg3);
+            
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_RiveAnimationView_SetShapeFillColor")]
+            public static extern void SetShapeFillColor(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, global::System.Runtime.InteropServices.HandleRef jarg3);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_RiveAnimationView_SetShapeStrokeColor")]
+            public static extern void SetShapeStrokeColor(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, global::System.Runtime.InteropServices.HandleRef jarg3);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_RiveAnimationView_SetNodeOpacity")]
+            public static extern void SetNodeOpacity(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, float jarg3);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_RiveAnimationView_SetNodeScale")]
+            public static extern void SetNodeScale(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, global::System.Runtime.InteropServices.HandleRef jarg3);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_RiveAnimationView_SetNodeRotation")]
+            public static extern void SetNodeRotation(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, global::System.Runtime.InteropServices.HandleRef jarg3);
+            
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_RiveAnimationView_SetNodePosition")]
+            public static extern void SetNodePosition(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, global::System.Runtime.InteropServices.HandleRef jarg3);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_RiveAnimationView_PlayAnimation")]
+            public static extern void PlayAnimation(global::System.Runtime.InteropServices.HandleRef jarg1);
+            
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_RiveAnimationView_PauseAnimation")]
+            public static extern void PauseAnimation(global::System.Runtime.InteropServices.HandleRef jarg1);
+            
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_RiveAnimationView_StopAnimation")]
+            public static extern void StopAnimation(global::System.Runtime.InteropServices.HandleRef jarg1);
+        }
+    }
+}
diff --git a/src/Tizen.NUI/src/public/BaseComponents/RiveAnimationView.cs b/src/Tizen.NUI/src/public/BaseComponents/RiveAnimationView.cs
new file mode 100755 (executable)
index 0000000..7afc4a3
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+* Copyright(c) 2021 Samsung Electronics Co., Ltd.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+using System;
+using System.ComponentModel;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Tizen.NUI.BaseComponents
+{
+    /// <summary>
+    /// RiveAnimationView renders an animated vector image (Rive file).
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class RiveAnimationView : View
+    {
+        static RiveAnimationView() { }
+
+        /// <summary>
+        /// RiveAnimationView constructor.
+        /// </summary>
+        /// <param name="url">The rive resource URL</param>
+        ///[EditorBrowsable(EditorBrowsableState.Never)]
+        public RiveAnimationView(string url) : this(Interop.RiveAnimationView.New(url), true)
+        {
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+
+        internal RiveAnimationView(global::System.IntPtr cPtr, bool shown = true) : base(cPtr, shown)
+        {
+            if (!shown)
+            {
+                SetVisible(false);
+            }
+        }
+
+        /// <summary>
+        /// Eanables the given animation.
+        /// </summary>
+        /// <param name="animationName">The animation to enable</param>
+        /// <param name="on">The enable state of given animation</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void EnableAnimation(string animationName, bool on)
+        {
+            Interop.RiveAnimationView.EnableAnimation(SwigCPtr, animationName, on);
+        }
+
+        /// <summary>
+        /// Play animation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void PlayAnimation()
+        {
+            Interop.RiveAnimationView.PlayAnimation(SwigCPtr);
+        }
+
+        /// <summary>
+        /// Pause animation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void PauseAnimation()
+        {
+            Interop.RiveAnimationView.PauseAnimation(SwigCPtr);
+        }
+
+        /// <summary>
+        /// Stop animation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void StopAnimation()
+        {
+            Interop.RiveAnimationView.StopAnimation(SwigCPtr);
+        }
+
+        /// <summary>
+        /// Sets the fill color of given fill.
+        /// </summary>
+        /// <param name="shapeFillName">The shape fill name</param>
+        /// <param name="color">The rgba color</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SetShapeFillColor(string shapeFillName, Color color)
+        {
+            if (color == null)
+                 throw new ArgumentNullException(nameof(color));
+            Interop.RiveAnimationView.SetShapeFillColor(SwigCPtr, shapeFillName, color.SwigCPtr);
+        }
+
+        /// <summary>
+        /// Sets the shape stroke color of given stroke.
+        /// </summary>
+        /// <param name="shapeStrokeName">The shape stroke name</param>
+        /// <param name="color">The rgba color</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SetShapeStrokeColor(string shapeStrokeName, Color color)
+        {
+            if (color == null)
+                 throw new ArgumentNullException(nameof(color));
+            Interop.RiveAnimationView.SetShapeStrokeColor(SwigCPtr, shapeStrokeName, color.SwigCPtr);
+        }
+
+        /// <summary>
+        /// Sets the opacity of given node.
+        /// </summary>
+        /// <param name="nodeName">The node name</param>
+        /// <param name="opacity">The opacity of given node</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SetNodeOpacity(string nodeName, float opacity)
+        {
+            Interop.RiveAnimationView.SetNodeOpacity(SwigCPtr, nodeName, opacity);
+        }
+
+        /// <summary>
+        /// Sets the scale of given node.
+        /// </summary>
+        /// <param name="nodeName">The node name</param>
+        /// <param name="scale">The scale of given node</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SetNodeScale(string nodeName, Vector2 scale)
+        {
+            if (scale == null)
+                 throw new ArgumentNullException(nameof(scale));
+            Interop.RiveAnimationView.SetNodeScale(SwigCPtr, nodeName, Vector2.getCPtr(scale));
+        }
+
+        /// <summary>
+        /// Sets the rotation of given node.
+        /// </summary>
+        /// <param name="nodeName">The node name</param>
+        /// <param name="degree">The degree of given node</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SetNodeRotation(string nodeName, Degree degree)
+        {            
+            if (degree == null)
+                 throw new ArgumentNullException(nameof(degree));
+            Interop.RiveAnimationView.SetNodeRotation(SwigCPtr, nodeName, Degree.getCPtr(degree));
+        }
+
+        /// <summary>
+        /// Sets the position of given node.
+        /// </summary>
+        /// <param name="nodeName">The node name</param>
+        /// <param name="position">The position of given node</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SetNodePosition(string nodeName, Position position)
+        {
+            if (position == null)
+                 throw new ArgumentNullException(nameof(position));
+            Interop.RiveAnimationView.SetNodePosition(SwigCPtr, nodeName, position.SwigCPtr);
+        }
+    }
+}
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/RiveAnimationTest.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/RiveAnimationTest.cs
new file mode 100755 (executable)
index 0000000..b141b39
--- /dev/null
@@ -0,0 +1,168 @@
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+
+namespace Tizen.NUI.Samples
+{
+    public class RiveAnimationTest : IExample
+    {
+        private Window window;
+        private Layer defaultLayer;
+
+        RiveAnimationView rav;
+        Button playButton, stopButton;
+        Button bounceButton, brokeButton;
+        Button fillButton, strokeButton, opacityButton;
+        Button scaleButton, rotationButton, positionButton;
+        public void Activate()
+        {
+            window = NUIApplication.GetDefaultWindow();
+            defaultLayer = window.GetDefaultLayer();
+
+            rav = new RiveAnimationView(Tizen.Applications.Application.Current.DirectoryInfo.Resource + "buggy.riv")
+            {
+                Size = new Size(500, 500),
+                ParentOrigin = ParentOrigin.Center,
+                PivotPoint = PivotPoint.Center,
+                PositionUsesPivotPoint = true,
+            };
+
+            rav.EnableAnimation("idle", true);
+
+            playButton = new Button()
+            {
+                Size = new Size(200, 100),
+                Position = new Position(0, 0),
+                Text = "Play"
+            };
+            playButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                rav.PlayAnimation();
+            };
+
+            stopButton = new Button()
+            {
+                Size = new Size(200, 100),
+                Position = new Position(200, 0),
+                Text = "Stop"
+            };
+            stopButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                rav.StopAnimation();
+            };
+
+            bounceButton = new Button()
+            {
+                Size = new Size(200, 100),
+                Position = new Position(0, 100),
+                Text = "Bounce"
+            };
+            bounceButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                rav.EnableAnimation("bouncing", true);
+            };
+
+            brokeButton = new Button()
+            {
+                Size = new Size(200, 100),
+                Position = new Position(200, 100),
+                Text = "Broken"
+            };
+            brokeButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                rav.EnableAnimation("broken", true);
+            };
+
+            fillButton = new Button()
+            {
+                Size = new Size(200, 100),
+                Position = new Position(0, 200),
+                Text = "Fill"
+            };
+            fillButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                rav.SetShapeFillColor("grillFillColor", new Color(1.0f, 0.0f, 0.0f, 1.0f));
+            };
+
+            strokeButton = new Button()
+            {
+                Size = new Size(200, 100),
+                Position = new Position(200, 200),
+                Text = "Stroke"
+            };
+            strokeButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                rav.SetShapeStrokeColor("grillStrokeColor", new Color(0.0f, 255.0f, 0.0f, 255.0f));
+            };
+
+            opacityButton = new Button()
+            {
+                Size = new Size(200, 100),
+                Position = new Position(400, 200),
+                Text = "Opacity"
+            };
+            opacityButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                rav.SetNodeOpacity("front_light", 0.3f);
+            };
+
+            scaleButton = new Button()
+            {
+                Size = new Size(200, 100),
+                Position = new Position(0, 300),
+                Text = "Scale"
+            };
+            scaleButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                rav.SetNodeScale("front_light", new Vector2(2.0f, 2.0f));
+            };
+
+            rotationButton = new Button()
+            {
+                Size = new Size(200, 100),
+                Position = new Position(200, 300),
+                Text = "Rotation"
+            };
+            rotationButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                rav.SetNodeRotation("front_light", new Degree(45.0f));
+            };
+
+            positionButton = new Button()
+            {
+                Size = new Size(200, 100),
+                Position = new Position(400, 300),
+                Text = "Position"
+            };
+            positionButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                rav.SetNodePosition("front_light", new Position(100.0f, -50.0f));
+            };
+
+            defaultLayer.Add(rav);
+            defaultLayer.Add(playButton);
+            defaultLayer.Add(stopButton);
+            defaultLayer.Add(bounceButton);
+            defaultLayer.Add(brokeButton);
+            defaultLayer.Add(fillButton);
+            defaultLayer.Add(strokeButton);
+            defaultLayer.Add(opacityButton);
+            defaultLayer.Add(scaleButton);
+            defaultLayer.Add(rotationButton);
+            defaultLayer.Add(positionButton);
+        }
+        public void Deactivate()
+        {
+            defaultLayer.Remove(rav);
+            defaultLayer.Remove(playButton);
+            defaultLayer.Remove(stopButton);
+            defaultLayer.Remove(bounceButton);
+            defaultLayer.Remove(brokeButton);
+            defaultLayer.Remove(fillButton);
+            defaultLayer.Remove(strokeButton);
+            defaultLayer.Remove(opacityButton);
+            defaultLayer.Remove(scaleButton);
+            defaultLayer.Remove(rotationButton);
+            defaultLayer.Remove(positionButton);
+        }
+    }
+}
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/res/buggy.riv b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/res/buggy.riv
new file mode 100644 (file)
index 0000000..3a4227b
Binary files /dev/null and b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/res/buggy.riv differ