Explorar el Código

Prevents continuous mouse button pressed from processing mouse event without slider completed the layout.

BDisp hace 11 meses
padre
commit
92e067e014
Se han modificado 2 ficheros con 37 adiciones y 6 borrados
  1. 22 5
      Terminal.Gui/Views/Scroll/Scroll.cs
  2. 15 1
      Terminal.Gui/Views/Scroll/ScrollSlider.cs

+ 22 - 5
Terminal.Gui/Views/Scroll/Scroll.cs

@@ -22,12 +22,12 @@ public class Scroll : View
         Height = Dim.Auto (DimAutoStyle.Content, 1);
     }
 
-    private readonly ScrollSlider _slider;
 
-    private Orientation _orientation;
+    internal bool _wasSliderLayoutComplete = true;
 
+    private readonly ScrollSlider _slider;
+    private Orientation _orientation;
     private int _position;
-
     private int _size;
 
     /// <inheritdoc/>
@@ -118,6 +118,12 @@ public class Scroll : View
     /// <inheritdoc/>
     protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
     {
+        if (!_wasSliderLayoutComplete)
+        {
+            // Do not process if slider layout wasn't yet completed
+            return base.OnMouseEvent (mouseEvent);
+        }
+
         int location = Orientation == Orientation.Vertical ? mouseEvent.Position.Y : mouseEvent.Position.X;
         int barSize = Orientation == Orientation.Vertical ? GetContentSize ().Height : GetContentSize ().Width;
 
@@ -125,11 +131,11 @@ public class Scroll : View
                                                        ? new (_slider.Frame.Y, _slider.Frame.Bottom - 1)
                                                        : new (_slider.Frame.X, _slider.Frame.Right - 1);
 
-        if (mouseEvent.Flags == MouseFlags.Button1Pressed && location < sliderPos.topLeft)
+        if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) && location < sliderPos.topLeft)
         {
             Position = Math.Max (Position - barSize, 0);
         }
-        else if (mouseEvent.Flags == MouseFlags.Button1Pressed && location > sliderPos.bottomRight)
+        else if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) && location > sliderPos.bottomRight)
         {
             Position = Math.Min (Position + barSize, Size - barSize);
         }
@@ -150,10 +156,21 @@ public class Scroll : View
                 return _slider.OnMouseEvent (mouseEvent);
             }
         }
+        // Flag as false until slider layout is completed
+        _wasSliderLayoutComplete = false;
 
         return base.OnMouseEvent (mouseEvent);
     }
 
+    /// <inheritdoc/>
+    protected internal override bool OnMouseLeave (MouseEvent mouseEvent)
+    {
+        // If scroll isn't handling mouse then reset the flag
+        _wasSliderLayoutComplete = true;
+
+        return base.OnMouseLeave (mouseEvent);
+    }
+
     // TODO: Move this into "ScrollSlider" and override it there. Scroll can then subscribe to _slider.LayoutComplete and call AdjustSlider.
     // QUESTION: I've been meaning to add a "View.FrameChanged" event (fired from LayoutComplete only if Frame has changed). Should we do that as part of this PR?
     // QUESTION: Note I *did* add "View.ViewportChanged" in a previous PR.

+ 15 - 1
Terminal.Gui/Views/Scroll/ScrollSlider.cs

@@ -73,11 +73,17 @@ internal class ScrollSlider : View
     /// <inheritdoc/>
     protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
     {
+        if (!_host._wasSliderLayoutComplete)
+        {
+            // Ensure not blocking scroll mouse event
+            _host._wasSliderLayoutComplete = true;
+        }
+
         int location = _host.Orientation == Orientation.Vertical ? mouseEvent.Position.Y : mouseEvent.Position.X;
         int offset = _lastLocation > -1 ? location - _lastLocation : 0;
         int barSize = _host.Orientation == Orientation.Vertical ? _host.GetContentSize ().Height : _host.GetContentSize ().Width;
 
-        if (mouseEvent.Flags == MouseFlags.Button1Pressed)
+        if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) && _lastLocation == -1)
         {
             if (Application.MouseGrabView != this)
             {
@@ -143,6 +149,14 @@ internal class ScrollSlider : View
         return base.OnMouseLeave (mouseEvent);
     }
 
+    /// <inheritdoc />
+    internal override void OnLayoutComplete (LayoutEventArgs args)
+    {
+        base.OnLayoutComplete (args);
+
+        _host._wasSliderLayoutComplete = true;
+    }
+
     private int GetPositionFromSliderLocation (int location)
     {
         if (_host.GetContentSize ().Height == 0 || _host.GetContentSize ().Width == 0)