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 index 00000000000..f602a008881 --- /dev/null +++ b/src/Tizen.NUI.WindowSystem/src/internal/Interop/Interop.InputGesture.cs @@ -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 index 00000000000..540df835ce1 --- /dev/null +++ b/src/Tizen.NUI.WindowSystem/src/public/EdgeDragEventArgs.cs @@ -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 +{ + /// + /// This class contains the data related to the EdgeDrag event. + /// + /// 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; + } + /// + /// Mode + /// + public int Mode{ get; internal set; } + /// + /// Fingers + /// + public int Fingers{ get; internal set;} + /// + /// Cx + /// + public int Cx{ get; internal set;} + /// + /// Cy + /// + public int Cy{ get; internal set;} + /// + /// Edge + /// + 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 index 00000000000..e782d87d825 --- /dev/null +++ b/src/Tizen.NUI.WindowSystem/src/public/EdgeSwipeEventArgs.cs @@ -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 +{ + /// + /// This class contains the data related to the EdgeSwipe event. + /// + /// 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; + } + /// + /// Mode + /// + public int Mode{ get; internal set; } + /// + /// Fingers + /// + public int Fingers{ get; internal set;} + /// + /// Sx + /// + public int Sx{ get; internal set;} + /// + /// Sy + /// + public int Sy{ get; internal set;} + /// + /// Edge + /// + 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 index 00000000000..b78fb7a269b --- /dev/null +++ b/src/Tizen.NUI.WindowSystem/src/public/InputGesture.cs @@ -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 +{ + /// + /// Enumeration of gesture modes. + /// + /// This enum is need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public enum GestureMode + { + /// + /// None. + /// + None, + + /// + /// Begin. + /// + Begin, + + /// + /// Update. + /// + Update, + + /// + /// End. + /// + End, + + /// + /// Done. + /// + Done, + } + + /// + /// Enumeration of gesture edges. + /// + /// This enum is need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public enum GestureEdge + { + /// + /// edge none. + /// + None, + + /// + /// edge top. + /// + Top, + + /// + /// edge right. + /// + Right, + + /// + /// edge bottom. + /// + Bottom, + + /// + /// edge left. + /// + Left, + } + + /// + /// Enumeration of gesture edge sizes. + /// + /// This enum is need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public enum GestureEdgeSize + { + /// + /// edge size none. + /// + None, + + /// + /// edge size full. + /// + Full, + + /// + /// edge size partial. + /// + Partial, + } + + /// + /// Class for the Tizen Input Gesture. + /// + /// + /// http://tizen.org/privilege/gesturegrab + /// + /// 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 _edgeSwipeEventHandler; + private EdgeSwipeCb _edgeSwipeDelegate; + + private event EventHandler _edgeDragEventHandler; + private EdgeDragCb _edgeDragDelegate; + + private event EventHandler _tapEventHandler; + private TapCb _tapDelegate; + + private event EventHandler _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"); + } + } + + /// + /// Creates a new InputGesture. + /// + /// This module operates in a NUI application and requires instantiation and disposal on the main thread. + /// Thrown when the memory is not enough to allocate. + /// Thrown when the feature is not supported. + /// Thrown when the permission is denied. + 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"); + } + + /// + /// Destructor. + /// + ~InputGesture() + { + if (!isDisposeQueued) + { + isDisposeQueued = true; + DisposeQueue.Instance.Add(this); + } + } + + /// + /// Dispose. + /// + public void Dispose() + { + if (isDisposeQueued) + { + Dispose(DisposeTypes.Implicit); + } + else + { + Dispose(DisposeTypes.Explicit); + GC.SuppressFinalize(this); + } + } + + /// + 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; + } + + /// + /// Generates a edge swipe gesture's grab info handle + /// + /// The number of fingers + /// The position of edge + /// The edge swipe gesture data handle + /// Thrown when failed of invalid argument. + /// Thrown when the memory is not enough to allocate. + 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; + } + + /// + /// Frees a memory of edge swipe gesture's grab info handle + /// + /// The edge swipe gesture data handle + /// Thrown when failed of invalid argument. + 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"); + } + + /// + /// Sets a specific size of edge for edge swipe gesture + /// + /// The edge swipe gesture data handle + /// The enum of gesture edge size + /// The start point of edge area + /// The end point of edge area + /// Thrown when failed of invalid argument. + 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); + } + + /// + /// Generates a edge drag gesture's grab info handle + /// + /// The number of fingers + /// The position of edge + /// The edge drag gesture data handle + /// Thrown when failed of invalid argument. + /// Thrown when the memory is not enough to allocate. + 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; + } + + /// + /// Frees a memory of edge drag gesture's grab info handle + /// + /// The edge drag gesture data handle + /// Thrown when failed of invalid argument. + 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"); + } + + /// + /// Sets a specific size of edge for edge drag gesture + /// + /// The edge drag gesture data handle + /// The enum of gesture edge size + /// The start point of edge area + /// The end point of edge area + /// Thrown when failed of invalid argument. + 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); + } + + /// + /// Generates a tap gesture's grab info handle + /// + /// The number of fingers + /// The number of repeats + /// The tap gesture data handle + /// Thrown when failed of invalid argument. + /// Thrown when the memory is not enough to allocate. + 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; + } + + /// + /// Frees a memory of tap gesture's grab info handle + /// + /// The tap gesture data handle + /// Thrown when failed of invalid argument. + 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"); + } + + /// + /// Generates a palm cover gesture's grab info handle + /// + /// The palm cover gesture data handle + /// Thrown when failed of invalid argument. + /// Thrown when the memory is not enough to allocate. + 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; + } + + /// + /// Frees a memory of palm cover gesture's grab info handle + /// + /// The palm cover gesture data handle + /// Thrown when failed of invalid argument. + 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"); + } + + /// + /// Grabs a global gesture + /// + /// gesture data to grab + /// Thrown when failed of invalid argument. + 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"); + } + + /// + /// Ungrabs a global gesture. + /// + /// gesture data to ungrab + /// Thrown when failed of invalid argument. + 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"); + } + + /// + /// Emits the event when the edge swipe event comes + /// + /// Thrown when failed of invalid argument. + public event EventHandler 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); + } + } + } + + /// + /// Emits the event when the edge drag event comes + /// + /// Thrown when failed of invalid argument. + public event EventHandler 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); + } + } + } + + /// + /// Emits the event when the tap event comes + /// + /// Thrown when failed of invalid argument. + public event EventHandler 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); + } + } + } + /// + /// Emits the event when the palm cover event comes + /// + /// Thrown when failed of invalid argument. + public event EventHandler 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 index 00000000000..f24c051b254 --- /dev/null +++ b/src/Tizen.NUI.WindowSystem/src/public/PalmCoverEventArgs.cs @@ -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 +{ + /// + /// This class contains the data related to the PalmCover event. + /// + /// 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; + } + /// + /// Mode + /// + public int Mode{ get; internal set; } + /// + /// Duration + /// + public int Duration{ get; internal set;} + /// + /// Cx + /// + public int Cx{ get; internal set;} + /// + /// Cy + /// + public int Cy{ get; internal set;} + /// + /// Size + /// + public double Size{ get; internal set;} + /// + /// Pressure + /// + 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 index 00000000000..4d84557ff87 --- /dev/null +++ b/src/Tizen.NUI.WindowSystem/src/public/TapEventArgs.cs @@ -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 +{ + /// + /// This class contains the data related to the Tap event. + /// + /// 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; + } + /// + /// Mode + /// + public int Mode{ get; internal set; } + /// + /// Fingers + /// + public int Fingers{ get; internal set;} + /// + /// Repeats + /// + 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 index 00000000000..455bd67f873 --- /dev/null +++ b/test/Tizen.NUI.WindowSystem.InputGesture/Tizen.NUI.WindowSystem.InputGesture.cs @@ -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; + } + + /// + /// + /// The sender object. + /// Argument of Event. + 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); + } + /// + /// + /// The sender object. + /// Argument of Event. + 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); + } + /// + /// + /// The sender object. + /// Argument of Event. + private static void _tapEventHandler(object sender, TapEventArgs e) + { + Log.Debug("GestureSample", "Mode: " + (GestureMode)e.Mode + ", Fingers: " + e.Fingers + ", Repeats: " + e.Fingers); + } + /// + /// + /// The sender object. + /// Argument of Event. + 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 index 00000000000..b0bb521cc41 --- /dev/null +++ b/test/Tizen.NUI.WindowSystem.InputGesture/Tizen.NUI.WindowSystem.InputGesture.csproj @@ -0,0 +1,27 @@ + + + + Exe + net6.0 + + + + portable + + + None + + + + + + + + + + + + True + + + 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 index 00000000000..9f3cb986081 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 index 00000000000..5c85e42c178 --- /dev/null +++ b/test/Tizen.NUI.WindowSystem.InputGesture/tizen-manifest.xml @@ -0,0 +1,16 @@ + + + + + + Tizen.NUI.WindowSystem.InputGesture.png + + + 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 index 00000000000..cb53adc6fce --- /dev/null +++ b/test/Tizen.NUI.WindowSystem.InputGesture/tizen_dotnet_project.yaml @@ -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