[NUI] test: Add Rive AIAgentLayer Sample
authorTaehyub Kim <taehyub.kim@samsung.com>
Mon, 25 Apr 2022 05:42:54 +0000 (14:42 +0900)
committerJaehyun Cho <jaehyun0cho@gmail.com>
Mon, 4 Jul 2022 07:13:17 +0000 (16:13 +0900)
- resource is updated based on 05.30 version

test/AIAgentLayer/AIAgentLayer.cs [new file with mode: 0644]
test/AIAgentLayer/AIAgentLayer.csproj [new file with mode: 0644]
test/AIAgentLayer/res/agent.riv [new file with mode: 0644]
test/AIAgentLayer/res/mini_a.riv [new file with mode: 0644]
test/AIAgentLayer/res/mini_a_ori.riv [new file with mode: 0755]
test/AIAgentLayer/res/mini_kth.riv [new file with mode: 0755]
test/AIAgentLayer/shared/res/AIAgentLayer.png [new file with mode: 0644]
test/AIAgentLayer/tizen-manifest.xml [new file with mode: 0644]

diff --git a/test/AIAgentLayer/AIAgentLayer.cs b/test/AIAgentLayer/AIAgentLayer.cs
new file mode 100644 (file)
index 0000000..eb7da68
--- /dev/null
@@ -0,0 +1,473 @@
+using System;
+using Tizen.NUI;
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Extension;
+
+namespace AIAgentLayer
+{
+    class Program : NUIApplication
+    {
+        //Define RiveAnimation Variable as Member Variable
+        Tizen.NUI.Extension.RiveAnimationView rav;
+
+        //Control RiveAnimationState Buttons
+        Button inButton, outButton, thinkingButton, okButton, listenButton;
+
+        //Control Position Animation for RiveAnimationView
+        Animation moveAnimation;
+        AlphaFunction alphaFunction;
+        Button topButton, bottomButton, leftButton, centerButton, rightButton;
+        Button leftTopButton, rightTopButton, leftBottomButton, rightBottomButton;
+
+        //In and Out Animation Timer
+        Animation inAnimation;
+        Animation outAnimation;
+        Animation resetEyeAnimation;
+        Animation resetOkAnimation;
+        Animation resetThinkingAnimation;
+        Animation resetListenAnimation;
+
+        void resetEyeFinished(object sender, EventArgs e)
+        {
+            rav.SetAnimationElapsedTime("reset", -1.0f);
+        }
+
+        void resetOkFinished(object sender, EventArgs e)
+        {
+            rav.SetAnimationElapsedTime("thinking", -1.0f);
+            rav.SetAnimationElapsedTime("listen", -1.0f);
+        }
+
+        void resetThinkingFinished(object sender, EventArgs e)
+        {
+            rav.SetAnimationElapsedTime("ok", -1.0f);
+            rav.SetAnimationElapsedTime("listen", -1.0f);
+        }
+
+        void resetListenFinished(object sender, EventArgs e)
+        {
+            rav.SetAnimationElapsedTime("ok", -1.0f);
+            rav.SetAnimationElapsedTime("thinking", -1.0f);
+        }
+
+        void moveAnimationFinished(object sender, EventArgs e)
+        {
+            rav.SetAnimationElapsedTime("reset", 0.0f);
+            rav.SetAnimationElapsedTime("eye 360", -1.0f);
+
+            if (resetEyeAnimation)
+            {
+                resetEyeAnimation.Reset();
+            }
+            else
+            {
+                resetEyeAnimation = new Animation(100);
+                resetEyeAnimation.Finished += resetEyeFinished;
+            }
+            resetEyeAnimation.Play();
+        }
+
+        void inAnimationFinished(object sender, EventArgs e)
+        {
+            rav.SetAnimationElapsedTime("reset", -1.0f);
+            rav.SetAnimationElapsedTime("eye 360", -1.0f);
+            rav.SetAnimationElapsedTime("out", -1.0f);
+            rav.EnableAnimation("in", false);
+            rav.EnableAnimation("idle", true);
+        }
+
+        void outAnimationFinished(object sender, EventArgs e)
+        {
+            rav.SetAnimationElapsedTime("reset", 0.0f);
+            rav.SetAnimationElapsedTime("eye 360", -1.0f);
+            rav.SetAnimationElapsedTime("out", -1.0f);
+            rav.EnableAnimation("out", false);
+            rav.EnableAnimation("idle", false);
+        }
+        void InitializeTimer()
+        {
+            inAnimation = new Animation(1100);
+            inAnimation.Finished += inAnimationFinished;
+            outAnimation = new Animation(900);
+            outAnimation.Finished += outAnimationFinished;
+        }
+
+        protected override void OnCreate()
+        {
+            base.OnCreate();
+            InitializeTimer();
+            Initialize();
+        }
+
+        protected override void OnTerminate()
+        {
+            base.OnTerminate();
+            Destory();
+        }
+        
+        private double CalculateEyeAngle(Vector2 targetPos)
+        {
+            double ravCenterX = rav.PositionX + (rav.Size.Width / 2);
+            double ravCenterY = rav.PositionY + (rav.Size.Height / 2);
+
+            double angle = Math.Atan2(targetPos.Y - ravCenterY, targetPos.X - ravCenterX) * (180.0f / Math.PI);
+            angle += 180.0f;
+            if (angle < 0.0f)
+            {
+                angle = 360.0f + angle;
+            }
+
+            double angleToTime = angle / 180.0f;
+            return angleToTime;
+        }
+
+        private void OnTouchEvent(object source, Window.TouchEventArgs e)
+        {
+            if (e.Touch.GetState(0) == PointStateType.Motion)
+            {
+                //Calibrate Cursor Posiiton to Animation Time
+                Vector2 pos = e.Touch.GetScreenPosition(0);
+                double angleToTime = CalculateEyeAngle(pos);
+
+                //Control eye 360 animation using cursor position
+                rav.SetAnimationElapsedTime("reset", -1.0f);
+                rav.SetAnimationElapsedTime("eye 360", (float)angleToTime);
+            }
+        }
+
+        void ResetMoveAnimation()
+        {
+            //Reset previous moving animation
+            if (moveAnimation)
+            {
+                moveAnimation.Stop();
+                moveAnimation.Dispose();
+            }
+
+            moveAnimation = new Animation(800);
+            var c1 = new Vector2(0.86f, 0.0f);
+            var c2 = new Vector2(0.07f, 1.0f);
+
+            alphaFunction = new AlphaFunction(c1, c2);
+            moveAnimation.DefaultAlphaFunction = alphaFunction;
+            moveAnimation.Finished += moveAnimationFinished;
+        }
+
+        void ApplyMoveAnimation(int X, int Y)
+        {
+            ResetMoveAnimation();
+            Vector2 pos = new Vector2(X, Y);
+            double angleToTime = CalculateEyeAngle(pos);
+            rav.SetAnimationElapsedTime("reset", -1.0f);
+            rav.SetAnimationElapsedTime("eye 360", (float)angleToTime);
+
+            moveAnimation.AnimateTo(rav, "PositionX", pos.X);
+            moveAnimation.AnimateTo(rav, "PositionY", pos.Y);
+            moveAnimation.Play();
+        }
+
+        void Initialize()
+        {
+            Window.Instance.WindowSize = new Size(1920, 1080);
+
+            //Make Window Transparency
+            Window.Instance.BackgroundColor = Color.Transparent;
+            Window.Instance.SetTransparency(true);
+
+            //Ignore Key Events for Receiving remote controller event
+            Window.Instance.SetAcceptFocus(false);
+
+            //Set Window Notification Type
+            Window.Instance.Type = WindowType.Notification;
+
+            //Make Window Notification Level Top
+            Window.Instance.SetNotificationLevel(NotificationLevel.Top);
+
+            Window.Instance.TouchEvent += OnTouchEvent;
+
+            //Create RiveAnimation
+            rav = new Tizen.NUI.Extension.RiveAnimationView(Tizen.Applications.Application.Current.DirectoryInfo.Resource + "mini_a.riv")
+            {
+                Size = new Size(300, 300),
+                Position = new Position( 750, 300)
+            };
+
+            //Enable In Animation
+            rav.EnableAnimation("in", true);
+
+            //Play RiveAnimation 
+            rav.Play();
+            inAnimation.Play();
+
+            inButton = new Button()
+            {
+                Size = new Size(120, 100),
+                Position = new Position(10, 10),
+                Text = "in"
+            };
+            inButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                if (inAnimation)
+                {
+                    inAnimation.Reset();
+                }
+                rav.SetAnimationElapsedTime("reset", -1.0f);
+                rav.SetAnimationElapsedTime("eye 360", -1.0f);
+                rav.SetAnimationElapsedTime("out", 0.0f);
+                rav.EnableAnimation("out", false);
+                rav.EnableAnimation("in", true);
+                inAnimation.Play();
+            };
+
+            outButton = new Button()
+            {
+                Size = new Size(120, 100),
+                Position = new Position(140, 10),
+                Text = "out"
+            };
+            outButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                if (outAnimation)
+                {
+                    outAnimation.Reset();
+                }
+                rav.EnableAnimation("in", false);
+                rav.EnableAnimation("out", true);
+                outAnimation.Play();
+            };
+
+            okButton = new Button()
+            {
+                Size = new Size(120, 100),
+                Position = new Position(10, 120),
+                Text = "ok"
+            };
+            okButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                rav.SetAnimationElapsedTime("reset", -1.0f);
+                rav.SetAnimationElapsedTime("eye 360", -1.0f);
+                //Enable ok animation only
+                rav.SetAnimationElapsedTime("thinking", 0.0f);
+                rav.SetAnimationElapsedTime("listen", 0.0f);
+
+                if (resetOkAnimation)
+                {
+                    resetOkAnimation.Reset();
+                }
+                else
+                {
+                    resetOkAnimation = new Animation(100);
+                    resetOkAnimation.Finished += resetOkFinished;
+                }
+                resetOkAnimation.Play();
+
+                rav.EnableAnimation("thinking", false);
+                rav.EnableAnimation("listen", false);
+                rav.EnableAnimation("ok", true);
+            };
+
+            listenButton = new Button()
+            {
+                Size = new Size(120, 100),
+                Position = new Position(140, 120),
+                Text = "listen"
+            };
+            listenButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                rav.SetAnimationElapsedTime("reset", -1.0f);
+                rav.SetAnimationElapsedTime("eye 360", -1.0f);
+                //Enable listen animation only
+                rav.SetAnimationElapsedTime("ok", 0.0f);
+                rav.SetAnimationElapsedTime("thinking", 0.0f);
+
+                if (resetListenAnimation)
+                {
+                    resetListenAnimation.Reset();
+                }
+                else
+                {
+                    resetListenAnimation = new Animation(100);
+                    resetListenAnimation.Finished += resetListenFinished;
+                }
+                resetListenAnimation.Play();
+
+                rav.EnableAnimation("ok", false);
+                rav.EnableAnimation("thinking", false);
+                rav.EnableAnimation("listen", true);
+            };
+
+            thinkingButton = new Button()
+            {
+                Size = new Size(120, 100),
+                Position = new Position(270, 120),
+                Text = "thinking"
+            };
+            thinkingButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                rav.SetAnimationElapsedTime("reset", -1.0f);
+                rav.SetAnimationElapsedTime("eye 360", -1.0f);
+                //Enable ok animation only
+                rav.SetAnimationElapsedTime("ok", 0.0f);
+                rav.SetAnimationElapsedTime("listen", 0.0f);
+
+                if (resetThinkingAnimation)
+                {
+                    resetThinkingAnimation.Reset();
+                }
+                else
+                {
+                    resetThinkingAnimation = new Animation(100);
+                    resetThinkingAnimation.Finished += resetThinkingFinished;
+                }
+                resetThinkingAnimation.Play();
+
+                rav.EnableAnimation("ok", false);
+                rav.EnableAnimation("listen", false);
+                rav.EnableAnimation("thinking", true);
+            };
+
+            topButton = new Button()
+            {
+                Size = new Size(160, 100),
+                Position = new Position(180, 250),
+                Text = "Move Top"
+            };
+            topButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                ApplyMoveAnimation(750, 0);
+            };
+
+            bottomButton = new Button()
+            {
+                Size = new Size(160, 100),
+                Position = new Position(180, 470),
+                Text = "Move Bottom"
+            };
+            bottomButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                ApplyMoveAnimation(750, 600);
+            };
+
+            leftButton = new Button()
+            {
+                Size = new Size(160, 100),
+                Position = new Position(10, 360),
+                Text = "Move Left"
+            };
+            leftButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                ApplyMoveAnimation(300, 300);
+            };
+
+            centerButton = new Button()
+            {
+                Size = new Size(160, 100),
+                Position = new Position(180, 360),
+                Text = "Move Center"
+            };
+            centerButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                ApplyMoveAnimation(750, 300);
+            };
+
+            rightButton = new Button()
+            {
+                Size = new Size(160, 100),
+                Position = new Position(350, 360),
+                Text = "Move Right"
+            };
+            rightButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                ApplyMoveAnimation(1400, 300);
+            };
+
+            leftTopButton = new Button()
+            {
+                Size = new Size(160, 100),
+                Position = new Position(10, 250),
+                Text = "Left Top"
+            };
+            leftTopButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                ApplyMoveAnimation(300, 0);
+            };
+
+            rightTopButton = new Button()
+            {
+                Size = new Size(160, 100),
+                Position = new Position(350, 250),
+                Text = "Move Right"
+            };
+            rightTopButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                ApplyMoveAnimation(1400, 0);
+            };
+
+            leftBottomButton = new Button()
+            {
+                Size = new Size(160, 100),
+                Position = new Position(10, 470),
+                Text = "Move Right"
+            };
+            leftBottomButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                ApplyMoveAnimation(300, 750);
+            };
+
+            rightBottomButton = new Button()
+            {
+                Size = new Size(160, 100),
+                Position = new Position(350, 470),
+                Text = "Move Right"
+            };
+            rightBottomButton.Clicked += (object source, ClickedEventArgs args) =>
+            {
+                ApplyMoveAnimation(1400, 750);
+            };
+
+            //Add RiveAnimationView and NUI Buttons to Main Window
+            Window.Instance.GetDefaultLayer().Add(rav);
+            Window.Instance.GetDefaultLayer().Add(inButton);
+            Window.Instance.GetDefaultLayer().Add(outButton);
+            Window.Instance.GetDefaultLayer().Add(thinkingButton);
+            Window.Instance.GetDefaultLayer().Add(listenButton);
+            Window.Instance.GetDefaultLayer().Add(okButton);
+            Window.Instance.GetDefaultLayer().Add(topButton);
+            Window.Instance.GetDefaultLayer().Add(bottomButton);
+            Window.Instance.GetDefaultLayer().Add(leftButton);
+            Window.Instance.GetDefaultLayer().Add(centerButton);
+            Window.Instance.GetDefaultLayer().Add(rightButton);
+            Window.Instance.GetDefaultLayer().Add(leftTopButton);
+            Window.Instance.GetDefaultLayer().Add(rightTopButton);
+            Window.Instance.GetDefaultLayer().Add(leftBottomButton);
+            Window.Instance.GetDefaultLayer().Add(rightBottomButton);
+        }
+
+        void Destory()
+        {
+            //Remove RiveAnimationView and NUI Buttons from Main Window
+            Window.Instance.GetDefaultLayer().Remove(rav);
+            Window.Instance.GetDefaultLayer().Remove(inButton);
+            Window.Instance.GetDefaultLayer().Remove(outButton);
+            Window.Instance.GetDefaultLayer().Remove(thinkingButton);
+            Window.Instance.GetDefaultLayer().Remove(listenButton);
+            Window.Instance.GetDefaultLayer().Remove(okButton);
+            Window.Instance.GetDefaultLayer().Remove(topButton);
+            Window.Instance.GetDefaultLayer().Remove(bottomButton);
+            Window.Instance.GetDefaultLayer().Remove(leftButton);
+            Window.Instance.GetDefaultLayer().Remove(centerButton);
+            Window.Instance.GetDefaultLayer().Remove(rightButton);
+            Window.Instance.GetDefaultLayer().Remove(leftTopButton);
+            Window.Instance.GetDefaultLayer().Remove(rightTopButton);
+            Window.Instance.GetDefaultLayer().Remove(leftBottomButton);
+            Window.Instance.GetDefaultLayer().Remove(rightBottomButton);
+        }
+
+        static void Main(string[] args)
+        {
+            var app = new Program();
+            app.Run(args);
+        }
+    }
+}
diff --git a/test/AIAgentLayer/AIAgentLayer.csproj b/test/AIAgentLayer/AIAgentLayer.csproj
new file mode 100644 (file)
index 0000000..ed08816
--- /dev/null
@@ -0,0 +1,27 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <OutputType>Exe</OutputType>
+        <TargetFramework>netcoreapp3.1</TargetFramework>
+    </PropertyGroup>
+
+    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+        <DebugType>portable</DebugType>
+    </PropertyGroup>
+    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+        <DebugType>None</DebugType>
+    </PropertyGroup>
+
+    <ItemGroup>
+        <PackageReference Include="Tizen.NET.Sdk" Version="1.0.9" />
+        <ProjectReference Include="../../src/Tizen/Tizen.csproj" />
+        <ProjectReference Include="../../src/Tizen.NUI.Components/Tizen.NUI.Components.csproj" />
+        <ProjectReference Include="../../src/Tizen.NUI/Tizen.NUI.csproj" />
+        <ProjectReference Include="../../src/Tizen.NUI.Extension/Tizen.NUI.Extension.csproj" />
+    </ItemGroup>
+
+    <PropertyGroup>
+        <NeedInjection>True</NeedInjection>
+    </PropertyGroup>
+
+</Project>
diff --git a/test/AIAgentLayer/res/agent.riv b/test/AIAgentLayer/res/agent.riv
new file mode 100644 (file)
index 0000000..01b2c8b
Binary files /dev/null and b/test/AIAgentLayer/res/agent.riv differ
diff --git a/test/AIAgentLayer/res/mini_a.riv b/test/AIAgentLayer/res/mini_a.riv
new file mode 100644 (file)
index 0000000..1d7d73a
Binary files /dev/null and b/test/AIAgentLayer/res/mini_a.riv differ
diff --git a/test/AIAgentLayer/res/mini_a_ori.riv b/test/AIAgentLayer/res/mini_a_ori.riv
new file mode 100755 (executable)
index 0000000..c7e6e7a
Binary files /dev/null and b/test/AIAgentLayer/res/mini_a_ori.riv differ
diff --git a/test/AIAgentLayer/res/mini_kth.riv b/test/AIAgentLayer/res/mini_kth.riv
new file mode 100755 (executable)
index 0000000..541d80a
Binary files /dev/null and b/test/AIAgentLayer/res/mini_kth.riv differ
diff --git a/test/AIAgentLayer/shared/res/AIAgentLayer.png b/test/AIAgentLayer/shared/res/AIAgentLayer.png
new file mode 100644 (file)
index 0000000..9f3cb98
Binary files /dev/null and b/test/AIAgentLayer/shared/res/AIAgentLayer.png differ
diff --git a/test/AIAgentLayer/tizen-manifest.xml b/test/AIAgentLayer/tizen-manifest.xml
new file mode 100644 (file)
index 0000000..4df4ff6
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="6" package="org.tizen.example.AIAgentLayer" version="1.0.0">
+  <profile name="common" />
+  <ui-application appid="org.tizen.example.AIAgentLayer" exec="AIAgentLayer.dll" type="dotnet" multiple="false" taskmanage="true" nodisplay="false">
+    <icon>AIAgentLayer.png</icon>
+    <label>AIAgentLayer</label>
+    <metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
+  </ui-application>
+  <privileges>
+    <privilege>http://tizen.org/privilege/window.priority.set</privilege>
+  </privileges>
+</manifest>