Pārlūkot izejas kodu

click outside of border cancels arrangemode

Tig 10 mēneši atpakaļ
vecāks
revīzija
6aba0e573f

+ 4 - 0
Terminal.Gui/Application/ApplicationNavigation.cs

@@ -1,5 +1,7 @@
 #nullable enable
 
+using System.Diagnostics;
+
 namespace Terminal.Gui;
 
 /// <summary>
@@ -76,6 +78,8 @@ public class ApplicationNavigation
             return;
         }
 
+        Debug.Assert(value is {});
+
         _focused = value;
 
         FocusedChanged?.Invoke (null, EventArgs.Empty);

+ 7 - 1
Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs

@@ -591,7 +591,13 @@ public abstract class ConsoleDriver
 
     /// <summary>Called when a mouse event occurs. Fires the <see cref="MouseEvent"/> event.</summary>
     /// <param name="a"></param>
-    public void OnMouseEvent (MouseEvent a) { MouseEvent?.Invoke (this, a); }
+    public void OnMouseEvent (MouseEvent a)
+    {
+        // Ensure ScreenPosition is set
+        a.ScreenPosition = a.Position;
+
+        MouseEvent?.Invoke (this, a);
+    }
 
     /// <summary>Simulates a key press.</summary>
     /// <param name="keyChar">The key character.</param>

+ 53 - 21
Terminal.Gui/View/Adornment/Border.cs

@@ -1,5 +1,6 @@
 #nullable enable
 using System.Diagnostics;
+using Microsoft.CodeAnalysis;
 using static Terminal.Gui.SpinnerStyle;
 
 namespace Terminal.Gui;
@@ -66,6 +67,7 @@ public class Border : Adornment
         Highlight += Border_Highlight;
     }
 
+
 #if SUBVIEW_BASED_BORDER
     private Line _left;
 
@@ -289,13 +291,12 @@ public class Border : Adornment
             return true;
         }
 
-        // BUGBUG: Shouldn't non-focusable views be draggable??
-        //if (!Parent.CanFocus)
-        //{
-        //    return false;
-        //}
-
-        if (!Parent!.Arrangement.HasFlag (ViewArrangement.Movable))
+        if (!Parent!.Arrangement.HasFlag (ViewArrangement.Movable)
+            && !Parent!.Arrangement.HasFlag (ViewArrangement.BottomResizable)
+            && !Parent!.Arrangement.HasFlag (ViewArrangement.TopResizable)
+            && !Parent!.Arrangement.HasFlag (ViewArrangement.LeftResizable)
+            && !Parent!.Arrangement.HasFlag (ViewArrangement.RightResizable)
+           )
         {
             return false;
         }
@@ -321,9 +322,9 @@ public class Border : Adornment
             return true;
         }
 
