[NUI] Add DispatchGestureEvents and DispatchParentGestureEvents (#4609)
authorJoogabYun <40262755+JoogabYun@users.noreply.github.com>
Fri, 30 Sep 2022 05:41:49 +0000 (14:41 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Tue, 4 Oct 2022 11:26:36 +0000 (20:26 +0900)
This determines whether gesture events are emitted or not.

If DispatchGestureEvents is set to false, then itself and parents will not receive all gesture event signals.
If DispatchParentGestureEvents is set to false, then parents will not receive all gesture event signals.

src/Tizen.NUI/src/public/BaseComponents/View.cs
src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs
src/Tizen.NUI/src/public/Events/LongPressGestureDetector.cs
src/Tizen.NUI/src/public/Events/PanGestureDetector.cs
src/Tizen.NUI/src/public/Events/PinchGestureDetector.cs
src/Tizen.NUI/src/public/Events/RotationGestureDetector.cs
src/Tizen.NUI/src/public/Events/TapGestureDetector.cs
src/Tizen.NUI/src/public/Window/DefaultBorder.cs

index 2dc6cb6..8639717 100755 (executable)
@@ -71,7 +71,17 @@ namespace Tizen.NUI.BaseComponents
         private Size2D internalSize2D = null;
         private int layoutCount = 0;
         private ControlState propagatableControlStates = ControlState.All;
+
+        // List of dispatch Event
+        private PanGestureDetector panGestureDetector = null;
+        private LongPressGestureDetector longGestureDetector = null;
+        private PinchGestureDetector pinchGestureDetector = null;
+        private TapGestureDetector tapGestureDetector = null;
+        private RotationGestureDetector rotationGestureDetector = null;
+        private int configGestureCount = 0;
         private bool dispatchTouchEvents = true;
+        private bool dispatchGestureEvents = true;
+        private bool dispatchParentGestureEvents = true;
 
 #if NUI_PROPERTY_CHANGE_DEBUG
 internal static int LayoutSetGetter = 0;
@@ -1210,7 +1220,7 @@ LayoutSetGetter++;
         /// <remarks>
         /// The <see cref="Size"/>, <see cref="Position"/>, <see cref="Color"/>, and <see cref="Scale"/> properties are set in the main thread.
         /// Therefore, it is not updated in real time when the value is changed in the render thread (for example, the value is changed during animation).
-        /// However, <see cref="CurrentSize"/>, <see cref="CurrentPosition"/>, <see cref="CurrentColor"/>, and <see cref="CurrentScale"/> properties are updated in real time, 
+        /// However, <see cref="CurrentSize"/>, <see cref="CurrentPosition"/>, <see cref="CurrentColor"/>, and <see cref="CurrentScale"/> properties are updated in real time,
         /// and users can get the current actual values through them.
         /// </remarks>
         /// <since_tizen> 3 </since_tizen>
@@ -1280,7 +1290,7 @@ Size2DSetter++;
         /// <remarks>
         /// The <see cref="Size"/>, <see cref="Position"/>, <see cref="Color"/>, and <see cref="Scale"/> properties are set in the main thread.
         /// Therefore, it is not updated in real time when the value is changed in the render thread (for example, the value is changed during animation).
-        /// However, <see cref="CurrentSize"/>, <see cref="CurrentPosition"/>, <see cref="CurrentColor"/>, and <see cref="CurrentScale"/> properties are updated in real time, 
+        /// However, <see cref="CurrentSize"/>, <see cref="CurrentPosition"/>, <see cref="CurrentColor"/>, and <see cref="CurrentScale"/> properties are updated in real time,
         /// and users can get the current actual values through them.
         /// </remarks>
         /// <since_tizen> 3 </since_tizen>
@@ -3542,7 +3552,7 @@ SizeSetter++;
 
         /// <summary>
         /// Gets or sets the status of whether the view should emit key event signals.
-        /// If a View's DispatchKeyEvents is set to false, then it's children will not emit a key event signal either.
+        /// If a View's DispatchKeyEvents is set to false, then itself and parents will not receive key event signals.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
         public bool DispatchKeyEvents
@@ -3596,6 +3606,107 @@ SizeSetter++;
         }
 
         /// <summary>
+        /// Gets or sets the status of whether the view should emit Gesture event signals.
+        /// If a View's DispatchGestureEvents is set to false, then itself and parents will not receive all gesture event signals.
+        /// The itself and parents does not receive tap, pinch, pan, rotation, or longpress gestures.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool DispatchGestureEvents
+        {
+            get
+            {
+                return dispatchGestureEvents;
+            }
+            set
+            {
+                if (dispatchGestureEvents != value)
+                {
+                    dispatchGestureEvents = value;
+                    ConfigGestureDetector(dispatchGestureEvents);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the status of whether the view should emit Gesture event signals.
+        /// If a View's DispatchParentGestureEvents is set to false, then parents will not receive all gesture event signals.
+        /// The parents does not receive tap, pinch, pan, rotation, or longpress gestures.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool DispatchParentGestureEvents
+        {
+            get
+            {
+                return dispatchParentGestureEvents;
+            }
+            set
+            {
+                if (dispatchParentGestureEvents != value)
+                {
+                    dispatchParentGestureEvents = value;
+                    ConfigGestureDetector(dispatchParentGestureEvents);
+                }
+            }
+        }
+
+        private void ConfigGestureDetector(bool dispatch)
+        {
+            if (panGestureDetector == null) panGestureDetector = new PanGestureDetector();
+            if (longGestureDetector == null) longGestureDetector = new LongPressGestureDetector();
+            if (pinchGestureDetector == null) pinchGestureDetector = new PinchGestureDetector();
+            if (tapGestureDetector == null) tapGestureDetector = new TapGestureDetector();
+            if (rotationGestureDetector == null) rotationGestureDetector = new RotationGestureDetector();
+
+            if (dispatch == true)
+            {
+                configGestureCount = configGestureCount > 0 ? configGestureCount-- : 0;
+                if (configGestureCount == 0)
+                {
+                    panGestureDetector.Detach(this);
+                    longGestureDetector.Detach(this);
+                    pinchGestureDetector.Detach(this);
+                    tapGestureDetector.Detach(this);
+                    rotationGestureDetector.Detach(this);
+
+                    panGestureDetector.Detected -= OnGestureDetected;
+                    longGestureDetector.Detected -= OnGestureDetected;
+                    pinchGestureDetector.Detected -= OnGestureDetected;
+                    tapGestureDetector.Detected -= OnGestureDetected;
+                    rotationGestureDetector.Detected -= OnGestureDetected;
+
+                    panGestureDetector = null;
+                    longGestureDetector = null;
+                    pinchGestureDetector = null;
+                    tapGestureDetector = null;
+                    rotationGestureDetector = null;
+                }
+            }
+            else
+            {
+                if (configGestureCount == 0)
+                {
+                    panGestureDetector.Attach(this);
+                    longGestureDetector.Attach(this);
+                    pinchGestureDetector.Attach(this);
+                    tapGestureDetector.Attach(this);
+                    rotationGestureDetector.Attach(this);
+
+                    panGestureDetector.Detected += OnGestureDetected;
+                    longGestureDetector.Detected += OnGestureDetected;
+                    pinchGestureDetector.Detected += OnGestureDetected;
+                    tapGestureDetector.Detected += OnGestureDetected;
+                    rotationGestureDetector.Detected += OnGestureDetected;
+                }
+                configGestureCount++;
+            }
+        }
+
+        private void OnGestureDetected(object source, EventArgs e)
+        {
+            // Does notting. This is to consume the gesture.
+        }
+
+        /// <summary>
         /// Called when the view is hit through TouchEvent or GestureEvent.
         /// If it returns true, it means that it was hit, and the touch/gesture event is called from the view.
         /// If it returns false, it means that it will not be hit, and the hit-test continues to the next view.
@@ -3616,7 +3727,7 @@ SizeSetter++;
         /// <remarks>
         /// The <see cref="Size"/>, <see cref="Position"/>, <see cref="Color"/>, and <see cref="Scale"/> properties are set in the main thread.
         /// Therefore, it is not updated in real time when the value is changed in the render thread (for example, the value is changed during animation).
-        /// However, <see cref="CurrentSize"/>, <see cref="CurrentPosition"/>, <see cref="CurrentColor"/>, and <see cref="CurrentScale"/> properties are updated in real time, 
+        /// However, <see cref="CurrentSize"/>, <see cref="CurrentPosition"/>, <see cref="CurrentColor"/>, and <see cref="CurrentScale"/> properties are updated in real time,
         /// and users can get the current actual values through them.
         /// </remarks>
         [EditorBrowsable(EditorBrowsableState.Never)]
@@ -3628,7 +3739,7 @@ SizeSetter++;
         /// <remarks>
         /// The <see cref="Size"/>, <see cref="Position"/>, <see cref="Color"/>, and <see cref="Scale"/> properties are set in the main thread.
         /// Therefore, it is not updated in real time when the value is changed in the render thread (for example, the value is changed during animation).
-        /// However, <see cref="CurrentSize"/>, <see cref="CurrentPosition"/>, <see cref="CurrentColor"/>, and <see cref="CurrentScale"/> properties are updated in real time, 
+        /// However, <see cref="CurrentSize"/>, <see cref="CurrentPosition"/>, <see cref="CurrentColor"/>, and <see cref="CurrentScale"/> properties are updated in real time,
         /// and users can get the current actual values through them.
         /// </remarks>
         [EditorBrowsable(EditorBrowsableState.Never)]
index 1341f79..8135c96 100755 (executable)
@@ -1210,6 +1210,17 @@ namespace Tizen.NUI.BaseComponents
             internalSize2D?.Dispose();
             internalSize2D = null;
 
+            panGestureDetector?.Dispose();
+            panGestureDetector = null;
+            longGestureDetector?.Dispose();
+            longGestureDetector = null;
+            pinchGestureDetector?.Dispose();
+            pinchGestureDetector = null;
+            tapGestureDetector?.Dispose();
+            tapGestureDetector = null;
+            rotationGestureDetector?.Dispose();
+            rotationGestureDetector = null;
+
             if (type == DisposeTypes.Explicit)
             {
                 //Called by User
index 79546ca..351b804 100755 (executable)
@@ -217,6 +217,12 @@ namespace Tizen.NUI
                 e.View = Registry.GetManagedBaseHandleFromRefObject(actor) as View;
             }
 
+            // If DispatchGestureEvents is false, no gesture events are dispatched.
+            if (e.View != null && e.View.DispatchGestureEvents == false)
+            {
+                return;
+            }
+
             e.LongPressGesture = Tizen.NUI.LongPressGesture.GetLongPressGestureFromPtr(longPressGesture);
 
             if (detectedEventHandler != null)
index 64422af..27b9b95 100755 (executable)
@@ -569,6 +569,12 @@ namespace Tizen.NUI
                     e.View = Registry.GetManagedBaseHandleFromRefObject(actor) as View;
                 }
 
+                // If DispatchGestureEvents is false, no gesture events are dispatched.
+                if (e.View != null && e.View.DispatchGestureEvents == false)
+                {
+                    return;
+                }
+
                 e.PanGesture = Tizen.NUI.PanGesture.GetPanGestureFromPtr(panGesture);
                 detectedEventHandler(this, e);
             }
index 28f49f8..caa56a4 100755 (executable)
@@ -142,6 +142,12 @@ namespace Tizen.NUI
                     e.View = Registry.GetManagedBaseHandleFromRefObject(actor) as View;
                 }
 
+                // If DispatchGestureEvents is false, no gesture events are dispatched.
+                if (e.View != null && e.View.DispatchGestureEvents == false)
+                {
+                    return;
+                }
+
                 e.PinchGesture = Tizen.NUI.PinchGesture.GetPinchGestureFromPtr(pinchGesture);
                 //Here we send all data to user event handlers.
                 detectedEventHandler(this, e);
index f81b368..c48ff10 100755 (executable)
@@ -142,6 +142,12 @@ namespace Tizen.NUI
                     e.View = Registry.GetManagedBaseHandleFromRefObject(actor) as View;
                 }
 
