[NUI] Adds Spring Like AlphaFunction for NUI.Animation
authorSeungho Baek <sbsh.baek@samsung.com>
Thu, 8 May 2025 07:43:57 +0000 (16:43 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Wed, 14 May 2025 06:35:12 +0000 (15:35 +0900)
Signed-off-by: Seungho Baek <sbsh.baek@samsung.com>
src/Tizen.NUI/src/internal/Interop/Interop.AlphaFunction.cs
src/Tizen.NUI/src/internal/Interop/Interop.AlphaFunctionSpringData.cs [new file with mode: 0755]
src/Tizen.NUI/src/public/Animation/AlphaFunction.cs
src/Tizen.NUI/src/public/Animation/AlphaFunctionSpringData.cs [new file with mode: 0644]
src/Tizen.NUI/src/public/Animation/AlphaFunctionSpringType.cs [new file with mode: 0644]
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/SpringAlphaFunctionTest.cs [new file with mode: 0755]

index 3ad8664002b41b38d177a575739509e44a1aa5f0..2760fa1fce7f3bb17898602ba268bbea6a682fed 100755 (executable)
@@ -21,26 +21,32 @@ namespace Tizen.NUI
     {
         internal static partial class AlphaFunction
         {
-            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_AlphaFunction__SWIG_0")]
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_AlphaFunction_0")]
             public static extern global::System.IntPtr NewAlphaFunction();
 
-            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_AlphaFunction__SWIG_1")]
-            public static extern global::System.IntPtr NewAlphaFunction(int jarg1);
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_AlphaFunction_BuiltInFunction")]
+            public static extern global::System.IntPtr NewAlphaFunction(int builtInFunction);
 
-            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_AlphaFunction__SWIG_2")]
-            public static extern global::System.IntPtr NewAlphaFunction(global::System.Runtime.InteropServices.HandleRef jarg1);
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_AlphaFunction_CustomAlphaFunction")]
+            public static extern global::System.IntPtr NewAlphaFunction(global::System.Runtime.InteropServices.HandleRef alphaFunction);
 
-            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_AlphaFunction__SWIG_3")]
-            public static extern global::System.IntPtr NewAlphaFunction(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2);
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_AlphaFunction_Bezier")]
+            public static extern global::System.IntPtr NewAlphaFunction(global::System.Runtime.InteropServices.HandleRef controlPoint0, global::System.Runtime.InteropServices.HandleRef controlPoint1);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_AlphaFunction_BuiltInSpring")]
+            public static extern global::System.IntPtr NewAlphaFunctionSpringType(int springType);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_AlphaFunction_CustomSpring")]
+            public static extern global::System.IntPtr NewAlphaFunctionSpringData(float stiffness, float damping, float mass);
 
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_AlphaFunction_GetBezierControlPoints")]
-            public static extern global::System.IntPtr GetBezierControlPoints(global::System.Runtime.InteropServices.HandleRef jarg1);
+            public static extern global::System.IntPtr GetBezierControlPoints(global::System.Runtime.InteropServices.HandleRef alphaFunction);
 
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_AlphaFunction_GetBuiltinFunction")]
-            public static extern int GetBuiltinFunction(global::System.Runtime.InteropServices.HandleRef jarg1);
+            public static extern int GetBuiltinFunction(global::System.Runtime.InteropServices.HandleRef alphaFunction);
 
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_AlphaFunction_GetMode")]
-            public static extern int GetMode(global::System.Runtime.InteropServices.HandleRef jarg1);
+            public static extern int GetMode(global::System.Runtime.InteropServices.HandleRef alphaFunction);
 
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_AlphaFunction")]
             public static extern void DeleteAlphaFunction(global::System.Runtime.InteropServices.HandleRef jarg1);
diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.AlphaFunctionSpringData.cs b/src/Tizen.NUI/src/internal/Interop/Interop.AlphaFunctionSpringData.cs
new file mode 100755 (executable)
index 0000000..2595ac3
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright(c) 2025 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 AlphaFunctionSpringData
+        {
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_AlphaFunctionSpringData_GetDuration")]
+            public static extern float GetDuration(float stiffness, float damping, float mass);
+        }
+    }
+}
index af82a605884a2b11826d3e5b3f009d8a5b1a8e8b..1b0db16ac1aecd3ac2f6510407da3be1edc2c681 100755 (executable)
@@ -96,6 +96,27 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
+        /// <summary>
+        /// Constructor for spring-based AlphaFunction using a predefined SpringType.
+        /// </summary>
+        /// <param name="springType">The spring preset type to use (e.g., Gentle, Quick, etc.).</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public AlphaFunction(AlphaFunctionSpringType springType) : this(Interop.AlphaFunction.NewAlphaFunctionSpringType((int)springType), true)
+        {
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+
+        /// <summary>
+        /// Constructor for spring-based AlphaFunction using custom spring parameters.
+        /// This allows creating a spring easing function with fully customizable physics behavior.
+        /// </summary>
+        /// <param name="springData"> The custom spring configuration (stiffness, damping, mass)</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public AlphaFunction(AlphaFunctionSpringData springData) : this(Interop.AlphaFunction.NewAlphaFunctionSpringData(springData.Stiffness, springData.Damping, springData.Mass), true)
+        {
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+
         internal AlphaFunction(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
@@ -199,10 +220,23 @@ namespace Tizen.NUI
             /// The user has provided a custom function.
             /// </summary>
             CustomFunction,
+
             /// <summary>
             /// The user has provided the control points of a bezier curve.
             /// </summary>
-            Bezier
+            Bezier,
+
+            /// <summary>
+            /// The user has provided the spring type.
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            Spring,
+
+            /// <summary>
+            /// The user has provided the spring data.
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            CustomSpring
         }
 
         internal global::System.Delegate CustomAlphaFunctionDelegate { get; private set; }
diff --git a/src/Tizen.NUI/src/public/Animation/AlphaFunctionSpringData.cs b/src/Tizen.NUI/src/public/Animation/AlphaFunctionSpringData.cs
new file mode 100644 (file)
index 0000000..43b6de1
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright(c) 2025 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.ComponentModel;
+
+namespace Tizen.NUI
+{
+    /// <summary>
+    /// Enumeration for predefined spring animation types.
+    /// This presets are based on typical spring behavior tuned for different motion effects.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class AlphaFunctionSpringData
+    {
+        /// <summary>
+        /// Spring stiffness(Hooke's constant). Higher values make the spring snap back faster. Minimum value is 0.1.
+        /// Default Value is 1.0.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float Stiffness { set; get; } = 1.0f;
+
+        /// <summary>
+        /// Damping coefficient. Controls oscillation and settling. Minimum value is 0.1.
+        /// Default Value is 1.0.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float Damping { set; get; } = 1.0f;
+
+        /// <summary>
+        /// Mass of the object. Affects inertia and the duration of the motion. Minimum value is 0.1.
+        /// Default Value is 1.0.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float Mass { set; get; } = 1.0f;
+
+        public AlphaFunctionSpringData(float stiffness, float damping, float mass)
+        {
+            Stiffness = stiffness;
+            Damping = damping;
+            Mass = mass;
+        }
+
+        /// <summary>
+        /// Returns the time in milliseconds it takes for a Spring Animation to converge based on the AlphaFunctionSpringData.
+        /// The maximum value for the returned duration is 100000 milliseconds(100 seconds).
+        /// Since this value is calculated in an incremental manner, it may take longer if used frequently.
+        /// </summary>
+        /// <returns>Expected duration for input springData.</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int GetDuration()
+        {
+            int duration = (int)(Interop.AlphaFunctionSpringData.GetDuration(Stiffness, Damping, Mass) * 1000.0f);
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+            return duration;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.NUI/src/public/Animation/AlphaFunctionSpringType.cs b/src/Tizen.NUI/src/public/Animation/AlphaFunctionSpringType.cs
new file mode 100644 (file)
index 0000000..2f592f0
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright(c) 2025 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.ComponentModel;
+
+/// <summary>
+/// Enumeration for predefined spring animation types.
+/// This presets are based on typical spring behavior tuned for different motion effects.
+/// </summary>
+[EditorBrowsable(EditorBrowsableState.Never)]
+public enum AlphaFunctionSpringType
+{
+    /// <summary>
+    /// Gentle spring. slower and smoother motion with less oscillation.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    Gentle,
+
+    /// <summary>
+    /// Quick spring, Fast settling animation with minimal overshoot.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    Quick,
+
+    /// <summary>
+    /// Bouncy spring. Highly elastic and oscillatory animation.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    Bouncy,
+
+    /// <summary>
+    /// Slow spring. Smooth and relaxed motion with longer settling.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    Slow
+}
\ No newline at end of file
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/SpringAlphaFunctionTest.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/SpringAlphaFunctionTest.cs
new file mode 100755 (executable)
index 0000000..335448a
--- /dev/null
@@ -0,0 +1,142 @@
+
+using global::System;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using NUnit.Framework;
+
+namespace Tizen.NUI.Samples
+{
+    public class SpringAlphaFunctionTest : IExample
+    {
+        private Window window;
+        private TextLabel mGentle, mQuick, mBouncy, mSlow, mS100D10M1, mS4420D20_8M1, mS1000D10M10;
+        private Animation animationGentle, animationQuick, animationBouncy, animationSlow, animationS100D10M1, animationS4420D20_8M1, animationS1000D10M10;
+
+        public void Activate()
+        {
+            window = NUIApplication.GetDefaultWindow();
+            window.SetBackgroundColor(Color.White);
+
+            View pink = new View()
+            {
+                PositionUsesPivotPoint = true,
+                PivotPoint = PivotPoint.TopLeft,
+                Size = new Size(250.0f, 1000.0f),
+                PositionX = 250.0f,
+                BackgroundColor = Color.Pink
+            };
+            window.Add(pink);
+
+            const float positionDiff = 100.0f;
+            float positionY = 0.0f;
+            mGentle = new TextLabel("Gentle")
+            {
+                PositionUsesPivotPoint = true,
+                PivotPoint = PivotPoint.TopLeft,
+                Name = "Gentle",
+                PositionY = positionY,
+            };
+            window.Add(mGentle);
+            positionY += positionDiff;
+
+            mQuick = new TextLabel("Quick")
+            {
+                PositionUsesPivotPoint = true,
+                PivotPoint = PivotPoint.TopLeft,
+                Name = "Quick",
+                PositionY = positionY,
+            };
+            window.Add(mQuick);
+            positionY += positionDiff;
+
+            mBouncy = new TextLabel("Bouncy")
+            {
+                PositionUsesPivotPoint = true,
+                PivotPoint = PivotPoint.TopLeft,
+                Name = "Bouncy",
+                PositionY = positionY,
+            };
+            window.Add(mBouncy);
+            positionY += positionDiff;
+
+            mSlow = new TextLabel("Slow")
+            {
+                PositionUsesPivotPoint = true,
+                PivotPoint = PivotPoint.TopLeft,
+                Name = "Slow",
+                PositionY = positionY,
+            };
+            window.Add(mSlow);
+            positionY += positionDiff;
+
+            mS100D10M1 = new TextLabel("S100D10M1")
+            {
+                PositionUsesPivotPoint = true,
+                PivotPoint = PivotPoint.TopLeft,
+                Name = "S100D10M1",
+                PositionY = positionY,
+            };
+            window.Add(mS100D10M1);
+            positionY += positionDiff;
+
+            mS4420D20_8M1 = new TextLabel("S4420D20_8M1")
+            {
+                PositionUsesPivotPoint = true,
+                PivotPoint = PivotPoint.TopLeft,
+                Name = "S4420D20_8M1",
+                PositionY = positionY,
+            };
+            window.Add(mS4420D20_8M1);
+            positionY += positionDiff;
+
+            mS1000D10M10 = new TextLabel("S1000D10M10")
+            {
+                PositionUsesPivotPoint = true,
+                PivotPoint = PivotPoint.TopLeft,
+                Name = "S1000D10M10",
+                PositionY = positionY,
+            };
+            window.Add(mS1000D10M10);
+            positionY += positionDiff;
+
+            animationGentle = new Animation(1000);  // Set the longest duration.
+            animationGentle.AnimateTo(mGentle, "PositionX", 500.0f, new AlphaFunction(AlphaFunctionSpringType.Gentle));
+            animationGentle.Looping = true;
+            animationGentle.Play();
+
+            animationQuick = new Animation(1000);  // Set the longest duration.
+            animationQuick.AnimateTo(mQuick, "PositionX", 500.0f, new AlphaFunction(AlphaFunctionSpringType.Quick));
+            animationQuick.Looping = true;
+            animationQuick.Play();
+
+            animationBouncy = new Animation(1000);  // Set the longest duration.
+            animationBouncy.AnimateTo(mBouncy, "PositionX", 500.0f, new AlphaFunction(AlphaFunctionSpringType.Bouncy));
+            animationBouncy.Looping = true;
+            animationBouncy.Play();
+
+            animationSlow = new Animation(1000);  // Set the longest duration.
+            animationSlow.AnimateTo(mSlow, "PositionX", 500.0f, new AlphaFunction(AlphaFunctionSpringType.Slow));
+            animationSlow.Looping = true;
+            animationSlow.Play();
+
+            animationS100D10M1 = new Animation(new AlphaFunctionSpringData(100.0f, 10.0f, 1.0f).GetDuration());  // Set the longest duration.
+            animationS100D10M1.AnimateTo(mS100D10M1, "PositionX", 500.0f, new AlphaFunction(new AlphaFunctionSpringData(100.0f, 10.0f, 1.0f)));
+            animationS100D10M1.Looping = true;
+            animationS100D10M1.Play();
+
+            animationS4420D20_8M1 = new Animation(new AlphaFunctionSpringData(4420.0f, 20.8f, 1.0f).GetDuration());  // Set the longest duration.
+            animationS4420D20_8M1.AnimateTo(mS4420D20_8M1, "PositionX", 500.0f, new AlphaFunction(new AlphaFunctionSpringData(4420.0f, 20.8f, 1.0f)));
+            animationS4420D20_8M1.Looping = true;
+            animationS4420D20_8M1.Play();
+
+            animationS1000D10M10 = new Animation(new AlphaFunctionSpringData(1000.0f, 10.0f, 10.0f).GetDuration());  // Set the longest duration.
+            animationS1000D10M10.AnimateTo(mS1000D10M10, "PositionX", 500.0f, new AlphaFunction(new AlphaFunctionSpringData(1000.0f, 10.0f, 10.0f)));
+            animationS1000D10M10.Looping = true;
+            animationS1000D10M10.Play();
+        }
+
+        public void Deactivate()
+        {
+        }
+    }
+}