Browse Source

Refixed Adornment view drag. Still some issues.

Tig Kindel 1 year ago
parent
commit
3a834ac5dc

+ 15 - 15
Terminal.Gui/Application.cs

@@ -1404,19 +1404,19 @@ public static partial class Application
         {
             // If the mouse is grabbed, send the event to the view that grabbed it.
             // The coordinates are relative to the Bounds of the view that grabbed the mouse.
-            Point newxy = MouseGrabView.ScreenToFrame (a.MouseEvent.X, a.MouseEvent.Y);
+            Point frameLoc = MouseGrabView.ScreenToFrame (a.MouseEvent.X, a.MouseEvent.Y);
 
-            var nme = new MouseEvent
+            var viewRelativeMouseEvent = new MouseEvent
             {
-                X = newxy.X,
-                Y = newxy.Y,
+                X = frameLoc.X,
+                Y = frameLoc.Y,
                 Flags = a.MouseEvent.Flags,
-                OfX = a.MouseEvent.X - newxy.X,
-                OfY = a.MouseEvent.Y - newxy.Y,
+                ScreenX = a.MouseEvent.X,
+                ScreenY = a.MouseEvent.Y,
                 View = view
             };
 
-            if (MouseGrabView.Bounds.Contains (nme.X, nme.Y) is false)
+            if (MouseGrabView.Bounds.Contains (viewRelativeMouseEvent.X, viewRelativeMouseEvent.Y) is false)
             {
                 // The mouse has moved outside the bounds of the view that
                 // grabbed the mouse, so we tell the view that last got 
@@ -1426,7 +1426,7 @@ public static partial class Application
             }
 
             //System.Diagnostics.Debug.WriteLine ($"{nme.Flags};{nme.X};{nme.Y};{mouseGrabView}");
-            if (MouseGrabView?.OnMouseEvent (nme) == true)
+            if (MouseGrabView?.OnMouseEvent (viewRelativeMouseEvent) == true)
             {
                 return;
             }
@@ -1461,15 +1461,15 @@ public static partial class Application
 
         if (view is Adornment adornment)
         {
-            Rectangle screen = adornment.FrameToScreen ();
+            var frameLoc = adornment.ScreenToFrame (a.MouseEvent.X, a.MouseEvent.Y);
 
             me = new MouseEvent
             {
-                X = a.MouseEvent.X - screen.X,
-                Y = a.MouseEvent.Y - screen.Y,
+                X = frameLoc.X,
+                Y = frameLoc.Y,
                 Flags = a.MouseEvent.Flags,
-                OfX = a.MouseEvent.X - screen.X,
-                OfY = a.MouseEvent.Y - screen.Y,
+                ScreenX = a.MouseEvent.X,
+                ScreenY = a.MouseEvent.Y,
                 View = view
             };
         }
@@ -1482,8 +1482,8 @@ public static partial class Application
                 X = boundsPoint.X,
                 Y = boundsPoint.Y,
                 Flags = a.MouseEvent.Flags,
-                OfX = boundsPoint.X,
-                OfY = boundsPoint.Y,
+                ScreenX = a.MouseEvent.X,
+                ScreenY = a.MouseEvent.X,
                 View = view
             };
         }

+ 43 - 18
Terminal.Gui/Input/Mouse.cs

@@ -96,11 +96,11 @@ public enum MouseFlags
 // TODO: Merge MouseEvent and MouseEventEventArgs into a single class.
 
 /// <summary>
-///     Low-level construct that conveys the details of mouse events, such as coordinates and button state, from
+///     Conveys the details of mouse events, such as coordinates and button state, from
 ///     ConsoleDrivers up to <see cref="Application"/> and Views.
 /// </summary>
 /// <remarks>
-///     The <see cref="Application"/> class includes the <see cref="Application.MouseEvent"/> Action which takes a
+///     The <see cref="Application"/> class includes the <see cref="Application.MouseEvent"/> event which takes a
 ///     MouseEvent argument.
 /// </remarks>
 public class MouseEvent
@@ -108,28 +108,53 @@ public class MouseEvent
     /// <summary>Flags indicating the kind of mouse event that is being posted.</summary>
     public MouseFlags Flags { get; set; }
 