-        if (mouseEvent.Flags is (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition))
+        if (mouseEvent.Flags is (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) && Application.MouseGrabView == this)
         {
-            if (Application.MouseGrabView == this && _dragPosition.HasValue)
+            if (_dragPosition.HasValue)
             {
                 if (Parent.SuperView is null)
                 {
@@ -368,16 +369,6 @@ public class Border : Adornment
         return false;
     }
 
-    /// <inheritdoc/>
-    protected override void Dispose (bool disposing)
-    {
-        Application.GrabbingMouse -= Application_GrabbingMouse;
-        Application.UnGrabbingMouse -= Application_UnGrabbingMouse;
-
-        _dragPosition = null;
-        base.Dispose (disposing);
-    }
-
     private void Application_GrabbingMouse (object? sender, GrabMouseEventArgs e)
     {
         if (Application.MouseGrabView == this && _dragPosition.HasValue)
@@ -771,7 +762,6 @@ public class Border : Adornment
         Add (_arrangeButton);
 
         CanFocus = true;
-        //_arrangeButton.SetFocus ();
 
         AddCommand (Command.Quit, EndArrange);
 
@@ -876,6 +866,9 @@ public class Border : Adornment
         KeyBindings.Add (Key.Tab, KeyBindingScope.HotKey, Command.Tab);
         KeyBindings.Add (Key.Tab.WithShift, KeyBindingScope.HotKey, Command.BackTab);
 
+        Application.MouseEvent += ApplicationOnMouseEvent;
+
+
         if (Parent!.Arrangement.HasFlag (ViewArrangement.Movable))
         {
             _arranging = ViewArrangement.Movable;
@@ -923,9 +916,38 @@ public class Border : Adornment
             return true;
         }
     }
+
+    private void ApplicationOnMouseEvent (object? sender, MouseEvent e)
+    {
+        if (e.Flags != MouseFlags.Button1Clicked)
+        {
+            return;
+        }
+
+        // If mouse click is outside of Border.Thickness then exit Arrange Mode
+        // e.Position is screen relative
+        Point framePos = ScreenToFrame(e.ScreenPosition);
+
+        if (!Thickness.Contains (Frame, framePos))
+        {
+            EndArrange ();
+
+            return;
+        }
+    }
+
     private bool? EndArrange ()
     {
+        Debug.Assert (_arranging != ViewArrangement.Fixed);
         _arranging = ViewArrangement.Fixed;
+
+        Application.MouseEvent -= ApplicationOnMouseEvent;
+
+        if (Application.MouseGrabView == this && _dragPosition.HasValue)
+        {
+            Application.UngrabMouse();
+        }
+
         CanFocus = false;
 
         if (_arrangeButton is { })
@@ -937,7 +959,17 @@ public class Border : Adornment
 
         KeyBindings.Clear ();
 
-
         return true;
     }
+
+    /// <inheritdoc/>
+    protected override void Dispose (bool disposing)
+    {
+        Application.GrabbingMouse -= Application_GrabbingMouse;
+        Application.UnGrabbingMouse -= Application_UnGrabbingMouse;
+
+        _dragPosition = null;
+        base.Dispose (disposing);
+    }
+
 }

+ 23 - 10
Terminal.Gui/View/View.Navigation.cs

@@ -573,27 +573,40 @@ public partial class View // Focus and cross-view navigation management (TabStop
         // If newFocusedVew is null, we need to find the view that should get focus, and SetFocus on it.
         if (!traversingDown && newFocusedView is null)
         {
-            if (SuperView?._previouslyMostFocused is { } && SuperView?._previouslyMostFocused != this)
+            if (SuperView?._previouslyMostFocused is { })
             {
-                SuperView?._previouslyMostFocused?.SetFocus ();
+                if (SuperView?._previouslyMostFocused != this)
+                {
+                    SuperView?._previouslyMostFocused?.SetFocus ();
 
-                // The above will cause SetHasFocusFalse, so we can return
-                return;
+                    // The above will cause SetHasFocusFalse, so we can return
+                    return;
+                }
+                newFocusedView = SuperView?._previouslyMostFocused;
             }
 
-            if (SuperView is { } && SuperView.AdvanceFocus (NavigationDirection.Forward, TabStop))
+            if (SuperView is { })
             {
-                // The above will cause SetHasFocusFalse, so we can return
-                return;
+                if (SuperView.AdvanceFocus (NavigationDirection.Forward, TabStop))
+                {
+                    // The above will cause SetHasFocusFalse, so we can return
+                    return;
+                }
+                newFocusedView = SuperView;
             }
 
+
             // Are we an Adornment? 
             if (this is Adornment ad)
             {
-                if (ad.Parent is {} && ad.Parent.RestoreFocus ())
+                if (ad.Parent is {})
                 {
-                    // The above will cause SetHasFocusFalse, so we can return
-                    return;
+                    if (ad.Parent.RestoreFocus ())
+                    {
+                        // The above will cause SetHasFocusFalse, so we can return
+                        return;
+                    }
+                    newFocusedView = ad.Parent;
                 }
             }