The Touch event calls the TouchEvent callback by going back from the last child actor to the parent via hitTest.
InterceptTouchEvent checks the touch event in the parent first.
Returning false from interceptTouchEvent allows child actors to receive TouchEvents.
If it returns true, the actor will receive a TouchEvent.
for example
View parent = new View();
View child = new View();
parent.Add(child);
child.TouchEvent += childFunctor;
parent.TouchEvent += parentFunctor;
The callbacks are called in the order childFunctor -> parentFunctor.
If you connect interceptTouchSignal to parentActor.
parent.InterceptTouchEvent += interceptFunctor;
When interceptFunctor returns false, it is called in the same order childFunctor -> parentFunctor.
If intereptFunctor returns true, it means that the TouchEvent was intercepted.
So the child actor will not be able to receive touch events.
Only the parentFunctor is called.
--- /dev/null
+/*
+ * Copyright(c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Tizen.NUI
+{
+ internal class InterceptTouchSignal : Disposable
+ {
+
+ internal InterceptTouchSignal(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
+ {
+ }
+
+
+ protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
+ {
+ Interop.TouchSignal.delete_TouchSignal(swigCPtr);
+ }
+
+
+ public bool Empty()
+ {
+ bool ret = Interop.TouchSignal.TouchSignal_Empty(swigCPtr);
+ if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+ return ret;
+ }
+
+ public uint GetConnectionCount()
+ {
+ uint ret = Interop.TouchSignal.TouchSignal_GetConnectionCount(swigCPtr);
+ if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+ return ret;
+ }
+
+ public void Connect(System.Delegate func)
+ {
+ System.IntPtr ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(func);
+ {
+ Interop.TouchSignal.TouchSignal_Connect(swigCPtr, new System.Runtime.InteropServices.HandleRef(this, ip));
+ if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+ }
+ }
+
+ public void Disconnect(System.Delegate func)
+ {
+ System.IntPtr ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(func);
+ {
+ Interop.TouchSignal.TouchSignal_Disconnect(swigCPtr, new System.Runtime.InteropServices.HandleRef(this, ip));
+ if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+ }
+ }
+
+ public void Emit(Touch arg)
+ {
+ Interop.TouchSignal.TouchSignal_Emit(swigCPtr, Touch.getCPtr(arg));
+ if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+ }
+
+ public InterceptTouchSignal() : this(Interop.TouchSignal.new_InterceptTouchSignal(), true)
+ {
+ if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+ }
+ }
+}
[global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_ActorSignal")]
public static extern void delete_ActorSignal(global::System.Runtime.InteropServices.HandleRef jarg1);
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Actor_InterceptTouchSignal")]
+ public static extern global::System.IntPtr Actor_InterceptTouchSignal(global::System.Runtime.InteropServices.HandleRef jarg1);
+
[global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Actor_TouchSignal")]
public static extern global::System.IntPtr Actor_TouchSignal(global::System.Runtime.InteropServices.HandleRef jarg1);
[global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_TouchSignal")]
public static extern global::System.IntPtr new_TouchSignal();
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_InterceptTouchSignal")]
+ public static extern global::System.IntPtr new_InterceptTouchSignal();
+
[global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_TouchSignal")]
public static extern void delete_TouchSignal(global::System.Runtime.InteropServices.HandleRef jarg1);
}
private WheelEventCallbackType _wheelEventCallback;
private EventHandlerWithReturnType<object, KeyEventArgs, bool> _keyEventHandler;
private KeyCallbackType _keyCallback;
+ private EventHandlerWithReturnType<object, TouchEventArgs, bool> _interceptTouchDataEventHandler;
+ private TouchDataCallbackType _interceptTouchDataCallback;
private EventHandlerWithReturnType<object, TouchEventArgs, bool> _touchDataEventHandler;
private TouchDataCallbackType _touchDataCallback;
private EventHandlerWithReturnType<object, HoverEventArgs, bool> _hoverEventHandler;
/// <summary>
/// An event for the touched signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
/// The touched signal is emitted when the touch input is received.<br />
+ /// This can receive touch events before child. <br />
+ /// If it returns false, the child can receive the touch event. If it returns true, the touch event is intercepted. So child cannot receive touch event.<br />
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event EventHandlerWithReturnType<object, TouchEventArgs, bool> InterceptTouchEvent
+ {
+ add
+ {
+ if (_interceptTouchDataEventHandler == null)
+ {
+ _interceptTouchDataCallback = OnInterceptTouch;
+ this.InterceptTouchSignal().Connect(_interceptTouchDataCallback);
+ }
+
+ _interceptTouchDataEventHandler += value;
+ }
+
+ remove
+ {
+ _interceptTouchDataEventHandler -= value;
+
+ if (_interceptTouchDataEventHandler == null && InterceptTouchSignal().Empty() == false)
+ {
+ this.InterceptTouchSignal().Disconnect(_interceptTouchDataCallback);
+ }
+ }
+ }
+
+ /// <summary>
+ /// An event for the touched signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
+ /// The touched signal is emitted when the touch input is received.<br />
/// </summary>
/// <since_tizen> 3 </since_tizen>
public event EventHandlerWithReturnType<object, TouchEventArgs, bool> TouchEvent
}
}
+ internal TouchDataSignal InterceptTouchSignal()
+ {
+ TouchDataSignal ret = new TouchDataSignal(Interop.ActorSignal.Actor_InterceptTouchSignal(swigCPtr), false);
+ if (NDalicPINVOKE.SWIGPendingException.Pending)
+ throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+ return ret;
+ }
+
internal TouchDataSignal TouchSignal()
{
TouchDataSignal ret = new TouchDataSignal(Interop.ActorSignal.Actor_TouchSignal(swigCPtr), false);
}
// Callback for View TouchSignal
+ private bool OnInterceptTouch(IntPtr view, IntPtr touchData)
+ {
+ if (touchData == global::System.IntPtr.Zero)
+ {
+ NUILog.Error("touchData should not be null!");
+ return true;
+ }
+
+ TouchEventArgs e = new TouchEventArgs();
+
+ e.Touch = Tizen.NUI.Touch.GetTouchFromPtr(touchData);
+
+ bool consumed = false;
+
+ if (_interceptTouchDataEventHandler != null)
+ {
+ consumed = _interceptTouchDataEventHandler(this, e);
+ }
+
+ if (enableControlState && !consumed)
+ {
+ consumed = HandleControlStateOnTouch(e.Touch);
+ }
+
+ return consumed;
+ }
+
+ // Callback for View TouchSignal
private bool OnTouch(IntPtr view, IntPtr touchData)
{
if (touchData == global::System.IntPtr.Zero)
this.HoveredSignal().Disconnect(_hoverEventCallback);
}
+ if (_interceptTouchDataCallback != null)
+ {
+ this.InterceptTouchSignal().Disconnect(_interceptTouchDataCallback);
+ }
+
if (_touchDataCallback != null)
{
this.TouchSignal().Disconnect(_touchDataCallback);