-    /// <summary>
-    ///     Indicates if the current mouse event has already been processed and the driver should stop notifying any other
-    ///     event subscriber. Its important to set this value to true specially when updating any View's layout from inside the
-    ///     subscriber method.
-    /// </summary>
-    public bool Handled { get; set; }
-
-    /// <summary>The offset X (column) location for the mouse event.</summary>
-    public int OfX { get; set; }
-
-    /// <summary>The offset Y (column) location for the mouse event.</summary>
-    public int OfY { get; set; }
-
-    /// <summary>The current view at the location for the mouse event.</summary>
+    /// <summary>The View at the location for the mouse event.</summary>
     public View View { get; set; }
 
-    /// <summary>The X (column) location for the mouse event.</summary>
+    /// <summary>The X (column) location of the mouse in <see cref="View.Bounds"/>-relative coordinates.</summary>
     public int X { get; set; }
 
-    /// <summary>The Y (column) location for the mouse event.</summary>
+    /// <summary>The Y (column) location of the mouse in <see cref="View.Bounds"/>-relative coordinates.</summary>
     public int Y { get; set; }
 
+    /// <summary>
+    ///     Indicates if the current mouse event has been processed. Set this value to <see langword="true"/> to indicate the mouse
+    ///     event was handled.
+    /// </summary>
+    public bool Handled { get; set; }
+
+    /// <summary>
+    ///     The screen-relative mouse coordinate.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         Calculated and processed in <see cref="Application.OnMouseEvent(MouseEventEventArgs)"/>.
+    ///     </para>
+    ///     <para>
+    ///         The View that has called <see cref="Application.GrabMouse"/> will receive all mouse events
+    ///         with <see cref="View.Bounds"/>-relative coordinates. <see cref="ScreenX"/> and <see cref="ScreenY"/> provide
+    ///         the screen-relative offset of these coordinates, enabling the grabbed view to know how much the
+    ///         mouse has moved.
+    ///     </para>
+    /// </remarks>
+    public int ScreenX { get; set; }
+
+    /// <summary>
+    ///     The screen-relative mouse coordinate.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         Calculated and processed in <see cref="Application.OnMouseEvent(MouseEventEventArgs)"/>.
+    ///     </para>
+    ///     <para>
+    ///         The View that has called <see cref="Application.GrabMouse"/> will receive all mouse events
+    ///         with <see cref="View.Bounds"/>-relative coordinates. <see cref="ScreenX"/> and <see cref="ScreenY"/> provide
+    ///         the screen-relative offset of these coordinates, enabling the grabbed view to know how much the
+    ///         mouse has moved.
+    ///     </para>
+    /// </remarks>
+    public int ScreenY { get; set; }
+
     /// <summary>Returns a <see cref="T:System.String"/> that represents the current <see cref="MouseEvent"/>.</summary>
     /// <returns>A <see cref="T:System.String"/> that represents the current <see cref="MouseEvent"/>.</returns>
     public override string ToString () { return $"({X},{Y}):{Flags}"; }

+ 14 - 14
Terminal.Gui/View/Adornment/Adornment.cs

@@ -212,20 +212,17 @@ public class Adornment : View
 
         int nx, ny;
 
-        if (!_dragPosition.HasValue
-            && (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)
-                || mouseEvent.Flags.HasFlag (MouseFlags.Button2Pressed)
-                || mouseEvent.Flags.HasFlag (MouseFlags.Button3Pressed)))
+        if (!_dragPosition.HasValue && (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)))
         {
             Parent.SetFocus ();
             Application.BringOverlappedTopToFront ();
 
-            // Only start grabbing if the user clicks on the title bar.
-            if (mouseEvent.Y == 0 && mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed))
+            // Only start grabbing if the user clicks in the Thickness area
+            if (Thickness.Contains (Frame, mouseEvent.X, mouseEvent.Y) && mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed))
             {
                 _startGrabPoint = new (mouseEvent.X, mouseEvent.Y);
-                nx = mouseEvent.X - mouseEvent.OfX;
-                ny = mouseEvent.Y - mouseEvent.OfY;
+                nx = mouseEvent.ScreenX;
+                ny = mouseEvent.ScreenY;
                 _dragPosition = new Point (nx, ny);
                 Application.GrabMouse (this);
             }
