[NUI] Add InterceptKeyEvent
authorjoogab.yun <joogab.yun@samsung.com>
Mon, 4 Jul 2022 01:35:02 +0000 (10:35 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Wed, 31 Aug 2022 05:41:10 +0000 (14:41 +0900)
Intercepts KeyEvents in the window before dispatching KeyEvents to the View.
If a KeyEvent is consumed, no KeyEvent is delivered to the View.

```c#
Window win = NUIApplication.GetDefaultWindow();
win.InterceptKeyEvent += OnInterceptKeyEvent;

private void OnInterceptKeyEvent(object sender, Window.KeyEventArgs e)
{
   return false;   //If it returns true, other views and windows do not receive KeyEvents.
}
```

refer
https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-core/+/280490/
https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-adaptor/+/280491/
https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-csharp-binder/+/280492/

src/Tizen.NUI/src/internal/Interop/Interop.Window.cs
src/Tizen.NUI/src/public/Window/WindowEvent.cs

index 1c61efe..a6974b2 100755 (executable)
@@ -212,6 +212,9 @@ namespace Tizen.NUI
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_KeyEventSignal")]
             public static extern global::System.IntPtr KeyEventSignal(global::System.Runtime.InteropServices.HandleRef jarg1);
 
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_InterceptKeyEventSignal")]
+            public static extern global::System.IntPtr InterceptKeyEventSignal(global::System.Runtime.InteropServices.HandleRef jarg1);
+
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_TouchSignal")]
             public static extern global::System.IntPtr TouchSignal(global::System.Runtime.InteropServices.HandleRef jarg1);
 
index 09e93bf..a7a671e 100755 (executable)
@@ -34,6 +34,7 @@ namespace Tizen.NUI
         private RootLayerTouchDataCallbackType rootLayerTouchDataCallback;
         private WheelEventCallbackType wheelEventCallback;
         private EventCallbackDelegateType1 stageKeyCallbackDelegate;
+        private InterceptKeyEventDelegateType stageInterceptKeyCallbackDelegate;
         private EventCallbackDelegateType0 stageEventProcessingFinishedEventCallbackDelegate;
         private EventHandler stageContextLostEventHandler;
         private EventCallbackDelegateType0 stageContextLostEventCallbackDelegate;
@@ -47,6 +48,7 @@ namespace Tizen.NUI
         private WindowTransitionEffectSignal transitionEffectSignal;
         private KeyboardRepeatSettingsChangedEventCallbackType keyboardRepeatSettingsChangedEventCallback;
         private KeyboardRepeatSettingsChangedSignal keyboardRepeatSettingsChangedSignal;
+        private KeyEventSignal interceptKeyEventSignal;
         private AuxiliaryMessageEventCallbackType auxiliaryMessageEventCallback;
 
         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
@@ -65,6 +67,8 @@ namespace Tizen.NUI
         private delegate void KeyboardRepeatSettingsChangedEventCallbackType();
         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
         private delegate void AuxiliaryMessageEventCallbackType(IntPtr kData, IntPtr vData, IntPtr optionsArray);
+        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+        private delegate bool InterceptKeyEventDelegateType(IntPtr arg1);
 
         /// <summary>
         /// FocusChanged event.
@@ -215,6 +219,38 @@ namespace Tizen.NUI
         }
 
         /// <summary>
+        /// Intercepts KeyEvents in the window before dispatching KeyEvents to the child.<br />
+        /// If it returns true(consumed), no KeyEvent is delivered to the child.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event ReturnTypeEventHandler<object, KeyEventArgs, bool> InterceptKeyEvent
+        {
+            add
+            {
+                if (stageInterceptKeyHandler == null)
+                {
+                    stageInterceptKeyCallbackDelegate = OnStageInterceptKey;
+                    interceptKeyEventSignal = InterceptKeyEventSignal();
+                    interceptKeyEventSignal?.Connect(stageInterceptKeyCallbackDelegate);
+                }
+                stageInterceptKeyHandler += value;
+            }
+            remove
+            {
+                stageInterceptKeyHandler -= value;
+                if (stageInterceptKeyHandler == null && interceptKeyEventSignal?.Empty() == false)
+                {
+                    interceptKeyEventSignal?.Disconnect(stageInterceptKeyCallbackDelegate);
+                    if (interceptKeyEventSignal?.Empty() == true)
+                    {
+                        stageInterceptKeyCallbackDelegate = null;
+                    }
+                }
+            }
+        }
+
+
+        /// <summary>
         /// Emits the event when the window resized.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
@@ -356,6 +392,7 @@ namespace Tizen.NUI
         private event EventHandler<TouchEventArgs> rootLayerTouchDataEventHandler;
         private event EventHandler<WheelEventArgs> stageWheelHandler;
         private event EventHandler<KeyEventArgs> stageKeyHandler;
+        private ReturnTypeEventHandler<object, KeyEventArgs, bool> stageInterceptKeyHandler;
         private event EventHandler stageEventProcessingFinishedEventHandler;
         private event EventHandler<ResizedEventArgs> windowResizeEventHandler;
         private event EventHandler<FocusChangedEventArgs> windowFocusChangedEventHandler2;
@@ -502,6 +539,13 @@ namespace Tizen.NUI
             return ret;
         }
 
+        internal KeyEventSignal InterceptKeyEventSignal()
+        {
+            KeyEventSignal ret = new KeyEventSignal(Interop.Window.InterceptKeyEventSignal(SwigCPtr), false);
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+            return ret;
+        }
+
         internal VoidSignal EventProcessingFinishedSignal()
         {
             VoidSignal ret = new VoidSignal(Interop.StageSignal.EventProcessingFinishedSignal(stageCPtr), false);
@@ -615,6 +659,12 @@ namespace Tizen.NUI
                 }
             }
 
+            if (stageInterceptKeyCallbackDelegate != null)
+            {
+                interceptKeyEventSignal?.Disconnect(stageInterceptKeyCallbackDelegate);
+                stageInterceptKeyCallbackDelegate = null;
+            }
+
             if (stageEventProcessingFinishedEventCallbackDelegate != null)
             {
                 using VoidSignal eventProcessingFinishedSignal = EventProcessingFinishedSignal();
@@ -795,6 +845,20 @@ namespace Tizen.NUI
             }
         }
 
+        // Callback for Stage InterceptKeyEventsignal
+        private bool OnStageInterceptKey(IntPtr data)
+        {
+            bool consumed = false;
+            if (stageInterceptKeyHandler != null)
+            {
+                KeyEventArgs e = new KeyEventArgs();
+                e.Key = Tizen.NUI.Key.GetKeyFromPtr(data);
+                //here we send all data to user event handlers
+                consumed = stageInterceptKeyHandler(this, e);
+            }
+            return consumed;
+        }
+
         // Callback for Stage EventProcessingFinishedSignal
         private void OnEventProcessingFinished()
         {