|
@@ -20,10 +20,6 @@ namespace Terminal.Gui;
|
|
|
/// </remarks>
|
|
|
public partial class Toplevel : View
|
|
|
{
|
|
|
- internal static Point? _dragPosition;
|
|
|
-
|
|
|
- private Point _startGrabPoint;
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// Initializes a new instance of the <see cref="Toplevel"/> class with <see cref="LayoutStyle.Computed"/> layout,
|
|
|
/// defaulting to full screen. The <see cref="View.Width"/> and <see cref="View.Height"/> properties will be set to the
|
|
@@ -36,13 +32,6 @@ public partial class Toplevel : View
|
|
|
|
|
|
ColorScheme = Colors.ColorSchemes ["TopLevel"];
|
|
|
|
|
|
- Application.GrabbingMouse += Application_GrabbingMouse;
|
|
|
- Application.UnGrabbingMouse += Application_UnGrabbingMouse;
|
|
|
-
|
|
|
- // TODO: v2 - ALL Views (Responders??!?!) should support the commands related to
|
|
|
- // - Focus
|
|
|
- // Move the appropriate AddCommand calls to `Responder`
|
|
|
-
|
|
|
// Things this view knows how to do
|
|
|
AddCommand (
|
|
|
Command.QuitToplevel,
|
|
@@ -236,100 +225,6 @@ public partial class Toplevel : View
|
|
|
/// </summary>
|
|
|
public event EventHandler Loaded;
|
|
|
|
|
|
- /// <inheritdoc/>
|
|
|
- protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
|
|
|
- {
|
|
|
- if (!CanFocus)
|
|
|
- {
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- //System.Diagnostics.Debug.WriteLine ($"dragPosition before: {dragPosition.HasValue}");
|
|
|
-
|
|
|
- int nx, ny;
|
|
|
-
|
|
|
- if (!_dragPosition.HasValue
|
|
|
- && (mouseEvent.Flags == MouseFlags.Button1Pressed
|
|
|
- || mouseEvent.Flags == MouseFlags.Button2Pressed
|
|
|
- || mouseEvent.Flags == MouseFlags.Button3Pressed))
|
|
|
- {
|
|
|
- SetFocus ();
|
|
|
- Application.BringOverlappedTopToFront ();
|
|
|
-
|
|
|
- // Only start grabbing if the user clicks on the title bar.
|
|
|
- // BUGBUG: Assumes Frame == Border and Title is always at Y == 0
|
|
|
- if (mouseEvent.Y == 0 && mouseEvent.Flags == MouseFlags.Button1Pressed)
|
|
|
- {
|
|
|
- _startGrabPoint = new Point (mouseEvent.X, mouseEvent.Y);
|
|
|
- _dragPosition = Point.Empty;
|
|
|
- nx = mouseEvent.X - mouseEvent.OfX;
|
|
|
- ny = mouseEvent.Y - mouseEvent.OfY;
|
|
|
- _dragPosition = new Point (nx, ny);
|
|
|
- Application.GrabMouse (this);
|
|
|
- }
|
|
|
-
|
|
|
- //System.Diagnostics.Debug.WriteLine ($"Starting at {dragPosition}");
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- if (mouseEvent.Flags == (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) || mouseEvent.Flags == MouseFlags.Button3Pressed)
|
|
|
- {
|
|
|
- if (_dragPosition.HasValue)
|
|
|
- {
|
|
|
- if (SuperView is null)
|
|
|
- {
|
|
|
- // Redraw the entire app window using just our Frame. Since we are
|
|
|
- // Application.Top, and our Frame always == our Bounds (Location is always (0,0))
|
|
|
- // our Frame is actually view-relative (which is what Redraw takes).
|
|
|
- // We need to pass all the view bounds because since the windows was
|
|
|
- // moved around, we don't know exactly what was the affected region.
|
|
|
- Application.Top.SetNeedsDisplay ();
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- SuperView.SetNeedsDisplay ();
|
|
|
- }
|
|
|
-
|
|
|
- // BUGBUG: Assumes Frame == Border?
|
|
|
- GetLocationThatFits (
|
|
|
- this,
|
|
|
- mouseEvent.X
|
|
|
- + (SuperView == null
|
|
|
- ? mouseEvent.OfX - _startGrabPoint.X
|
|
|
- : Frame.X - _startGrabPoint.X),
|
|
|
- mouseEvent.Y
|
|
|
- + (SuperView == null
|
|
|
- ? mouseEvent.OfY - _startGrabPoint.Y
|
|
|
- : Frame.Y - _startGrabPoint.Y),
|
|
|
- out nx,
|
|
|
- out ny,
|
|
|
- out _,
|
|
|
- out _
|
|
|
- );
|
|
|
-
|
|
|
- _dragPosition = new Point (nx, ny);
|
|
|
- X = nx;
|
|
|
- Y = ny;
|
|
|
-
|
|
|
- //System.Diagnostics.Debug.WriteLine ($"Drag: nx:{nx},ny:{ny}");
|
|
|
-
|
|
|
- SetNeedsDisplay ();
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Released) && _dragPosition.HasValue)
|
|
|
- {
|
|
|
- _dragPosition = null;
|
|
|
- Application.UngrabMouse ();
|
|
|
- }
|
|
|
-
|
|
|
- //System.Diagnostics.Debug.WriteLine ($"dragPosition after: {dragPosition.HasValue}");
|
|
|
- //System.Diagnostics.Debug.WriteLine ($"Toplevel: {mouseEvent}");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
/// <summary>Virtual method to invoke the <see cref="AlternateBackwardKeyChanged"/> event.</summary>
|
|
|
/// <param name="e"></param>
|
|
|
public virtual void OnAlternateBackwardKeyChanged (KeyChangedEventArgs e)
|
|
@@ -646,17 +541,7 @@ public partial class Toplevel : View
|
|
|
/// to dispose objects after calling <see cref="Application.End(RunState)"/>.
|
|
|
/// </summary>
|
|
|
public event EventHandler Unloaded;
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- protected override void Dispose (bool disposing)
|
|
|
- {
|
|
|
- Application.GrabbingMouse -= Application_GrabbingMouse;
|
|
|
- Application.UnGrabbingMouse -= Application_UnGrabbingMouse;
|
|
|
-
|
|
|
- _dragPosition = null;
|
|
|
- base.Dispose (disposing);
|
|
|
- }
|
|
|
-
|
|
|
+
|
|
|
internal void AddMenuStatusBar (View view)
|
|
|
{
|
|
|
if (view is MenuBar)
|
|
@@ -670,154 +555,6 @@ public partial class Toplevel : View
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// Gets a new location of the <see cref="Toplevel"/> that is within the Bounds of the <paramref name="top"/>'s
|
|
|
- /// <see cref="View.SuperView"/> (e.g. for dragging a Window). The `out` parameters are the new X and Y coordinates.
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// If <paramref name="top"/> does not have a <see cref="View.SuperView"/> or it's SuperView is not
|
|
|
- /// <see cref="Application.Top"/> the position will be bound by the <see cref="ConsoleDriver.Cols"/> and
|
|
|
- /// <see cref="ConsoleDriver.Rows"/>.
|
|
|
- /// </remarks>
|
|
|
- /// <param name="top">The Toplevel that is to be moved.</param>
|
|
|
- /// <param name="targetX">The target x location.</param>
|
|
|
- /// <param name="targetY">The target y location.</param>
|
|
|
- /// <param name="nx">The x location that will ensure <paramref name="top"/> will be visible.</param>
|
|
|
- /// <param name="ny">The y location that will ensure <paramref name="top"/> will be visible.</param>
|
|
|
- /// <param name="menuBar">The new top most menuBar</param>
|
|
|
- /// <param name="statusBar">The new top most statusBar</param>
|
|
|
- /// <returns>
|
|
|
- /// Either <see cref="Application.Top"/> (if <paramref name="top"/> does not have a Super View) or
|
|
|
- /// <paramref name="top"/>'s SuperView. This can be used to ensure LayoutSubviews is called on the correct View.
|
|
|
- /// </returns>
|
|
|
- internal View GetLocationThatFits (
|
|
|
- Toplevel top,
|
|
|
- int targetX,
|
|
|
- int targetY,
|
|
|
- out int nx,
|
|
|
- out int ny,
|
|
|
- out MenuBar menuBar,
|
|
|
- out StatusBar statusBar
|
|
|
- )
|
|
|
- {
|
|
|
- int maxWidth;
|
|
|
- View superView;
|
|
|
-
|
|
|
- if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
|
|
|
- {
|
|
|
- maxWidth = Driver.Cols;
|
|
|
- superView = Application.Top;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // Use the SuperView's Bounds, not Frame
|
|
|
- maxWidth = top.SuperView.Bounds.Width;
|
|
|
- superView = top.SuperView;
|
|
|
- }
|
|
|
-
|
|
|
- if (superView.Margin is { } && superView == top.SuperView)
|
|
|
- {
|
|
|
- maxWidth -= superView.GetAdornmentsThickness ().Left + superView.GetAdornmentsThickness ().Right;
|
|
|
- }
|
|
|
-
|
|
|
- if (top.Frame.Width <= maxWidth)
|
|
|
- {
|
|
|
- nx = Math.Max (targetX, 0);
|
|
|
- nx = nx + top.Frame.Width > maxWidth ? Math.Max (maxWidth - top.Frame.Width, 0) : nx;
|
|
|
-
|
|
|
- if (nx > top.Frame.X + top.Frame.Width)
|
|
|
- {
|
|
|
- nx = Math.Max (top.Frame.Right, 0);
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- nx = targetX;
|
|
|
- }
|
|
|
-
|
|
|
- //System.Diagnostics.Debug.WriteLine ($"nx:{nx}, rWidth:{rWidth}");
|
|
|
- bool menuVisible, statusVisible;
|
|
|
-
|
|
|
- if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
|
|
|
- {
|
|
|
- menuVisible = Application.Top.MenuBar?.Visible == true;
|
|
|
- menuBar = Application.Top.MenuBar;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- View t = top.SuperView;
|
|
|
-
|
|
|
- while (t is not Toplevel)
|
|
|
- {
|
|
|
- t = t.SuperView;
|
|
|
- }
|
|
|
-
|
|
|
- menuVisible = ((Toplevel)t).MenuBar?.Visible == true;
|
|
|
- menuBar = ((Toplevel)t).MenuBar;
|
|
|
- }
|
|
|
-
|
|
|
- if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
|
|
|
- {
|
|
|
- maxWidth = menuVisible ? 1 : 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- maxWidth = 0;
|
|
|
- }
|
|
|
-
|
|
|
- ny = Math.Max (targetY, maxWidth);
|
|
|
-
|
|
|
- if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
|
|
|
- {
|
|
|
- statusVisible = Application.Top.StatusBar?.Visible == true;
|
|
|
- statusBar = Application.Top.StatusBar;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- View t = top.SuperView;
|
|
|
-
|
|
|
- while (t is not Toplevel)
|
|
|
- {
|
|
|
- t = t.SuperView;
|
|
|
- }
|
|
|
-
|
|
|
- statusVisible = ((Toplevel)t).StatusBar?.Visible == true;
|
|
|
- statusBar = ((Toplevel)t).StatusBar;
|
|
|
- }
|
|
|
-
|
|
|
- if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
|
|
|
- {
|
|
|
- maxWidth = statusVisible ? Driver.Rows - 1 : Driver.Rows;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- maxWidth = statusVisible ? top.SuperView.Frame.Height - 1 : top.SuperView.Frame.Height;
|
|
|
- }
|
|
|
-
|
|
|
- if (superView.Margin is { } && superView == top.SuperView)
|
|
|
- {
|
|
|
- maxWidth -= superView.GetAdornmentsThickness ().Top + superView.GetAdornmentsThickness ().Bottom;
|
|
|
- }
|
|
|
-
|
|
|
- ny = Math.Min (ny, maxWidth);
|
|
|
-
|
|
|
- if (top.Frame.Height <= maxWidth)
|
|
|
- {
|
|
|
- ny = ny + top.Frame.Height > maxWidth
|
|
|
- ? Math.Max (maxWidth - top.Frame.Height, menuVisible ? 1 : 0)
|
|
|
- : ny;
|
|
|
-
|
|
|
- if (ny > top.Frame.Y + top.Frame.Height)
|
|
|
- {
|
|
|
- ny = Math.Max (top.Frame.Bottom, 0);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //System.Diagnostics.Debug.WriteLine ($"ny:{ny}, rHeight:{rHeight}");
|
|
|
-
|
|
|
- return superView;
|
|
|
- }
|
|
|
-
|
|
|
internal virtual void OnActivate (Toplevel deactivated) { Activate?.Invoke (this, new ToplevelEventArgs (deactivated)); }
|
|
|
internal virtual void OnAllChildClosed () { AllChildClosed?.Invoke (this, EventArgs.Empty); }
|
|
|
|
|
@@ -901,22 +638,6 @@ public partial class Toplevel : View
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void Application_GrabbingMouse (object sender, GrabMouseEventArgs e)
|
|
|
- {
|
|
|
- if (Application.MouseGrabView == this && _dragPosition.HasValue)
|
|
|
- {
|
|
|
- e.Cancel = true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void Application_UnGrabbingMouse (object sender, GrabMouseEventArgs e)
|
|
|
- {
|
|
|
- if (Application.MouseGrabView == this && _dragPosition.HasValue)
|
|
|
- {
|
|
|
- e.Cancel = true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
private void FocusNearestView (IEnumerable<View> views, NavigationDirection direction)
|
|
|
{
|
|
|
if (views is null)
|