[NUI.WindowSystem] Introduce the new InputGesture feature
authorduna.oh <duna.oh@samsung.com>
Tue, 28 May 2024 07:53:06 +0000 (16:53 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Fri, 12 Jul 2024 07:31:14 +0000 (16:31 +0900)
supporting Edge Swipe, Edge Drag, Tap, and Palm Cover gestures

src/Tizen.NUI.WindowSystem/src/internal/Interop/Interop.InputGesture.cs [new file with mode: 0644]
src/Tizen.NUI.WindowSystem/src/public/EdgeDragEventArgs.cs [new file with mode: 0644]
src/Tizen.NUI.WindowSystem/src/public/EdgeSwipeEventArgs.cs [new file with mode: 0644]
src/Tizen.NUI.WindowSystem/src/public/InputGesture.cs [new file with mode: 0644]
src/Tizen.NUI.WindowSystem/src/public/PalmCoverEventArgs.cs [new file with mode: 0644]
src/Tizen.NUI.WindowSystem/src/public/TapEventArgs.cs [new file with mode: 0644]
test/Tizen.NUI.WindowSystem.InputGesture/Tizen.NUI.WindowSystem.InputGesture.cs [new file with mode: 0644]
test/Tizen.NUI.WindowSystem.InputGesture/Tizen.NUI.WindowSystem.InputGesture.csproj [new file with mode: 0644]
test/Tizen.NUI.WindowSystem.InputGesture/shared/res/Tizen.NUI.WindowSystem.InputGesture.png [new file with mode: 0644]
test/Tizen.NUI.WindowSystem.InputGesture/tizen-manifest.xml [new file with mode: 0644]
test/Tizen.NUI.WindowSystem.InputGesture/tizen_dotnet_project.yaml [new file with mode: 0644]

diff --git a/src/Tizen.NUI.WindowSystem/src/internal/Interop/Interop.InputGesture.cs b/src/Tizen.NUI.WindowSystem/src/internal/Interop/Interop.InputGesture.cs
new file mode 100644 (file)
index 0000000..f602a00
--- /dev/null
@@ -0,0 +1,93 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tizen.NUI.WindowSystem
+{
+    internal static partial class Interop
+    {
+        internal static class InputGesture
+        {
+            const string lib = "libcapi-ui-efl-util.so.0";
+
+            internal static string LogTag = "Tizen.NUI.WindowSystem";
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_initialize")]
+            internal static extern IntPtr Initialize();
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_deinitialize")]
+            internal static extern ErrorCode Deinitialize(IntPtr gestureHandler);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_edge_swipe_new")]
+            internal static extern IntPtr EdgeSwipeNew(IntPtr gestureHandler, int fingers, int edge);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_edge_swipe_free")]
+            internal static extern ErrorCode EdgeSwipeFree(IntPtr gestureHandler, IntPtr gestureData);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_edge_swipe_size_set")]
+            internal static extern ErrorCode EdgeSwipeSizeSet(IntPtr gestureData, int edgeSize, int startPoint, int endPoint);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_edge_drag_new")]
+            internal static extern IntPtr EdgeDragNew(IntPtr gestureHandler, int fingers, int edge);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_edge_drag_free")]
+            internal static extern ErrorCode EdgeDragFree(IntPtr gestureHandler, IntPtr gestureData);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_edge_drag_size_set")]
+            internal static extern ErrorCode EdgeDragSizeSet(IntPtr gestureData, int edgeSize, int startPoint, int endPoint);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_tap_new")]
+            internal static extern IntPtr TapNew(IntPtr gestureHandler, int fingers, int repeats);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_tap_free")]
+            internal static extern ErrorCode TapFree(IntPtr gestureHandler, IntPtr gestureData);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_palm_cover_new")]
+            internal static extern IntPtr PalmCoverNew(IntPtr gestureHandler);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_palm_cover_free")]
+            internal static extern ErrorCode PalmCoverFree(IntPtr gestureHandler, IntPtr gestureData);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_grab")]
+            internal static extern ErrorCode GestureGrab(IntPtr gestureHandler, IntPtr gestureData);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_ungrab")]
+            internal static extern ErrorCode GestureUngrab(IntPtr gestureHandler, IntPtr gestureData);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_edge_swipe_cb_set")]
+            internal static extern ErrorCode SetEdgeSwipeCb(IntPtr gestureHandler, EdgeSwipeCb cbFunc, IntPtr usergestureData);
+
+            [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+            internal delegate void EdgeSwipeCb(IntPtr usergestureData, int mode, int fingers, int sx, int sy, int edge);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_edge_drag_cb_set")]
+            internal static extern ErrorCode SetEdgeDragCb(IntPtr gestureHandler, EdgeDragCb cbFunc, IntPtr usergestureData);
+
+            [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+            internal delegate void EdgeDragCb(IntPtr usergestureData, int mode, int fingers, int cx, int cy, int edge);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_tap_cb_set")]
+            internal static extern ErrorCode SetTapCb(IntPtr gestureHandler, TapCb cbFunc, IntPtr usergestureData);
+
+            [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+            internal delegate void TapCb(IntPtr usergestureData, int mode, int fingers, int repeats);
+
+            [DllImport(lib, EntryPoint = "efl_util_gesture_palm_cover_cb_set")]
+            internal static extern ErrorCode SetPalmCoverCb(IntPtr gestureHandler, PalmCoverCb cbFunc, IntPtr usergestureData);
+
+            [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+            internal delegate void PalmCoverCb(IntPtr usergestureData, int mode, int duration, int cx, int cy, int size, double pressure);
+
+            internal enum ErrorCode
+            {
+                None = Tizen.Internals.Errors.ErrorCode.None,                            // Successful
+                OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,              // Out of memory
+                InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,    // Invalid parameter
+                InvalidOperation = Tizen.Internals.Errors.ErrorCode.InvalidOperation,    // Invalid operation
+                PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,    // Permission denied
+                NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,            // NOT supported
+            };
+        }
+    }
+}
diff --git a/src/Tizen.NUI.WindowSystem/src/public/EdgeDragEventArgs.cs b/src/Tizen.NUI.WindowSystem/src/public/EdgeDragEventArgs.cs
new file mode 100644 (file)
index 0000000..540df83
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright(c) 2024 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;
+
+namespace Tizen.NUI.WindowSystem
+{
+    /// <summary>
+    /// This class contains the data related to the EdgeDrag event.
+    /// </summary>
+    /// This class is need to be hidden as inhouse API.
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class EdgeDragEventArgs : EventArgs
+    {
+        internal EdgeDragEventArgs(int mode, int fingers, int cx, int cy, int edge)
+        {
+            Mode = mode;
+            Fingers = fingers;
+            Cx = cx;
+            Cy = cy;
+            Edge = edge;
+        }
+        /// <summary>
+        /// Mode
+        /// </summary>
+        public int Mode{ get; internal set; }
+        /// <summary>
+        /// Fingers
+        /// </summary>
+        public int Fingers{ get; internal set;}
+        /// <summary>
+        /// Cx
+        /// </summary>
+        public int Cx{ get; internal set;}
+        /// <summary>
+        /// Cy
+        /// </summary>
+        public int Cy{ get; internal set;}
+        /// <summary>
+        /// Edge
+        /// </summary>
+        public int Edge{ get; internal set;}
+    }
+}
diff --git a/src/Tizen.NUI.WindowSystem/src/public/EdgeSwipeEventArgs.cs b/src/Tizen.NUI.WindowSystem/src/public/EdgeSwipeEventArgs.cs
new file mode 100644 (file)
index 0000000..e782d87
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright(c) 2024 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;
+
+namespace Tizen.NUI.WindowSystem
+{
+    /// <summary>
+    /// This class contains the data related to the EdgeSwipe event.
+    /// </summary>
+    /// This class is need to be hidden as inhouse API.
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class EdgeSwipeEventArgs : EventArgs
+    {
+        internal EdgeSwipeEventArgs(int mode, int fingers, int sx, int sy, int edge)
+        {
+            Mode = mode;
+            Fingers = fingers;
+            Sx = sx;
+            Sy = sy;
+            Edge = edge;
+        }
+        /// <summary>
+        /// Mode
+        /// </summary>
+        public int Mode{ get; internal set; }
+        /// <summary>
+        /// Fingers
+        /// </summary>
+        public int Fingers{ get; internal set;}
+        /// <summary>
+        /// Sx
+        /// </summary>
+        public int Sx{ get; internal set;}
+        /// <summary>
+        /// Sy
+        /// </summary>
+        public int Sy{ get; internal set;}
+        /// <summary>
+        /// Edge
+        /// </summary>
+        public int Edge{ get; internal set;}
+    }
+}
diff --git a/src/Tizen.NUI.WindowSystem/src/public/InputGesture.cs b/src/Tizen.NUI.WindowSystem/src/public/InputGesture.cs
new file mode 100644 (file)
index 0000000..b78fb7a
--- /dev/null
@@ -0,0 +1,578 @@
+/*
+ * Copyright(c) 2024 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 static Tizen.NUI.WindowSystem.Interop.InputGesture;
+
+namespace Tizen.NUI.WindowSystem
+{
+    /// <summary>
+    /// Enumeration of gesture modes.
+    /// </summary>
+    /// This enum is need to be hidden as inhouse API.
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public enum GestureMode
+    {
+        /// <summary>
+        /// None.
+        /// </summary>
+        None,
+
+        /// <summary>
+        /// Begin.
+        /// </summary>
+        Begin,
+
+        /// <summary>
+        /// Update.
+        /// </summary>
+        Update,
+
+        /// <summary>
+        /// End.
+        /// </summary>
+        End,
+
+        /// <summary>
+        /// Done.
+        /// </summary>
+        Done,
+    }
+
+    /// <summary>
+    /// Enumeration of gesture edges.
+    /// </summary>
+    /// This enum is need to be hidden as inhouse API.
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public enum GestureEdge
+    {
+        /// <summary>
+        /// edge none.
+        /// </summary>
+        None,
+
+        /// <summary>
+        /// edge top.
+        /// </summary>
+        Top,
+
+        /// <summary>
+        /// edge right.
+        /// </summary>
+        Right,
+
+        /// <summary>
+        /// edge bottom.
+        /// </summary>
+        Bottom,
+
+        /// <summary>
+        /// edge left.
+        /// </summary>
+        Left,
+    }
+
+    /// <summary>
+    /// Enumeration of gesture edge sizes.
+    /// </summary>
+    /// This enum is need to be hidden as inhouse API.
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public enum GestureEdgeSize
+    {
+        /// <summary>
+        /// edge size none.
+        /// </summary>
+        None,
+
+        /// <summary>
+        /// edge size full.
+        /// </summary>
+        Full,
+
+        /// <summary>
+        /// edge size partial.
+        /// </summary>
+        Partial,
+    }
+
+    /// <summary>
+    /// Class for the Tizen Input Gesture.
+    /// </summary>
+    /// <privilege>
+    /// http://tizen.org/privilege/gesturegrab
+    /// </privilege>
+    /// This class is need to be hidden as inhouse API.
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class InputGesture : IDisposable
+    {
+        private IntPtr _handler;
+        private bool disposed = false;
+        private bool isDisposeQueued = false;
+
+        private event EventHandler<EdgeSwipeEventArgs> _edgeSwipeEventHandler;
+        private EdgeSwipeCb _edgeSwipeDelegate;
+
+        private event EventHandler<EdgeDragEventArgs> _edgeDragEventHandler;
+        private EdgeDragCb _edgeDragDelegate;
+
+        private event EventHandler<TapEventArgs> _tapEventHandler;
+        private TapCb _tapDelegate;
+
+        private event EventHandler<PalmCoverEventArgs> _palmCoverEventHandler;
+        private PalmCoverCb _palmCoverDelegate;
+
+        internal void ErrorCodeThrow(Interop.InputGesture.ErrorCode error)
+        {
+            switch (error)
+            {
+                case Interop.InputGesture.ErrorCode.None :
+                    return;
+                case Interop.InputGesture.ErrorCode.OutOfMemory :
+                    throw new Tizen.Applications.Exceptions.OutOfMemoryException("Out of Memory");
+                case Interop.InputGesture.ErrorCode.InvalidParameter :
+                    throw new ArgumentException("Invalid Parameter");
+                case Interop.InputGesture.ErrorCode.PermissionDenied :
+                    throw new Tizen.Applications.Exceptions.PermissionDeniedException("Permission denied");
+                case Interop.InputGesture.ErrorCode.NotSupported :
+                    throw new NotSupportedException("Not Supported");
+                default :
+                    throw new InvalidOperationException("Unknown Error");
+            }
+        }
+
+        /// <summary>
+        /// Creates a new InputGesture.
+        /// </summary>
+        /// <remarks> This module operates in a NUI application and requires instantiation and disposal on the main thread.</remarks>
+        /// <exception cref="Tizen.Applications.Exceptions.OutOfMemoryException">Thrown when the memory is not enough to allocate.</exception>
+        /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
+        /// <exception cref="Tizen.Applications.Exceptions.PermissionDeniedException">Thrown when the permission is denied.</exception>
+        public InputGesture()
+        {
+            _handler = Interop.InputGesture.Initialize();
+            if (_handler == IntPtr.Zero)
+            {
+                int err = Tizen.Internals.Errors.ErrorFacts.GetLastResult();
+                ErrorCodeThrow((Interop.InputGesture.ErrorCode)err);
+            }
+            Log.Debug(LogTag, "InputGesture Created");
+        }
+
+        /// <summary>
+        /// Destructor.
+        /// </summary>
+        ~InputGesture()
+        {
+            if (!isDisposeQueued)
+            {
+                isDisposeQueued = true;
+                DisposeQueue.Instance.Add(this);
+            }
+        }
+
+        /// <summary>
+        /// Dispose.
+        /// </summary>
+        public void Dispose()
+        {
+            if (isDisposeQueued)
+            {
+                Dispose(DisposeTypes.Implicit);
+            }
+            else
+            {
+                Dispose(DisposeTypes.Explicit);
+                GC.SuppressFinalize(this);
+            }
+        }
+
+        /// <inheritdoc/>
+        protected virtual void Dispose(DisposeTypes type)
+        {
+            if (disposed)
+            {
+                return;
+            }
+
+            if (type == DisposeTypes.Explicit)
+            {
+                //Called by User
+                //Release your own managed resources here.
+                //You should release all of your own disposable objects here.
+            }
+
+            //Release your own unmanaged resources here.
+            //You should not access any managed member here except static instance.
+            //because the execution order of Finalizes is non-deterministic.
+            if (_handler != global::System.IntPtr.Zero)
+            {
+                Interop.InputGesture.ErrorCode res = Interop.InputGesture.Deinitialize(_handler);
+                ErrorCodeThrow(res);
+                _handler = IntPtr.Zero;
+            }
+
+            disposed = true;
+        }
+
+        /// <summary>
+        /// Generates a edge swipe gesture's grab info handle
+        /// </summary>
+        /// <param name="fingers"> The number of fingers </param>
+        /// <param name="edge"> The position of edge</param>
+        /// <returns> The edge swipe gesture data handle </returns>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        /// <exception cref="Tizen.Applications.Exceptions.OutOfMemoryException">Thrown when the memory is not enough to allocate.</exception>
+        public IntPtr CreateEdgeSwipeData(int fingers, GestureEdge edge)
+        {
+            IntPtr edgeSwipeG = IntPtr.Zero;
+            edgeSwipeG = Interop.InputGesture.EdgeSwipeNew(_handler, fingers, (int)edge);
+            if (edgeSwipeG == IntPtr.Zero)
+            {
+                int err = Tizen.Internals.Errors.ErrorFacts.GetLastResult();
+                ErrorCodeThrow((Interop.InputGesture.ErrorCode)err);
+            }
+            Log.Debug(LogTag, "CreateEdgeSwipeData" + "fingers: " + fingers, "edge: " + (int)edge);
+            return edgeSwipeG;
+        }
+
+        /// <summary>
+        /// Frees a memory of edge swipe gesture's grab info handle
+        /// </summary>
+        /// <param name="data"> The edge swipe gesture data handle </param>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        public void ReleaseEdgeSwipeData(IntPtr data)
+        {
+            if (data == IntPtr.Zero)
+            {
+                throw new ArgumentException("EdgeSwipeData is not valid.");
+            }
+            Interop.InputGesture.ErrorCode res = Interop.InputGesture.EdgeSwipeFree(_handler, data);
+            ErrorCodeThrow(res);
+            Log.Debug(LogTag, "ReleaseEdgeSwipeData");
+        }
+
+        /// <summary>
+        /// Sets a specific size of edge for edge swipe gesture
+        /// </summary>
+        /// <param name="data"> The edge swipe gesture data handle </param>
+        /// <param name="edgeSize"> The enum of gesture edge size </param>
+        /// <param name="startPoint"> The start point of edge area </param>
+        /// <param name="endPoint"> The end point of edge area</param>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        public void SetEdgeSwipeSize(IntPtr data, GestureEdgeSize edgeSize, int startPoint, int endPoint)
+        {
+            if (data == IntPtr.Zero)
+            {
+                throw new ArgumentException("EdgeSwipeData is not valid.");
+            }
+            Interop.InputGesture.ErrorCode res = Interop.InputGesture.EdgeSwipeSizeSet(data, (int)edgeSize, startPoint, endPoint);
+            ErrorCodeThrow(res);
+            Log.Debug(LogTag, "SetEdgeSwipeSize" + "size: " + (int)edgeSize + "startPoint: " + startPoint + "endPoint: " + endPoint);
+        }
+
+        /// <summary>
+        /// Generates a edge drag gesture's grab info handle
+        /// </summary>
+        /// <param name="fingers"> The number of fingers </param>
+        /// <param name="edge"> The position of edge</param>
+        /// <returns> The edge drag gesture data handle </returns>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        /// <exception cref="Tizen.Applications.Exceptions.OutOfMemoryException">Thrown when the memory is not enough to allocate.</exception>
+        public IntPtr CreateEdgeDragData(int fingers, GestureEdge edge)
+        {
+            IntPtr edgeDragG = IntPtr.Zero;
+            edgeDragG = Interop.InputGesture.EdgeDragNew(_handler, fingers, (int)edge);
+            if (edgeDragG == IntPtr.Zero)
+            {
+                int err = Tizen.Internals.Errors.ErrorFacts.GetLastResult();
+                ErrorCodeThrow((Interop.InputGesture.ErrorCode)err);
+            }
+            Log.Debug(LogTag, "CreateEdgeDragData" + "fingers: " + fingers, "edge: " + (int)edge);
+            return edgeDragG;
+        }
+
+        /// <summary>
+        /// Frees a memory of edge drag gesture's grab info handle
+        /// </summary>
+        /// <param name="data"> The edge drag gesture data handle </param>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        public void ReleaseEdgeDrageData(IntPtr data)
+        {
+            if (data == IntPtr.Zero)
+            {
+                throw new ArgumentException("EdgeDragData is not valid.");
+            }
+            Interop.InputGesture.ErrorCode res = Interop.InputGesture.EdgeDragFree(_handler, data);
+            ErrorCodeThrow(res);
+            Log.Debug(LogTag, "ReleaseEdgeDrageData");
+        }
+
+        /// <summary>
+        /// Sets a specific size of edge for edge drag gesture
+        /// </summary>
+        /// <param name="data"> The edge drag gesture data handle </param>
+        /// <param name="edgeSize"> The enum of gesture edge size </param>
+        /// <param name="startPoint"> The start point of edge area </param>
+        /// <param name="endPoint"> The end point of edge area</param>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        public void SetEdgeDragSize(IntPtr data, GestureEdgeSize edgeSize, int startPoint, int endPoint)
+        {
+            if (data == IntPtr.Zero)
+            {
+                throw new ArgumentException("EdgeDragData is not valid.");
+            }
+            Interop.InputGesture.ErrorCode res = Interop.InputGesture.EdgeDragSizeSet(data, (int)edgeSize, startPoint, endPoint);
+            ErrorCodeThrow(res);
+            Log.Debug(LogTag, "SetEdgeDragSize" + "size: " + (int)edgeSize + "startPoint: " + startPoint + "endPoint: " + endPoint);
+        }
+
+        /// <summary>
+        /// Generates a tap gesture's grab info handle
+        /// </summary>
+        /// <param name="fingers"> The number of fingers </param>
+        /// <param name="repeats"> The number of repeats</param>
+        /// <returns> The tap gesture data handle </returns>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        /// <exception cref="Tizen.Applications.Exceptions.OutOfMemoryException">Thrown when the memory is not enough to allocate.</exception>
+        public IntPtr CreateTapData(int fingers, int repeats)
+        {
+            IntPtr tapG = IntPtr.Zero;
+            tapG = Interop.InputGesture.TapNew(_handler, fingers, repeats);
+            if (tapG == IntPtr.Zero)
+            {
+                int err = Tizen.Internals.Errors.ErrorFacts.GetLastResult();
+                ErrorCodeThrow((Interop.InputGesture.ErrorCode)err);
+            }
+            Log.Debug(LogTag, "CreateTapData" + "fingers: " + fingers, "repeats: " + repeats);
+            return tapG;
+        }
+
+        /// <summary>
+        /// Frees a memory of tap gesture's grab info handle
+        /// </summary>
+        /// <param name="data"> The tap gesture data handle </param>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        public void ReleaseTapData(IntPtr data)
+        {
+            if (data == IntPtr.Zero)
+            {
+                throw new ArgumentException("tapData is not valid.");
+            }
+            Interop.InputGesture.ErrorCode res = Interop.InputGesture.TapFree(_handler, data);
+            ErrorCodeThrow(res);
+            Log.Debug(LogTag, "ReleaseTapData");
+        }
+
+        /// <summary>
+        /// Generates a palm cover gesture's grab info handle
+        /// </summary>
+        /// <returns> The palm cover gesture data handle </returns>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        /// <exception cref="Tizen.Applications.Exceptions.OutOfMemoryException">Thrown when the memory is not enough to allocate.</exception>
+        public IntPtr CreatePalmCoverData()
+        {
+            IntPtr palmCoverG = IntPtr.Zero;
+            palmCoverG = Interop.InputGesture.PalmCoverNew(_handler);
+            if (palmCoverG == IntPtr.Zero)
+            {
+                int err = Tizen.Internals.Errors.ErrorFacts.GetLastResult();
+                ErrorCodeThrow((Interop.InputGesture.ErrorCode)err);
+            }
+            Log.Debug(LogTag, "CreatePalmCoverData");
+            return palmCoverG;
+        }
+
+        /// <summary>
+        /// Frees a memory of palm cover gesture's grab info handle
+        /// </summary>
+        /// <param name="data"> The palm cover gesture data handle </param>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        public void ReleasePalmCoverData(IntPtr data)
+        {
+            if (data == IntPtr.Zero)
+            {
+                throw new ArgumentException("palmCoverData is not valid.");
+            }
+            Interop.InputGesture.ErrorCode res = Interop.InputGesture.PalmCoverFree(_handler, data);
+            ErrorCodeThrow(res);
+            Log.Debug(LogTag, "ReleasePalmCoverData");
+        }
+
+        /// <summary>
+        /// Grabs a global gesture
+        /// </summary>
+        /// <param name="data">gesture data to grab</param>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        public void GrabGesture(IntPtr data)
+        {
+            if (data == IntPtr.Zero)
+            {
+                throw new ArgumentException("gesture data is not valid.");
+            }
+            Interop.InputGesture.ErrorCode res = Interop.InputGesture.GestureGrab(_handler, data);
+            ErrorCodeThrow(res);
+            Log.Debug(LogTag, "GrabGesture");
+        }
+
+        /// <summary>
+        /// Ungrabs a global gesture.
+        /// </summary>
+        /// <param name="data">gesture data to ungrab</param>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        public void UngrabGesture(IntPtr data)
+        {
+            if (data == IntPtr.Zero)
+            {
+                throw new ArgumentException("gesture data is not valid.");
+            }
+            Interop.InputGesture.ErrorCode res = Interop.InputGesture.GestureUngrab(_handler, data);
+            ErrorCodeThrow(res);
+            Log.Debug(LogTag, "UngrabGesture");
+        }
+
+        /// <summary>
+        /// Emits the event when the edge swipe event comes
+        /// </summary>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        public event EventHandler<EdgeSwipeEventArgs> EdgeSwipeEventHandler
+        {
+            add
+            {
+                if (_edgeSwipeEventHandler == null)
+                {
+                    _edgeSwipeDelegate = (IntPtr userData, int mode,  int fingers, int sx, int sy, int edge) =>
+                    {
+                        EdgeSwipeEventArgs args = new EdgeSwipeEventArgs(mode, fingers, sx, sy, edge);
+                        Log.Debug(LogTag, "EdgeSwipe Event received. mode: " + mode + ", fingers: " + fingers);
+                        _edgeSwipeEventHandler?.Invoke(null, args);
+                    };
+                    Interop.InputGesture.ErrorCode res = Interop.InputGesture.SetEdgeSwipeCb(_handler, _edgeSwipeDelegate, IntPtr.Zero);
+                    ErrorCodeThrow(res);
+                }
+
+                _edgeSwipeEventHandler += value;
+            }
+            remove
+            {
+                _edgeSwipeEventHandler -= value;
+                if (_edgeSwipeEventHandler == null)
+                {
+                    Interop.InputGesture.ErrorCode res = Interop.InputGesture.SetEdgeSwipeCb(_handler, null, IntPtr.Zero);
+                    ErrorCodeThrow(res);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Emits the event when the edge drag event comes
+        /// </summary>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        public event EventHandler<EdgeDragEventArgs> EdgeDragEventHandler
+        {
+            add
+            {
+                if (_edgeDragEventHandler == null)
+                {
+                    _edgeDragDelegate = (IntPtr userData, int mode,  int fingers, int cx, int cy, int edge) =>
+                    {
+                        EdgeDragEventArgs args = new EdgeDragEventArgs(mode, fingers, cx, cy, edge);
+                        Log.Debug(LogTag, "EdgeDrag Event received. mode: " + mode + ", fingers: " + fingers);
+                        _edgeDragEventHandler?.Invoke(null, args);
+                    };
+                    Interop.InputGesture.ErrorCode res = Interop.InputGesture.SetEdgeDragCb(_handler, _edgeDragDelegate, IntPtr.Zero);
+                    ErrorCodeThrow(res);
+                }
+
+                _edgeDragEventHandler += value;
+            }
+            remove
+            {
+                _edgeDragEventHandler -= value;
+                if (_edgeDragEventHandler == null)
+                {
+                    Interop.InputGesture.ErrorCode res = Interop.InputGesture.SetEdgeDragCb(_handler, null, IntPtr.Zero);
+                    ErrorCodeThrow(res);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Emits the event when the tap event comes
+        /// </summary>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        public event EventHandler<TapEventArgs> TapEventHandler
+        {
+            add
+            {
+                if (_tapEventHandler == null)
+                {
+                    _tapDelegate = (IntPtr userData, int mode,  int fingers, int repeats) =>
+                    {
+                        TapEventArgs args = new TapEventArgs(mode, fingers, repeats);
+                        Log.Debug(LogTag, "Tap Event received. mode: " + mode + ", fingers: " + fingers + ", repeats: " + repeats);
+                        _tapEventHandler?.Invoke(null, args);
+                    };
+                    Interop.InputGesture.ErrorCode res = Interop.InputGesture.SetTapCb(_handler, _tapDelegate, IntPtr.Zero);
+                    ErrorCodeThrow(res);
+                }
+
+                _tapEventHandler += value;
+            }
+            remove
+            {
+                _tapEventHandler -= value;
+                if (_tapEventHandler == null)
+                {
+                    Interop.InputGesture.ErrorCode res = Interop.InputGesture.SetTapCb(_handler, null, IntPtr.Zero);
+                    ErrorCodeThrow(res);
+                }
+            }
+        }
+        /// <summary>
+        /// Emits the event when the palm cover event comes
+        /// </summary>
+        /// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
+        public event EventHandler<PalmCoverEventArgs> PalmCoverEventHandler
+        {
+            add
+            {
+                if (_palmCoverEventHandler == null)
+                {
+                    _palmCoverDelegate = (IntPtr userData, int mode,  int duration, int cx, int cy, int size, double pressure) =>
+                    {
+                        PalmCoverEventArgs args = new PalmCoverEventArgs(mode, duration, cx, cy, size, pressure);
+                        Log.Debug(LogTag, "PalmCover Event received. mode: " + mode + ", duration: " + duration);
+                        _palmCoverEventHandler?.Invoke(null, args);
+                    };
+                    Interop.InputGesture.ErrorCode res = Interop.InputGesture.SetPalmCoverCb(_handler, _palmCoverDelegate, IntPtr.Zero);
+                    ErrorCodeThrow(res);
+                }
+                _palmCoverEventHandler += value;
+            }
+            remove
+            {
+                _palmCoverEventHandler -= value;
+                if (_palmCoverEventHandler == null)
+                {
+                    Interop.InputGesture.ErrorCode res = Interop.InputGesture.SetPalmCoverCb(_handler, null, IntPtr.Zero);
+                    ErrorCodeThrow(res);
+                }
+            }
+        }
+    }
+}
diff --git a/src/Tizen.NUI.WindowSystem/src/public/PalmCoverEventArgs.cs b/src/Tizen.NUI.WindowSystem/src/public/PalmCoverEventArgs.cs
new file mode 100644 (file)
index 0000000..f24c051
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright(c) 2024 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;
+
+namespace Tizen.NUI.WindowSystem
+{
+    /// <summary>
+    /// This class contains the data related to the PalmCover event.
+    /// </summary>
+    /// This class is need to be hidden as inhouse API.
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class PalmCoverEventArgs : EventArgs
+    {
+        internal PalmCoverEventArgs(int mode, int duration, int cx, int cy, int size, double pressure)
+        {
+            Mode = mode;
+            Duration = duration;
+            Cx = cx;
+            Cy = cy;
+            Size = size;
+            Pressure = pressure;
+        }
+        /// <summary>
+        /// Mode
+        /// </summary>
+        public int Mode{ get; internal set; }
+        /// <summary>
+        /// Duration
+        /// </summary>
+        public int Duration{ get; internal set;}
+        /// <summary>
+        /// Cx
+        /// </summary>
+        public int Cx{ get; internal set;}
+        /// <summary>
+        /// Cy
+        /// </summary>
+        public int Cy{ get; internal set;}
+        /// <summary>
+        /// Size
+        /// </summary>
+        public double Size{ get; internal set;}
+        /// <summary>
+        /// Pressure
+        /// </summary>
+        public double Pressure{ get; internal set;}
+    }
+}
diff --git a/src/Tizen.NUI.WindowSystem/src/public/TapEventArgs.cs b/src/Tizen.NUI.WindowSystem/src/public/TapEventArgs.cs
new file mode 100644 (file)
index 0000000..4d84557
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright(c) 2024 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;
+
+namespace Tizen.NUI.WindowSystem
+{
+    /// <summary>
+    /// This class contains the data related to the Tap event.
+    /// </summary>
+    /// This class is need to be hidden as inhouse API.
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class TapEventArgs : EventArgs
+    {
+        internal TapEventArgs(int mode, int fingers, int repeats)
+        {
+            Mode = mode;
+            Fingers = fingers;
+            Repeats = repeats;
+        }
+        /// <summary>
+        /// Mode
+        /// </summary>
+        public int Mode{ get; internal set; }
+        /// <summary>
+        /// Fingers
+        /// </summary>
+        public int Fingers{ get; internal set;}
+        /// <summary>
+        /// Repeats
+        /// </summary>
+        public int Repeats{ get; internal set;}
+    }
+}
diff --git a/test/Tizen.NUI.WindowSystem.InputGesture/Tizen.NUI.WindowSystem.InputGesture.cs b/test/Tizen.NUI.WindowSystem.InputGesture/Tizen.NUI.WindowSystem.InputGesture.cs
new file mode 100644 (file)
index 0000000..455bd67
--- /dev/null
@@ -0,0 +1,231 @@
+using System;
+using Tizen;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.WindowSystem;
+using System.Collections.Generic;
+
+namespace Tizen.NUI.WindowSystem
+{
+    class Program : NUIApplication
+    {
+        protected override void OnCreate()
+        {
+            base.OnCreate();
+            Initialize();
+        }
+
+        void Initialize()
+        {
+            Window win = Window.Instance;
+            inputGesture = new InputGesture();
+
+            win.WindowSize = new Size2D(500, 500);
+            win.KeyEvent += OnKeyEvent;
+            win.BackgroundColor = Color.White;
+
+            View windowView = new View();
+            windowView.Size2D = new Size2D(500, 500);
+            windowView.BackgroundColor = Color.White;
+            windowView.TouchEvent += OnTouchEvent;
+            win.Add(windowView);
+
+            centerLabel = new TextLabel("InputGesture Sample, Click to generate Return Key.");
+            centerLabel.HorizontalAlignment = HorizontalAlignment.Center;
+            centerLabel.VerticalAlignment = VerticalAlignment.Center;
+            centerLabel.TextColor = Color.Black;
+            centerLabel.PointSize = 12.0f;
+            centerLabel.HeightResizePolicy = ResizePolicyType.FillToParent;
+            centerLabel.WidthResizePolicy = ResizePolicyType.FillToParent;
+            windowView.Add(centerLabel);
+
+            repeatCounter = 0;
+        }
+
+        private void OnKeyEvent(object sender, Window.KeyEventArgs e)
+        {
+            if (e.Key.State == Key.StateType.Down && (e.Key.KeyPressedName == "XF86Back" || e.Key.KeyPressedName == "Escape"))
+            {
+                Exit();
+            }
+            if (e.Key.State == Key.StateType.Down && e.Key.KeyPressedName == "Return")
+            {
+                repeatCounter++;
+                centerLabel.Text = "Return Key Pressed, counter: " + repeatCounter.ToString();
+            }
+
+            if (e.Key.State == Key.StateType.Down && (e.Key.KeyPressedName == "S" || e.Key.KeyPressedName == "s"))
+            {
+                if (edgeSwipeG == IntPtr.Zero)
+                    edgeSwipeG = inputGesture.CreateEdgeSwipeData(2, GestureEdge.Left);
+
+                if (edgeSwipeG == IntPtr.Zero)
+                {
+                    centerLabel.Text = "'S' Key Pressed. edgeSwipeG NULL!!";
+                    return;
+                }
+
+                if (!edgeSwipeGrabbed)
+                {
+                    inputGesture.GrabGesture(edgeSwipeG);
+                    centerLabel.Text = "'S' Key Pressed. edgeSwipe Grabbed";
+
+                    inputGesture.EdgeSwipeEventHandler += _edgeSwipeEventHandler;
+                    edgeSwipeGrabbed = true;
+                }
+                else
+                {
+                    inputGesture.UngrabGesture(edgeSwipeG);
+                    centerLabel.Text = "'S' Key Pressed. edgeSwipe Ungrabbed";
+                    edgeSwipeGrabbed = false;
+                }
+            }
+            if (e.Key.State == Key.StateType.Down && (e.Key.KeyPressedName == "D" || e.Key.KeyPressedName == "d"))
+            {
+                if (edgeDragG == IntPtr.Zero)
+                    edgeDragG = inputGesture.CreateEdgeDragData(2, GestureEdge.Right);
+
+                if (edgeDragG == IntPtr.Zero)
+                {
+                    centerLabel.Text = "'D' Key Pressed. edgeDrag NULL!!!";
+                    return;
+                }
+
+                if (!edgeDragGrabbed)
+                {
+                    inputGesture.GrabGesture(edgeDragG);
+                    centerLabel.Text = "'D' Key Pressed. edgeDrag Grabbed";
+
+                    inputGesture.EdgeDragEventHandler += _edgeDragEventHandler;
+                    edgeDragGrabbed = true;
+                }
+                else
+                {
+                    inputGesture.UngrabGesture(edgeDragG);
+                    centerLabel.Text = "'D' Key Pressed. edgeDrag Ungrabbed";
+                    edgeDragGrabbed = false;
+                }
+            }
+            if (e.Key.State == Key.StateType.Down && (e.Key.KeyPressedName == "T" || e.Key.KeyPressedName == "t"))
+            {
+                if (tapG == IntPtr.Zero)
+                    tapG = inputGesture.CreateTapData(3, 2);
+
+                if (tapG == IntPtr.Zero)
+                {
+                    centerLabel.Text = "'T' Key Pressed. Tap NULL!!!";
+                    return;
+                }
+
+                if (!tapGrabbed)
+                {
+                    inputGesture.GrabGesture(tapG);
+                    centerLabel.Text = "'T' Key Pressed. Tap Grabbed";
+
+                    inputGesture.TapEventHandler += _tapEventHandler;
+                    tapGrabbed = true;
+                }
+                else
+                {
+                    inputGesture.UngrabGesture(tapG);
+                    centerLabel.Text = "'T' Key Pressed. Tap Ungrabbed";
+                    tapGrabbed = false;
+                }
+            }
+            if (e.Key.State == Key.StateType.Down && (e.Key.KeyPressedName == "P" || e.Key.KeyPressedName == "p"))
+            {
+                if (palmG == IntPtr.Zero)
+                    palmG = inputGesture.CreatePalmCoverData();
+
+                if (palmG == IntPtr.Zero)
+                {
+                    centerLabel.Text = "'P' Key Pressed. PalmCover NULL!!!";
+                    return;
+                }
+
+                if (!palmCoverGrabbed)
+                {
+                    inputGesture.GrabGesture(palmG);
+                    centerLabel.Text = "'P' Key Pressed. PalmCover Grabbed";
+
+                    inputGesture.PalmCoverEventHandler += _palmCoverEventHandler;
+                    palmCoverGrabbed = true;
+                }
+                else
+                {
+                    inputGesture.UngrabGesture(palmG);
+                    centerLabel.Text = "'P' Key Pressed. PalmCover Ungrabbed";
+                    palmCoverGrabbed = false;
+                }
+            }
+        }
+
+        private bool OnTouchEvent(object sender, View.TouchEventArgs e)
+        {
+            touchCounter++;
+            // if (e.Touch.GetState(0) == PointStateType.Down)
+            // {
+            //     centerLabel.Text = "Touch Down";
+            // }
+            // else if (e.Touch.GetState(0) == PointStateType.Up)
+            // {
+            //     centerLabel.Text = "Touch Up";
+            // }
+
+            return true;
+        }
+
+        /// <summary>
+        /// </summary>
+        /// <param name="sender"> The sender object. </param>
+        /// <param name="e"> Argument of Event. </param>
+        private static void _edgeSwipeEventHandler(object sender, EdgeSwipeEventArgs e)
+        {
+            Log.Debug("GestureSample", "Mode: " + (GestureMode)e.Mode + ", Fingers: " + e.Fingers + ", Sx: " + e.Sx + ", Sy: " + e.Sy + ", Edge: " + (GestureEdge)e.Edge);
+        }
+        /// <summary>
+        /// </summary>
+        /// <param name="sender"> The sender object. </param>
+        /// <param name="e"> Argument of Event. </param>
+        private static void _edgeDragEventHandler(object sender, EdgeDragEventArgs e)
+        {
+            Log.Debug("GestureSample", "Mode: " + (GestureMode)e.Mode + ", Fingers: " + e.Fingers + ", Cx: " + e.Cx + ", Cy: " + e.Cy + ", Edge: " + (GestureEdge)e.Edge);
+        }
+        /// <summary>
+        /// </summary>
+        /// <param name="sender"> The sender object. </param>
+        /// <param name="e"> Argument of Event. </param>
+        private static void _tapEventHandler(object sender, TapEventArgs e)
+        {
+            Log.Debug("GestureSample", "Mode: " + (GestureMode)e.Mode + ", Fingers: " + e.Fingers + ", Repeats: " + e.Fingers);
+        }
+        /// <summary>
+        /// </summary>
+        /// <param name="sender"> The sender object. </param>
+        /// <param name="e"> Argument of Event. </param>
+        private static void _palmCoverEventHandler(object sender, PalmCoverEventArgs e)
+        {
+            Log.Debug("GestureSample", "Mode: " + (GestureMode)e.Mode + ", Duration: " + e.Duration + ", Cx: " + e.Cx + ", Cy: " + e.Cy + ", Size: " + e.Size + ", Pressure: " + e.Pressure);
+        }
+
+        static void Main(string[] args)
+        {
+            var app = new Program();
+            app.Run(args);
+        }
+
+        private InputGesture inputGesture;
+        IntPtr edgeSwipeG;
+        IntPtr edgeDragG;
+        IntPtr tapG;
+        IntPtr palmG;
+        private TextLabel centerLabel;
+        int repeatCounter = 0;
+        int touchCounter = 0;
+
+        bool edgeSwipeGrabbed;
+        bool edgeDragGrabbed;
+        bool tapGrabbed;
+        bool palmCoverGrabbed;
+    }
+}
diff --git a/test/Tizen.NUI.WindowSystem.InputGesture/Tizen.NUI.WindowSystem.InputGesture.csproj b/test/Tizen.NUI.WindowSystem.InputGesture/Tizen.NUI.WindowSystem.InputGesture.csproj
new file mode 100644 (file)
index 0000000..c836820
--- /dev/null
@@ -0,0 +1,27 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+      <OutputType>Exe</OutputType>
+      <TargetFramework>netstandard2.0</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.WindowSystem/Tizen.NUI.WindowSystem.csproj" />
+  </ItemGroup>
+
+  <PropertyGroup>
+      <NeedInjection>True</NeedInjection>
+  </PropertyGroup>
+
+</Project>
diff --git a/test/Tizen.NUI.WindowSystem.InputGesture/shared/res/Tizen.NUI.WindowSystem.InputGesture.png b/test/Tizen.NUI.WindowSystem.InputGesture/shared/res/Tizen.NUI.WindowSystem.InputGesture.png
new file mode 100644 (file)
index 0000000..9f3cb98
Binary files /dev/null and b/test/Tizen.NUI.WindowSystem.InputGesture/shared/res/Tizen.NUI.WindowSystem.InputGesture.png differ
diff --git a/test/Tizen.NUI.WindowSystem.InputGesture/tizen-manifest.xml b/test/Tizen.NUI.WindowSystem.InputGesture/tizen-manifest.xml
new file mode 100644 (file)
index 0000000..5c85e42
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="7.0" package="org.tizen.example.InputGesture" version="1.0.0">
+  <profile name="common" />
+  <ui-application appid="org.tizen.example.InputGesture"
+                                       exec="Tizen.NUI.WindowSystem.InputGesture.dll"
+                                       type="dotnet-nui"
+                                       multiple="false"
+                                       taskmanage="true"
+                                       nodisplay="false"
+                                       launch_mode="single"
+                    api-version="10">
+    <label>Tizen.NUI.WindowSystem.InputGesture</label>
+    <icon>Tizen.NUI.WindowSystem.InputGesture.png</icon>
+    <metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
+  </ui-application>
+</manifest>
diff --git a/test/Tizen.NUI.WindowSystem.InputGesture/tizen_dotnet_project.yaml b/test/Tizen.NUI.WindowSystem.InputGesture/tizen_dotnet_project.yaml
new file mode 100644 (file)
index 0000000..cb53adc
--- /dev/null
@@ -0,0 +1,9 @@
+# csproj file path
+csproj_file: Tizen.NUI.WindowSystem.InputGesture.csproj
+
+# files monitored for dirty/modified status
+files:
+  - Tizen.NUI.WindowSystem.InputGesture.csproj
+  - Tizen.NUI.WindowSystem.InputGesture.cs
+  - tizen-manifest.xml
+  - shared/res/Tizen.NUI.WindowSystem.InputGesture.png
\ No newline at end of file