@@ -233,9 +230,9 @@ public class Adornment : View
             return true;
         }
 
-        if (mouseEvent.Flags == (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) || mouseEvent.Flags == MouseFlags.Button3Pressed)
+        if (mouseEvent.Flags is (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition))
         {
-            if (_dragPosition.HasValue)
+            if (Application.MouseGrabView == this && _dragPosition.HasValue)
             {
                 if (Parent.SuperView is null)
                 {
@@ -247,20 +244,23 @@ public class Adornment : View
                     Parent.SuperView.SetNeedsDisplay ();
                 }
 
+                _dragPosition = new Point (mouseEvent.X, mouseEvent.Y);
+
+                var parentLoc = Parent.SuperView?.ScreenToBounds (mouseEvent.ScreenX, mouseEvent.ScreenY) ?? new (mouseEvent.ScreenX, mouseEvent.ScreenY);
                 GetLocationThatFits (
                                      Parent,
-                                     mouseEvent.X + mouseEvent.OfX - _startGrabPoint.X,
-                                     mouseEvent.Y + mouseEvent.OfY - _startGrabPoint.Y,
+                                     parentLoc.X - _startGrabPoint.X,
+                                     parentLoc.Y - _startGrabPoint.Y,
                                      out nx,
                                      out ny,
                                      out _,
                                      out _
                                     );
 
-                _dragPosition = new Point (nx, ny);
+
                 Parent.X = nx;
                 Parent.Y = ny;
-                Parent.SetNeedsDisplay ();
+                //Parent.SetNeedsDisplay ();
 
                 return true;
             }

+ 23 - 16
Terminal.Gui/View/Layout/ViewLayout.cs

@@ -764,6 +764,13 @@ public partial class View
     public Point ScreenToFrame (int x, int y)
     {
         Point superViewBoundsOffset = SuperView?.GetBoundsOffset () ?? Point.Empty;
+        // BUGBUG: Hack. Move into Adornment somehow.
+        if (this is Adornment adornment)
+        {
+            superViewBoundsOffset = adornment.Parent.SuperView?.GetBoundsOffset () ?? Point.Empty;
+            return adornment.Parent.ScreenToFrame (x, y);
+        }
+
         var ret = new Point (x - Frame.X - superViewBoundsOffset.X, y - Frame.Y - superViewBoundsOffset.Y);
 
         if (SuperView is { })
@@ -901,30 +908,30 @@ public partial class View
         out StatusBar statusBar
     )
     {
-        int maxWidth;
+        int maxDimension;
         View superView;
 
         if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
         {
-            maxWidth = Driver.Cols;
+            maxDimension = Driver.Cols;
             superView = Application.Top;
         }
         else
         {
             // Use the SuperView's Bounds, not Frame
-            maxWidth = top.SuperView.Bounds.Width;
+            maxDimension = top.SuperView.Bounds.Width;
             superView = top.SuperView;
         }
 
         if (superView.Margin is { } && superView == top.SuperView)
         {
-            maxWidth -= superView.GetAdornmentsThickness ().Left + superView.GetAdornmentsThickness ().Right;
+            maxDimension -= superView.GetAdornmentsThickness ().Left + superView.GetAdornmentsThickness ().Right;
         }
 
-        if (top.Frame.Width <= maxWidth)
+        if (top.Frame.Width <= maxDimension)
         {
             nx = Math.Max (targetX, 0);
-            nx = nx + top.Frame.Width > maxWidth ? Math.Max (maxWidth - top.Frame.Width, 0) : nx;
+            nx = nx + top.Frame.Width > maxDimension ? Math.Max (maxDimension - top.Frame.Width, 0) : nx;
 
             if (nx > top.Frame.X + top.Frame.Width)
             {
@@ -959,14 +966,14 @@ public partial class View
 
         if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
         {
-            maxWidth = menuVisible ? 1 : 0;
+            maxDimension = menuVisible ? 1 : 0;
         }
         else
         {
-            maxWidth = 0;
+            maxDimension = 0;
         }
 
-        ny = Math.Max (targetY, maxWidth);
+        ny = Math.Max (targetY, maxDimension);
 
         if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
         {
@@ -988,24 +995,24 @@ public partial class View
 
         if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
         {
-            maxWidth = statusVisible ? Driver.Rows - 1 : Driver.Rows;
+            maxDimension = statusVisible ? Driver.Rows - 1 : Driver.Rows;
         }
         else
         {
-            maxWidth = statusVisible ? top.SuperView.Frame.Height - 1 : top.SuperView.Frame.Height;
+            maxDimension = statusVisible ? top.SuperView.Frame.Height - 1 : top.SuperView.Frame.Height;
         }
 
         if (superView.Margin is { } && superView == top.SuperView)
         {
-            maxWidth -= superView.GetAdornmentsThickness ().Top + superView.GetAdornmentsThickness ().Bottom;
+            maxDimension -= superView.GetAdornmentsThickness ().Top + superView.GetAdornmentsThickness ().Bottom;
         }
 
-        ny = Math.Min (ny, maxWidth);
+        ny = Math.Min (ny, maxDimension);
 
-        if (top.Frame.Height <= maxWidth)
+        if (top.Frame.Height <= maxDimension)
         {
-            ny = ny + top.Frame.Height > maxWidth
-                     ? Math.Max (maxWidth - top.Frame.Height, menuVisible ? 1 : 0)
+            ny = ny + top.Frame.Height > maxDimension
+                     ? Math.Max (maxDimension - top.Frame.Height, menuVisible ? 1 : 0)
                      : ny;
 
             if (ny > top.Frame.Y + top.Frame.Height)

+ 4 - 5
Terminal.Gui/Views/Menu/MenuBar.cs

@@ -1795,8 +1795,8 @@ public class MenuBar : View
                             X = newxy.X,
                             Y = newxy.Y,
                             Flags = me.Flags,
-                            OfX = me.X - newxy.X,
-                            OfY = me.Y - newxy.Y,
+                            ScreenX = me.X - newxy.X,
+                            ScreenY = me.Y - newxy.Y,
                             View = v
                         };
                     }
@@ -1804,7 +1804,6 @@ public class MenuBar : View
                     {
                         nme = new MouseEvent { X = me.X + current.Frame.X, Y = 0, Flags = me.Flags, View = v };
                     }
-
                     v.OnMouseEvent (nme);
 
                     return false;
@@ -1842,11 +1841,11 @@ public class MenuBar : View
                                           MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
                                          )))
         {
-            Application.GrabMouse (current);
+           Application.GrabMouse (current);
         }
         else if (IsMenuOpen && (me.View is MenuBar || me.View is Menu))
         {
-            Application.GrabMouse (me.View);
+           Application.GrabMouse (me.View);
         }
         else
         {

+ 1 - 1
Terminal.Gui/Views/TextField.cs

@@ -1773,7 +1773,7 @@ public class TextField : View
 
         if (_text.Count == 0)
         {
-            x = pX - ev.OfX;
+            x = pX - ev.ScreenX;
         }
         else
         {

+ 1 - 0
Terminal.Gui/Views/Toplevel.cs

@@ -379,6 +379,7 @@ public partial class Toplevel : View
     /// <param name="top">The Toplevel to adjust.</param>
     public virtual void PositionToplevel (Toplevel top)
     {
+        return;
         View superView = GetLocationThatFits (
                                               top,
                                               top.Frame.X,

+ 3 - 2
UICatalog/Scenarios/Adornments.cs

@@ -17,7 +17,7 @@ public class Adornments : Scenario
         ConfigurationManager.Themes.Theme = Theme;
         ConfigurationManager.Apply ();
         Application.Top.ColorScheme = Colors.ColorSchemes [TopLevelColorScheme];
-
+        
         var view = new Window { Title = "The _Window" };
         var tf1 = new TextField { Width = 10, Text = "TextField" };
         var color = new ColorPicker { Title = "BG", BoxHeight = 1, BoxWidth = 1, X = Pos.AnchorEnd (11) };
@@ -75,7 +75,8 @@ public class Adornments : Scenario
         var editor = new AdornmentsEditor
         {
             Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
-            ColorScheme = Colors.ColorSchemes [TopLevelColorScheme]
+            ColorScheme = Colors.ColorSchemes [TopLevelColorScheme],
+            //BorderStyle = LineStyle.None,
         };
         view.X = 36;
         view.Y = 0;