The Wheel event calls the WheelEvent callback by going back from the last child actor to the parent via hitTest.
InterceptWheelEvent checks the wheel event in the parent first.
Returning false from interceptWheelEvent allows child actors to receive WheelEvents.
If it returns true, the actor will receive a WheelEvent.
for example
View parent = new View();
View child = new View();
parent.Add(child);
child.WheelEvent += childFunctor;
parent.WheelEvent += parentFunctor;
The callbacks are called in the order childFunctor -> parentFunctor.
If you connect InterceptWheelEvent to parentActor.
parent.InterceptWheelEvent += interceptFunctor;
When interceptFunctor returns false, it is called in the same order childFunctor -> parentFunctor.
If intereptFunctor returns true, it means that the WheelEvent was intercepted.
So the child actor will not be able to receive wheel events.
Only the parentFunctor is called.
refer :
https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-core/+/295232/
https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-csharp-binder/+/295233/
[DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Actor_WheelEventSignal_Disconnect")]
public static extern void WheelEventDisconnect(HandleRef actor, HandleRef handler);
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Actor_InterceptWheelSignal_Connect")]
+ public static extern void InterceptWheelConnect(HandleRef actor, HandleRef handler);
+
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Actor_InterceptWheelSignal_Disconnect")]
+ public static extern void InterceptWheelDisconnect(HandleRef actor, HandleRef handler);
+
[DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Actor_OnSceneSignal_Connect")]
public static extern void OnSceneConnect(HandleRef actor, HandleRef handler);
{
private EventHandler offWindowEventHandler;
private OffWindowEventCallbackType offWindowEventCallback;
+ private EventHandlerWithReturnType<object, WheelEventArgs, bool> interceptWheelHandler;
+ private WheelEventCallbackType interceptWheelCallback;
private EventHandlerWithReturnType<object, WheelEventArgs, bool> wheelEventHandler;
private WheelEventCallbackType wheelEventCallback;
private EventHandlerWithReturnType<object, KeyEventArgs, bool> keyEventHandler;
}
/// <summary>
+ /// An event for the wheel which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
+ /// The wheel event is emitted when the wheel input is received.<br />
+ /// This can receive wheel events before child. <br />
+ /// If it returns false, the child can receive the wheel event. If it returns true, the wheel event is intercepted. So child cannot receive wheel event.<br />
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event EventHandlerWithReturnType<object, WheelEventArgs, bool> InterceptWheelEvent
+ {
+ add
+ {
+ if (interceptWheelHandler == null)
+ {
+ interceptWheelCallback = OnInterceptWheel;
+ Interop.ActorSignal.InterceptWheelConnect(SwigCPtr, interceptWheelCallback.ToHandleRef(this));
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ }
+ interceptWheelHandler += value;
+ }
+
+ remove
+ {
+ interceptWheelHandler -= value;
+ if (interceptWheelHandler == null && interceptWheelCallback != null)
+ {
+ Interop.ActorSignal.InterceptWheelDisconnect(SwigCPtr, interceptWheelCallback.ToHandleRef(this));
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ interceptWheelCallback = null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// If child view doesn't want the parent's view to intercept the wheel event, you can set it to true.
+ /// for example :
+ /// parent.Add(child);
+ /// parent.InterceptWheelEvent += OnInterceptWheelEvent;
+ /// View view = child.GetParent() as View;
+ /// view.DisallowInterceptWheelEvent = true;
+ /// This prevents the parent from intercepting wheel event.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool DisallowInterceptWheelEvent { get; set; }
+
+ /// <summary>
/// An event for the WheelMoved signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
/// The WheelMoved signal is emitted when the wheel event is received.<br />
/// </summary>
return consumed;
}
+ // Callback for View InterceptWheel signal
+ private bool OnInterceptWheel(IntPtr view, IntPtr wheelEvent)
+ {
+ if (wheelEvent == global::System.IntPtr.Zero)
+ {
+ NUILog.Error("wheelEvent should not be null!");
+ return true;
+ }
+
+ // DisallowInterceptWheelEvent prevents the parent from intercepting wheel.
+ if (DisallowInterceptWheelEvent)
+ {
+ return false;
+ }
+
+ WheelEventArgs e = new WheelEventArgs();
+
+ e.Wheel = Tizen.NUI.Wheel.GetWheelFromPtr(wheelEvent);
+
+ bool consumed = false;
+
+ if (interceptWheelHandler != null)
+ {
+ consumed = interceptWheelHandler(this, e);
+ }
+
+ return consumed;
+ }
+
// Callback for View Wheel signal
private bool OnWheelEvent(IntPtr view, IntPtr wheelEvent)
{
{
internalTargetSize = new Vector3(0, 0, 0);
}
-
+
Interop.ActorInternal.RetrieveTargetSize(SwigCPtr, internalTargetSize.SwigCPtr);
-
+
if (NDalicPINVOKE.SWIGPendingException.Pending)
{
throw NDalicPINVOKE.SWIGPendingException.Retrieve();
{
internalCurrentSize = new Size2D(0, 0);
}
-
+
Interop.ActorInternal.RetrieveCurrentPropertyVector2ActualVector3(SwigCPtr, Property.SIZE, internalCurrentSize.SwigCPtr);
if (NDalicPINVOKE.SWIGPendingException.Pending)
{
internalCurrentPosition = new Position(0, 0, 0);
}
-
+
Interop.ActorInternal.RetrieveCurrentPropertyVector3(SwigCPtr, Property.POSITION, internalCurrentPosition.SwigCPtr);
if (NDalicPINVOKE.SWIGPendingException.Pending)
{
internalCurrentWorldPosition = new Vector3(0, 0, 0);
}
-
+
Interop.ActorInternal.RetrieveCurrentPropertyVector3(SwigCPtr, View.Property.WorldPosition, internalCurrentWorldPosition.SwigCPtr);
if (NDalicPINVOKE.SWIGPendingException.Pending)
{
internalCurrentScale = new Vector3(0, 0, 0);
}
-
+
Interop.ActorInternal.RetrieveCurrentPropertyVector3(SwigCPtr, View.Property.SCALE, internalCurrentScale.SwigCPtr);
if (NDalicPINVOKE.SWIGPendingException.Pending)
{
internalCurrentWorldScale = new Vector3(0, 0, 0);
}
-
+
Interop.ActorInternal.RetrieveCurrentPropertyVector3(SwigCPtr, View.Property.WorldScale, internalCurrentWorldScale.SwigCPtr);
if (NDalicPINVOKE.SWIGPendingException.Pending)
{
internalCurrentColor = new Vector4(0, 0, 0, 0);
}
-
+
Interop.ActorInternal.RetrieveCurrentPropertyVector4(SwigCPtr, Interop.ActorProperty.ColorGet(), internalCurrentColor.SwigCPtr);
if (NDalicPINVOKE.SWIGPendingException.Pending)
{
internalCurrentWorldColor = new Vector4(0, 0, 0, 0);
}
-
+
Interop.ActorInternal.RetrieveCurrentPropertyVector4(SwigCPtr, Property.WorldColor, internalCurrentWorldColor.SwigCPtr);
if (NDalicPINVOKE.SWIGPendingException.Pending)
onWindowEventCallback = null;
}
+ if (interceptWheelCallback != null)
+ {
+ NUILog.Debug($"[Dispose] interceptWheelCallback");
+
+ Interop.ActorSignal.InterceptWheelDisconnect(GetBaseHandleCPtrHandleRef, interceptWheelCallback.ToHandleRef(this));
+ NDalicPINVOKE.ThrowExceptionIfExistsDebug();
+ interceptWheelCallback = null;
+ }
+
if (wheelEventCallback != null)
{
NUILog.Debug($"[Dispose] wheelEventCallback");
private RootLayerTouchDataCallbackType rootLayerTouchDataCallback;
private RootLayerTouchDataCallbackType rootLayerInterceptTouchDataCallback;
private WheelEventCallbackType wheelEventCallback;
+ private WheelEventCallbackType interceptWheelCallback;
private EventCallbackDelegateType1 stageKeyCallbackDelegate;
private InterceptKeyEventDelegateType stageInterceptKeyCallbackDelegate;
private EventCallbackDelegateType0 stageEventProcessingFinishedEventCallbackDelegate;
}
/// <summary>
+ /// An event for the wheel event signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
+ /// The wheel event signal is emitted when the wheel input is received.<br />
+ /// This can receive wheel events before child. <br />
+ /// If it returns false, the child can receive the wheel event. If it returns true, the wheel event is intercepted. So child cannot receive wheel event.<br />
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event ReturnTypeEventHandler<object, WheelEventArgs, bool> InterceptWheelEvent
+ {
+ add
+ {
+ if (interceptWheelHandler == null)
+ {
+ interceptWheelCallback = OnWindowInterceptWheel;
+ Interop.ActorSignal.InterceptWheelConnect(Layer.getCPtr(GetRootLayer()), interceptWheelCallback.ToHandleRef(this));
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ }
+ interceptWheelHandler += value;
+ }
+ remove
+ {
+ interceptWheelHandler -= value;
+ if (interceptWheelHandler == null && interceptWheelCallback != null)
+ {
+ Interop.ActorSignal.InterceptWheelDisconnect(Layer.getCPtr(GetRootLayer()), interceptWheelCallback.ToHandleRef(this));
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ interceptWheelCallback = null;
+ }
+ }
+ }
+
+ /// <summary>
/// Emits the event when the key event is received.
/// </summary>
/// <since_tizen> 3 </since_tizen>
private event EventHandler<TouchEventArgs> rootLayerTouchDataEventHandler;
private ReturnTypeEventHandler<object, TouchEventArgs, bool> rootLayerInterceptTouchDataEventHandler;
private event EventHandler<WheelEventArgs> stageWheelHandler;
+ private ReturnTypeEventHandler<object, WheelEventArgs, bool> interceptWheelHandler;
private event EventHandler<KeyEventArgs> stageKeyHandler;
private ReturnTypeEventHandler<object, KeyEventArgs, bool> stageInterceptKeyHandler;
private event EventHandler stageEventProcessingFinishedEventHandler;
DetentEventCallback = null;
}
+ if (interceptWheelCallback != null)
+ {
+ Interop.ActorSignal.InterceptWheelDisconnect(Layer.getCPtr(GetRootLayer()), interceptWheelCallback.ToHandleRef(this));
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ interceptWheelCallback = null;
+ }
+
if (stageKeyCallbackDelegate != null)
{
using KeyEventSignal signal = new KeyEventSignal(Interop.Window.KeyEventSignal(GetBaseHandleCPtrHandleRef), false);
return true;
}
+ private bool OnWindowInterceptWheel(IntPtr view, IntPtr wheelEvent)
+ {
+ if (wheelEvent == global::System.IntPtr.Zero)
+ {
+ NUILog.Error("wheelEvent should not be null!");
+ return true;
+ }
+
+ bool consumed = false;
+ if (interceptWheelHandler != null)
+ {
+ WheelEventArgs e = new WheelEventArgs();
+ e.Wheel = Tizen.NUI.Wheel.GetWheelFromPtr(wheelEvent);
+ consumed = interceptWheelHandler(this, e);
+ }
+ return consumed;
+ }
+
// Callback for Stage KeyEventsignal
private void OnStageKey(IntPtr data)
{
public class ScrollableFocusSample : IExample
{
public View root;
- public class CustomScrollableBase : ScrollableBase
- {
- public override bool OnWheel(Wheel wheel)
- {
- base.OnWheel(wheel);
- Window window = NUIApplication.GetDefaultWindow();
- window.LazyFeedHover();
- return true;
- }
- }
public void Activate()
{
Window window = NUIApplication.GetDefaultWindow();
+ // Use LazyFeedHover if you want to trigger the HoverEvent again when a Wheel event is received.
+ window.InterceptWheelEvent += (s, e) =>
+ {
+ window.LazyFeedHover();
+ return false;
+ };
+
root = new View();
root.Layout = new AbsoluteLayout();
root.Size = new Size(500, 800);
};
root.Add(topbtn);
- var scrollview = new CustomScrollableBase
+ var scrollview = new ScrollableBase
{
ScrollingDirection = ScrollableBase.Direction.Vertical,
WidthSpecification = LayoutParamPolicies.MatchParent,
};
root.Add(middle);
- var myscrollview = new CustomScrollableBase
+ var myscrollview = new ScrollableBase
{
ScrollingDirection = ScrollableBase.Direction.Vertical,
WidthSpecification = LayoutParamPolicies.MatchParent,