+                // If DispatchGestureEvents is false, no gesture events are dispatched.
+                if (e.View != null && e.View.DispatchGestureEvents == false)
+                {
+                    return;
+                }
+
                 e.RotationGesture = Tizen.NUI.RotationGesture.GetRotationGestureFromPtr(rotationGesture);
                 //Here we send all data to user event handlers.
                 detectedEventHandler(this, e);
index 9e04e83..89ab9d7 100755 (executable)
@@ -205,6 +205,12 @@ namespace Tizen.NUI
                 e.View = Registry.GetManagedBaseHandleFromRefObject(actor) as View;
             }
 
+            // If DispatchGestureEvents is false, no gesture events are dispatched.
+            if (e.View != null && e.View.DispatchGestureEvents == false)
+            {
+                return;
+            }
+
             e.TapGesture = Tizen.NUI.TapGesture.GetTapGestureFromPtr(tapGesture);
 
             if (_detectedEventHandler != null)
index 0033cea..5d07c21 100755 (executable)
@@ -450,6 +450,7 @@ namespace Tizen.NUI
         [EditorBrowsable(EditorBrowsableState.Never)]
         public virtual bool OnLeftTopCornerIconTouched(object sender, View.TouchEventArgs e)
         {
+            SetDispatchParentGestureEvents(sender as View, false);
             if (e != null && e.Touch.GetState(0) == PointStateType.Down)
             {
               ClearWindowGesture();
@@ -468,6 +469,7 @@ namespace Tizen.NUI
         [EditorBrowsable(EditorBrowsableState.Never)]
         public virtual bool OnRightTopCornerIconTouched(object sender, View.TouchEventArgs e)
         {
+            SetDispatchParentGestureEvents(sender as View, false);
             if (e != null && e.Touch.GetState(0) == PointStateType.Down)
             {
               ClearWindowGesture();
@@ -487,6 +489,7 @@ namespace Tizen.NUI
         [EditorBrowsable(EditorBrowsableState.Never)]
         public virtual bool OnLeftBottomCornerIconTouched(object sender, View.TouchEventArgs e)
         {
+            SetDispatchParentGestureEvents(sender as View, false);
             if (e != null && e.Touch.GetState(0) == PointStateType.Down)
             {
               ClearWindowGesture();
@@ -505,6 +508,7 @@ namespace Tizen.NUI
         [EditorBrowsable(EditorBrowsableState.Never)]
         public virtual bool OnRightBottomCornerIconTouched(object sender, View.TouchEventArgs e)
         {
+            SetDispatchParentGestureEvents(sender as View, false);
             if (e != null && e.Touch.GetState(0) == PointStateType.Down)
             {
               ClearWindowGesture();
@@ -535,6 +539,7 @@ namespace Tizen.NUI
         [EditorBrowsable(EditorBrowsableState.Never)]
         public virtual bool OnMinimizeIconTouched(object sender, View.TouchEventArgs e)
         {
+            SetDispatchParentGestureEvents(sender as View, false);
             if (e != null && e.Touch.GetState(0) == PointStateType.Up)
             {
                 MinimizeBorderWindow();
@@ -565,6 +570,7 @@ namespace Tizen.NUI
         [EditorBrowsable(EditorBrowsableState.Never)]
         public virtual bool OnMaximizeIconTouched(object sender, View.TouchEventArgs e)
         {
+            SetDispatchParentGestureEvents(sender as View, false);
             if (e != null && e.Touch.GetState(0) == PointStateType.Up)
             {
                 MaximizeBorderWindow();
@@ -587,6 +593,7 @@ namespace Tizen.NUI
         [EditorBrowsable(EditorBrowsableState.Never)]
         public virtual bool OnCloseIconTouched(object sender, View.TouchEventArgs e)
         {
+            SetDispatchParentGestureEvents(sender as View, false);
             if (e != null && e.Touch.GetState(0) == PointStateType.Up)
             {
                 CloseBorderWindow();
@@ -594,6 +601,16 @@ namespace Tizen.NUI
             return true;
         }
 
+        private void SetDispatchParentGestureEvents(View view, bool dispatch)
+        {
+            if (view != null)
+            {
+                // If this is set, my parents will not receive gesture events.
+                // This is to prevent the move action by PanGesture when the icon is touched.
+                view.DispatchParentGestureEvents = dispatch;
+            }
+        }
+
 
         private void UpdateIcons()
         {