mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-30 01:38:01 +01:00
#nullable enable
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.Numerics;
|
||||
#nullable enable
|
||||
using System.Numerics;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Terminal.Gui;
|
||||
@@ -15,10 +16,7 @@ namespace Terminal.Gui;
|
||||
/// with the thickness widths subtracted.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Use the helper API (<see cref="Draw(Rectangle, string)"/> to draw the frame with the specified thickness.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Thickness uses <see langword="float"/> intenrally. As a result, there is a potential precision loss for very
|
||||
/// Thickness uses <see langword="float"/> internally. As a result, there is a potential precision loss for very
|
||||
/// large numbers. This is typically not an issue for UI dimensions but could be relevant in other contexts.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
@@ -91,7 +89,7 @@ public record struct Thickness
|
||||
/// <param name="diagnosticFlags"></param>
|
||||
/// <param name="label">The diagnostics label to draw on the bottom of the <see cref="Bottom"/>.</param>
|
||||
/// <returns>The inner rectangle remaining to be drawn.</returns>
|
||||
public Rectangle Draw (Rectangle rect, ViewDiagnosticFlags diagnosticFlags = ViewDiagnosticFlags.Off, string label = null)
|
||||
public Rectangle Draw (Rectangle rect, ViewDiagnosticFlags diagnosticFlags = ViewDiagnosticFlags.Off, string? label = null)
|
||||
{
|
||||
if (rect.Size.Width < 1 || rect.Size.Height < 1)
|
||||
{
|
||||
@@ -134,26 +132,26 @@ public record struct Thickness
|
||||
if (Right > 0)
|
||||
{
|
||||
Application.Driver?.FillRect (
|
||||
rect with
|
||||
{
|
||||
X = Math.Max (0, rect.X + rect.Width - Right),
|
||||
Width = Math.Min (rect.Width, Right)
|
||||
},
|
||||
rightChar
|
||||
);
|
||||
rect with
|
||||
{
|
||||
X = Math.Max (0, rect.X + rect.Width - Right),
|
||||
Width = Math.Min (rect.Width, Right)
|
||||
},
|
||||
rightChar
|
||||
);
|
||||
}
|
||||
|
||||
// Draw the Bottom side
|
||||
if (Bottom > 0)
|
||||
{
|
||||
Application.Driver?.FillRect (
|
||||
rect with
|
||||
{
|
||||
Y = rect.Y + Math.Max (0, rect.Height - Bottom),
|
||||
Height = Bottom
|
||||
},
|
||||
bottomChar
|
||||
);
|
||||
rect with
|
||||
{
|
||||
Y = rect.Y + Math.Max (0, rect.Height - Bottom),
|
||||
Height = Bottom
|
||||
},
|
||||
bottomChar
|
||||
);
|
||||
}
|
||||
|
||||
if (diagnosticFlags.HasFlag (ViewDiagnosticFlags.Ruler))
|
||||
@@ -192,6 +190,7 @@ public record struct Thickness
|
||||
{
|
||||
// Draw the diagnostics label on the bottom
|
||||
string text = label is null ? string.Empty : $"{label} {this}";
|
||||
|
||||
var tf = new TextFormatter
|
||||
{
|
||||
Text = text,
|
||||
|
||||
@@ -483,8 +483,8 @@ public class Border : Adornment
|
||||
Point parentLoc = Parent.SuperView?.ScreenToViewport (new (mouseEvent.ScreenPosition.X, mouseEvent.ScreenPosition.Y))
|
||||
?? mouseEvent.ScreenPosition;
|
||||
|
||||
int minHeight = Thickness.Vertical + Parent!.Margin.Thickness.Bottom;
|
||||
int minWidth = Thickness.Horizontal + Parent!.Margin.Thickness.Right;
|
||||
int minHeight = Thickness.Vertical + Parent!.Margin!.Thickness.Bottom;
|
||||
int minWidth = Thickness.Horizontal + Parent!.Margin!.Thickness.Right;
|
||||
|
||||
// TODO: This code can be refactored to be more readable and maintainable.
|
||||
switch (_arranging)
|
||||
@@ -1072,7 +1072,7 @@ public class Border : Adornment
|
||||
NoPadding = true,
|
||||
ShadowStyle = ShadowStyle.None,
|
||||
Text = $"{Glyphs.SizeVertical}",
|
||||
X = Pos.Center () + Parent!.Margin.Thickness.Horizontal,
|
||||
X = Pos.Center () + Parent!.Margin!.Thickness.Horizontal,
|
||||
Y = 0,
|
||||
Visible = false,
|
||||
Data = ViewArrangement.TopResizable
|
||||
@@ -1095,7 +1095,7 @@ public class Border : Adornment
|
||||
ShadowStyle = ShadowStyle.None,
|
||||
Text = $"{Glyphs.SizeHorizontal}",
|
||||
X = Pos.AnchorEnd (),
|
||||
Y = Pos.Center () + Parent!.Margin.Thickness.Vertical / 2,
|
||||
Y = Pos.Center () + Parent!.Margin!.Thickness.Vertical / 2,
|
||||
Visible = false,
|
||||
Data = ViewArrangement.RightResizable
|
||||
};
|
||||
@@ -1117,7 +1117,7 @@ public class Border : Adornment
|
||||
ShadowStyle = ShadowStyle.None,
|
||||
Text = $"{Glyphs.SizeHorizontal}",
|
||||
X = 0,
|
||||
Y = Pos.Center () + Parent!.Margin.Thickness.Vertical / 2,
|
||||
Y = Pos.Center () + Parent!.Margin!.Thickness.Vertical / 2,
|
||||
Visible = false,
|
||||
Data = ViewArrangement.LeftResizable
|
||||
};
|
||||
@@ -1138,7 +1138,7 @@ public class Border : Adornment
|
||||
NoPadding = true,
|
||||
ShadowStyle = ShadowStyle.None,
|
||||
Text = $"{Glyphs.SizeVertical}",
|
||||
X = Pos.Center () + Parent!.Margin.Thickness.Horizontal / 2,
|
||||
X = Pos.Center () + Parent!.Margin!.Thickness.Horizontal / 2,
|
||||
Y = Pos.AnchorEnd (),
|
||||
Visible = false,
|
||||
Data = ViewArrangement.BottomResizable
|
||||
|
||||
@@ -275,13 +275,13 @@ public class Margin : Adornment
|
||||
{
|
||||
case ShadowStyle.Transparent:
|
||||
// BUGBUG: This doesn't work right for all Border.Top sizes - Need an API on Border that gives top-right location of line corner.
|
||||
_rightShadow.Y = Parent!.Border.Thickness.Top > 0 ? ScreenToViewport (Parent.Border.GetBorderRectangle ().Location).Y + 1 : 0;
|
||||
_rightShadow.Y = Parent!.Border!.Thickness.Top > 0 ? ScreenToViewport (Parent.Border.GetBorderRectangle ().Location).Y + 1 : 0;
|
||||
|
||||
break;
|
||||
|
||||
case ShadowStyle.Opaque:
|
||||
// BUGBUG: This doesn't work right for all Border.Top sizes - Need an API on Border that gives top-right location of line corner.
|
||||
_rightShadow.Y = Parent!.Border.Thickness.Top > 0 ? ScreenToViewport (Parent.Border.GetBorderRectangle ().Location).Y + 1 : 0;
|
||||
_rightShadow.Y = Parent!.Border!.Thickness.Top > 0 ? ScreenToViewport (Parent.Border.GetBorderRectangle ().Location).Y + 1 : 0;
|
||||
_bottomShadow.X = Parent.Border.Thickness.Left > 0 ? ScreenToViewport (Parent.Border.GetBorderRectangle ().Location).X + 1 : 0;
|
||||
|
||||
break;
|
||||
|
||||
@@ -20,9 +20,6 @@ public class DrawEventArgs : CancelEventArgs
|
||||
OldViewport = oldViewport;
|
||||
}
|
||||
|
||||
/// <summary>If set to true, the draw operation will be canceled, if applicable.</summary>
|
||||
public bool Cancel { get; set; }
|
||||
|
||||
/// <summary>Gets the Content-relative rectangle describing the old visible viewport into the <see cref="View"/>.</summary>
|
||||
public Rectangle OldViewport { get; }
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
namespace Terminal.Gui;
|
||||
#nullable enable
|
||||
namespace Terminal.Gui;
|
||||
|
||||
public partial class View // Adornments
|
||||
{
|
||||
@@ -7,9 +8,10 @@ public partial class View // Adornments
|
||||
/// </summary>
|
||||
private void SetupAdornments ()
|
||||
{
|
||||
//// TODO: Move this to Adornment as a static factory method
|
||||
// TODO: Move this to Adornment as a static factory method
|
||||
if (this is not Adornment)
|
||||
{
|
||||
// TODO: Make the Adornments Lazy and only create them when needed
|
||||
Margin = new (this);
|
||||
Border = new (this);
|
||||
Padding = new (this);
|
||||
@@ -61,7 +63,7 @@ public partial class View // Adornments
|
||||
/// <see cref="SuperView"/> and its <see cref="Subviews"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public Margin Margin { get; private set; }
|
||||
public Margin? Margin { get; private set; }
|
||||
|
||||
private ShadowStyle _shadowStyle;
|
||||
|
||||
@@ -117,7 +119,7 @@ public partial class View // Adornments
|
||||
/// <see cref="SuperView"/> and its <see cref="Subviews"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public Border Border { get; private set; }
|
||||
public Border? Border { get; private set; }
|
||||
|
||||
/// <summary>Gets or sets whether the view has a one row/col thick border.</summary>
|
||||
/// <remarks>
|
||||
@@ -130,6 +132,10 @@ public partial class View // Adornments
|
||||
/// Setting this property to <see cref="LineStyle.None"/> is equivalent to setting <see cref="Border"/>'s
|
||||
/// <see cref="Adornment.Thickness"/> to `0` and <see cref="BorderStyle"/> to <see cref="LineStyle.None"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Calls <see cref="OnBorderStyleChanging"/> and raises <see cref="BorderStyleChanging"/>, which allows change
|
||||
/// to be cancelled.
|
||||
/// </para>
|
||||
/// <para>For more advanced customization of the view's border, manipulate see <see cref="Border"/> directly.</para>
|
||||
/// </remarks>
|
||||
public LineStyle BorderStyle
|
||||
@@ -150,32 +156,32 @@ public partial class View // Adornments
|
||||
return;
|
||||
}
|
||||
|
||||
BorderStyleChanging?.Invoke (this, e);
|
||||
|
||||
if (e.Cancel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetBorderStyle (e.NewValue);
|
||||
SetAdornmentFrames ();
|
||||
SetNeedsLayout ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the <see cref="BorderStyle"/> is changing. Invokes <see cref="BorderStyleChanging"/>, which allows the
|
||||
/// event to be cancelled.
|
||||
/// Called when the <see cref="BorderStyle"/> is changing.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Override <see cref="SetBorderStyle"/> to prevent the <see cref="BorderStyle"/> from changing.
|
||||
/// Set e.Cancel to true to prevent the <see cref="BorderStyle"/> from changing.
|
||||
/// </remarks>
|
||||
/// <param name="e"></param>
|
||||
protected virtual bool OnBorderStyleChanging (CancelEventArgs<LineStyle> e)
|
||||
{
|
||||
if (Border is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
protected virtual bool OnBorderStyleChanging (CancelEventArgs<LineStyle> e) { return false; }
|
||||
|
||||
BorderStyleChanging?.Invoke (this, e);
|
||||
|
||||
return e.Cancel;
|
||||
}
|
||||
/// <summary>
|
||||
/// Fired when the <see cref="BorderStyle"/> is changing. Allows the event to be cancelled.
|
||||
/// </summary>
|
||||
public event EventHandler<CancelEventArgs<LineStyle>>? BorderStyleChanging;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="BorderStyle"/> of the view to the specified value.
|
||||
@@ -198,25 +204,19 @@ public partial class View // Adornments
|
||||
{
|
||||
if (value != LineStyle.None)
|
||||
{
|
||||
if (Border.Thickness == Thickness.Empty)
|
||||
if (Border!.Thickness == Thickness.Empty)
|
||||
{
|
||||
Border.Thickness = new (1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Border.Thickness = new (0);
|
||||
Border!.Thickness = new (0);
|
||||
}
|
||||
|
||||
Border.LineStyle = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fired when the <see cref="BorderStyle"/> is changing. Allows the event to be cancelled.
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
public event EventHandler<CancelEventArgs<LineStyle>> BorderStyleChanging;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Adornment"/> inside of the view that offsets the <see cref="Viewport"/>
|
||||
/// from the <see cref="Border"/>.
|
||||
@@ -232,7 +232,7 @@ public partial class View // Adornments
|
||||
/// <see cref="SuperView"/> and its <see cref="Subviews"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public Padding Padding { get; private set; }
|
||||
public Padding? Padding { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para>Gets the thickness describing the sum of the Adornments' thicknesses.</para>
|
||||
@@ -245,12 +245,24 @@ public partial class View // Adornments
|
||||
/// <returns>A thickness that describes the sum of the Adornments' thicknesses.</returns>
|
||||
public Thickness GetAdornmentsThickness ()
|
||||
{
|
||||
if (Margin is null)
|
||||
Thickness result = Thickness.Empty;
|
||||
|
||||
if (Margin is { })
|
||||
{
|
||||
return Thickness.Empty;
|
||||
result += Margin.Thickness;
|
||||
}
|
||||
|
||||
return Margin.Thickness + Border.Thickness + Padding.Thickness;
|
||||
if (Border is { })
|
||||
{
|
||||
result += Border.Thickness;
|
||||
}
|
||||
|
||||
if (Padding is { })
|
||||
{
|
||||
result += Padding.Thickness;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Sets the Frame's of the Margin, Border, and Padding.</summary>
|
||||
@@ -262,13 +274,19 @@ public partial class View // Adornments
|
||||
return;
|
||||
}
|
||||
|
||||
if (Margin is null)
|
||||
if (Margin is { })
|
||||
{
|
||||
return; // CreateAdornments () has not been called yet
|
||||
Margin!.Frame = Rectangle.Empty with { Size = Frame.Size };
|
||||
}
|
||||
|
||||
Margin.Frame = Rectangle.Empty with { Size = Frame.Size };
|
||||
Border.Frame = Margin.Thickness.GetInside (Margin.Frame);
|
||||
Padding.Frame = Border.Thickness.GetInside (Border.Frame);
|
||||
if (Border is { } && Margin is { })
|
||||
{
|
||||
Border!.Frame = Margin!.Thickness.GetInside (Margin!.Frame);
|
||||
}
|
||||
|
||||
if (Padding is { } && Border is { })
|
||||
{
|
||||
Padding!.Frame = Border!.Thickness.GetInside (Border!.Frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
namespace Terminal.Gui;
|
||||
#nullable enable
|
||||
namespace Terminal.Gui;
|
||||
|
||||
public partial class View
|
||||
{
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#nullable enable
|
||||
using static Unix.Terminal.Curses;
|
||||
|
||||
namespace Terminal.Gui;
|
||||
|
||||
public partial class View
|
||||
@@ -13,21 +11,20 @@ public partial class View
|
||||
/// There is a single clip region for the entire application.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This method returns the current clip region, not a clone. If there is a need to modify the clip region, it is recommended to clone it first.
|
||||
/// This method returns the current clip region, not a clone. If there is a need to modify the clip region, it is
|
||||
/// recommended to clone it first.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <returns>The current Clip.</returns>
|
||||
public static Region? GetClip ()
|
||||
{
|
||||
return Application.Driver?.Clip;
|
||||
}
|
||||
public static Region? GetClip () { return Application.Driver?.Clip; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the Clip to the specified region.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// There is a single clip region for the entire application. This method sets the clip region to the specified region.
|
||||
/// There is a single clip region for the entire application. This method sets the clip region to the specified
|
||||
/// region.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="region"></param>
|
||||
@@ -47,7 +44,8 @@ public partial class View
|
||||
/// There is a single clip region for the entire application. This method sets the clip region to the screen.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This method returns the current clip region, not a clone. If there is a need to modify the clip region, it is recommended to clone it first.
|
||||
/// This method returns the current clip region, not a clone. If there is a need to modify the clip region, it is
|
||||
/// recommended to clone it first.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
@@ -56,6 +54,7 @@ public partial class View
|
||||
public static Region? SetClipToScreen ()
|
||||
{
|
||||
Region? previous = GetClip ();
|
||||
|
||||
if (Driver is { })
|
||||
{
|
||||
Driver.Clip = new (Application.Screen);
|
||||
@@ -65,7 +64,7 @@ public partial class View
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the specified rectangle from the Clip.
|
||||
/// Removes the specified rectangle from the Clip.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
@@ -73,17 +72,15 @@ public partial class View
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="rectangle"></param>
|
||||
public static void ExcludeFromClip (Rectangle rectangle)
|
||||
{
|
||||
Driver?.Clip?.Exclude (rectangle);
|
||||
}
|
||||
public static void ExcludeFromClip (Rectangle rectangle) { Driver?.Clip?.Exclude (rectangle); }
|
||||
|
||||
/// <summary>
|
||||
/// Changes the Clip to the intersection of the current Clip and the <see cref="Frame"/> of this View.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This method returns the current clip region, not a clone. If there is a need to modify the clip region, it is recommended to clone it first.
|
||||
/// This method returns the current clip region, not a clone. If there is a need to modify the clip region, it is
|
||||
/// recommended to clone it first.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
@@ -99,6 +96,7 @@ public partial class View
|
||||
Region previous = GetClip () ?? new (Application.Screen);
|
||||
|
||||
Region frameRegion = previous.Clone ();
|
||||
|
||||
// Translate viewportRegion to screen-relative coords
|
||||
Rectangle screenRect = FrameToScreen ();
|
||||
frameRegion.Intersect (screenRect);
|
||||
@@ -109,7 +107,7 @@ public partial class View
|
||||
frameRegion.Exclude (adornment.Thickness.GetInside (Frame));
|
||||
}
|
||||
|
||||
View.SetClip (frameRegion);
|
||||
SetClip (frameRegion);
|
||||
|
||||
return previous;
|
||||
}
|
||||
@@ -125,11 +123,12 @@ public partial class View
|
||||
/// If <see cref="ViewportSettings"/> has <see cref="Gui.ViewportSettings.ClipContentOnly"/> set, clipping will be
|
||||
/// applied to just the visible content area.
|
||||
/// </para>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This method returns the current clip region, not a clone. If there is a need to modify the clip region, it is recommended to clone it first.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This method returns the current clip region, not a clone. If there is a need to modify the clip region, it
|
||||
/// is recommended to clone it first.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The current Clip, which can be then re-applied <see cref="View.SetClip"/>
|
||||
@@ -161,7 +160,7 @@ public partial class View
|
||||
viewportRegion?.Exclude (adornment.Thickness.GetInside (viewport));
|
||||
}
|
||||
|
||||
View.SetClip (viewportRegion);
|
||||
SetClip (viewportRegion);
|
||||
|
||||
return previous;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
public partial class View
|
||||
{
|
||||
#region Drawing Primitives
|
||||
|
||||
/// <summary>Moves the drawing cursor to the specified <see cref="Viewport"/>-relative location in the view.</summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
@@ -121,8 +119,6 @@ public partial class View
|
||||
Attribute prev = SetAttribute (new (color ?? GetNormalColor ().Background));
|
||||
Driver.FillRect (toClear);
|
||||
SetAttribute (prev);
|
||||
View.SetClip (prevClip);
|
||||
SetClip (prevClip);
|
||||
}
|
||||
|
||||
#endregion Drawing Primitives
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
#nullable enable
|
||||
//#define HACK_DRAW_OVERLAPPED
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Terminal.Gui;
|
||||
|
||||
public partial class View // Drawing APIs
|
||||
{
|
||||
|
||||
internal static void Draw (IEnumerable<View> views, bool force)
|
||||
{
|
||||
IEnumerable<View> viewsArray = views as View [] ?? views.ToArray ();
|
||||
@@ -25,7 +22,6 @@ public partial class View // Drawing APIs
|
||||
Margin.DrawMargins (viewsArray);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Draws the view if it needs to be drawn.
|
||||
/// </summary>
|
||||
@@ -47,11 +43,12 @@ public partial class View // Drawing APIs
|
||||
}
|
||||
|
||||
Region? saved = GetClip ();
|
||||
|
||||
if (NeedsDraw || SubViewNeedsDraw)
|
||||
{
|
||||
saved = ClipFrame ();
|
||||
DoDrawBorderAndPadding ();
|
||||
View.SetClip (saved);
|
||||
SetClip (saved);
|
||||
|
||||
// By default, we clip to the viewport preventing drawing outside the viewport
|
||||
// We also clip to the content, but if a developer wants to draw outside the viewport, they can do
|
||||
@@ -108,7 +105,7 @@ public partial class View // Drawing APIs
|
||||
DoDrawComplete ();
|
||||
|
||||
// QUESTION: Should this go before DoDrawComplete? What is more correct?
|
||||
View.SetClip (saved);
|
||||
SetClip (saved);
|
||||
|
||||
// Exclude this view (not including Margin) from the Clip
|
||||
if (this is not Adornment && GetClip () is { })
|
||||
@@ -221,7 +218,6 @@ public partial class View // Drawing APIs
|
||||
SetNormalAttribute ();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Called when the normal attribute for the View is to be set. This is called before the View is drawn.
|
||||
/// </summary>
|
||||
@@ -245,13 +241,12 @@ public partial class View // Drawing APIs
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region ClearViewport
|
||||
|
||||
private void DoClearViewport ()
|
||||
{
|
||||
|
||||
if (OnClearingViewport ())
|
||||
{
|
||||
return;
|
||||
@@ -329,7 +324,6 @@ public partial class View // Drawing APIs
|
||||
|
||||
private void DoDrawText ()
|
||||
{
|
||||
|
||||
if (OnDrawingText ())
|
||||
{
|
||||
return;
|
||||
@@ -513,14 +507,15 @@ public partial class View // Drawing APIs
|
||||
/// <summary>
|
||||
/// Gets or sets whether this View will use it's SuperView's <see cref="LineCanvas"/> for rendering any
|
||||
/// lines. If <see langword="true"/> the rendering of any borders drawn by this Frame will be done by its parent's
|
||||
/// SuperView. If <see langword="false"/> (the default) this View's <see cref="OnDrawingBorderAndPadding"/> method will be
|
||||
/// SuperView. If <see langword="false"/> (the default) this View's <see cref="OnDrawingBorderAndPadding"/> method will
|
||||
/// be
|
||||
/// called to render the borders.
|
||||
/// </summary>
|
||||
public virtual bool SuperViewRendersLineCanvas { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Causes the contents of <see cref="LineCanvas"/> to be drawn.
|
||||
/// If <see cref="SuperViewRendersLineCanvas"/> is true, only the
|
||||
/// Causes the contents of <see cref="LineCanvas"/> to be drawn.
|
||||
/// If <see cref="SuperViewRendersLineCanvas"/> is true, only the
|
||||
/// <see cref="LineCanvas"/> of this view's subviews will be rendered. If <see cref="SuperViewRendersLineCanvas"/> is
|
||||
/// false (the default), this method will cause the <see cref="LineCanvas"/> to be rendered.
|
||||
/// </summary>
|
||||
@@ -577,6 +572,7 @@ public partial class View // Drawing APIs
|
||||
LineCanvas.Clear ();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion DrawLineCanvas
|
||||
|
||||
#region DrawComplete
|
||||
@@ -757,6 +753,7 @@ public partial class View // Drawing APIs
|
||||
{
|
||||
Padding?.ClearNeedsDraw ();
|
||||
}
|
||||
|
||||
foreach (View subview in Subviews)
|
||||
{
|
||||
subview.ClearNeedsDraw ();
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#nullable enable
|
||||
using System.Diagnostics;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using static Unix.Terminal.Curses;
|
||||
|
||||
namespace Terminal.Gui;
|
||||
|
||||
@@ -33,10 +31,12 @@ public partial class View // Layout APIs
|
||||
/// .
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Setting Frame will set <see cref="X"/>, <see cref="Y"/>, <see cref="Width"/>, and <see cref="Height"/> to absoulte values.
|
||||
/// Setting Frame will set <see cref="X"/>, <see cref="Y"/>, <see cref="Width"/>, and <see cref="Height"/> to
|
||||
/// absoulte values.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set, resulting in the
|
||||
/// Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set,
|
||||
/// resulting in the
|
||||
/// view being laid out and redrawn as appropriate in the next iteration of the <see cref="MainLoop"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
@@ -44,10 +44,11 @@ public partial class View // Layout APIs
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_needsLayout)
|
||||
if (NeedsLayout)
|
||||
{
|
||||
//Debug.WriteLine("Frame_get with _layoutNeeded");
|
||||
}
|
||||
|
||||
return _frame ?? Rectangle.Empty;
|
||||
}
|
||||
set
|
||||
@@ -193,7 +194,8 @@ public partial class View // Layout APIs
|
||||
/// laid out (e.g. <see cref="Layout(System.Drawing.Size)"/> has been called).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set, resulting in the
|
||||
/// Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set,
|
||||
/// resulting in the
|
||||
/// view being laid out and redrawn as appropriate in the next iteration of the <see cref="MainLoop"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
@@ -219,7 +221,6 @@ public partial class View // Layout APIs
|
||||
|
||||
private Pos _y = Pos.Absolute (0);
|
||||
|
||||
|
||||
/// <summary>Gets or sets the Y position for the view (the row).</summary>
|
||||
/// <value>The <see cref="Pos"/> object representing the Y position.</value>
|
||||
/// <remarks>
|
||||
@@ -236,7 +237,8 @@ public partial class View // Layout APIs
|
||||
/// laid out (e.g. <see cref="Layout(System.Drawing.Size)"/> has been called).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set, resulting in the
|
||||
/// Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set,
|
||||
/// resulting in the
|
||||
/// view being laid out and redrawn as appropriate in the next iteration of the <see cref="MainLoop"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
@@ -277,7 +279,8 @@ public partial class View // Layout APIs
|
||||
/// laid out (e.g. <see cref="Layout(System.Drawing.Size)"/> has been called).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set, resulting in the
|
||||
/// Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set,
|
||||
/// resulting in the
|
||||
/// view being laid out and redrawn as appropriate in the next iteration of the <see cref="MainLoop"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
@@ -323,7 +326,8 @@ public partial class View // Layout APIs
|
||||
/// laid out (e.g. <see cref="Layout(System.Drawing.Size)"/> has been called).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set, resulting in the
|
||||
/// Changing this property will result in <see cref="NeedsLayout"/> and <see cref="NeedsDraw"/> to be set,
|
||||
/// resulting in the
|
||||
/// view being laid out and redrawn as appropriate in the next iteration of the <see cref="MainLoop"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
@@ -354,14 +358,15 @@ public partial class View // Layout APIs
|
||||
#region Core Layout API
|
||||
|
||||
/// <summary>
|
||||
/// INTERNAL API - Performs layout of the specified views within the specified content size. Called by the Application main loop.
|
||||
/// INTERNAL API - Performs layout of the specified views within the specified content size. Called by the Application
|
||||
/// main loop.
|
||||
/// </summary>
|
||||
/// <param name="views">The views to layout.</param>
|
||||
/// <param name="contentSize">The size to bound the views by.</param>
|
||||
/// <returns><see langword="true"/>If any of the views needed to be laid out.</returns>
|
||||
internal static bool Layout (IEnumerable<View> views, Size contentSize)
|
||||
{
|
||||
bool neededLayout = false;
|
||||
var neededLayout = false;
|
||||
|
||||
foreach (View v in views)
|
||||
{
|
||||
@@ -404,7 +409,8 @@ public partial class View // Layout APIs
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs layout of the view and its subviews using the content size of either the <see cref="SuperView"/> or <see cref="Application.Screen"/>.
|
||||
/// Performs layout of the view and its subviews using the content size of either the <see cref="SuperView"/> or
|
||||
/// <see cref="Application.Screen"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
@@ -417,14 +423,12 @@ public partial class View // Layout APIs
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <returns><see langword="false"/>If the view could not be laid out (typically because dependency was not ready). </returns>
|
||||
public bool Layout ()
|
||||
{
|
||||
return Layout (GetContainerSize ());
|
||||
}
|
||||
public bool Layout () { return Layout (GetContainerSize ()); }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the position and size of this view, relative to the SuperView's ContentSize (nominally the same as
|
||||
/// <c>this.SuperView.GetContentSize ()</c>) based on the values of <see cref="X"/>, <see cref="Y"/>, <see cref="Width"/>,
|
||||
/// <c>this.SuperView.GetContentSize ()</c>) based on the values of <see cref="X"/>, <see cref="Y"/>,
|
||||
/// <see cref="Width"/>,
|
||||
/// and <see cref="Height"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
@@ -467,6 +471,7 @@ public partial class View // Layout APIs
|
||||
{
|
||||
newW = _width.Calculate (0, superviewContentSize.Width, this, Dimension.Width);
|
||||
newX = _x.Calculate (superviewContentSize.Width, newW, this, Dimension.Width);
|
||||
|
||||
if (newW != Frame.Width)
|
||||
{
|
||||
// Pos.Calculate gave us a new position. We need to redo dimension
|
||||
@@ -483,6 +488,7 @@ public partial class View // Layout APIs
|
||||
{
|
||||
newH = _height.Calculate (0, superviewContentSize.Height, this, Dimension.Height);
|
||||
newY = _y.Calculate (superviewContentSize.Height, newH, this, Dimension.Height);
|
||||
|
||||
if (newH != Frame.Height)
|
||||
{
|
||||
// Pos.Calculate gave us a new position. We need to redo dimension
|
||||
@@ -494,7 +500,6 @@ public partial class View // Layout APIs
|
||||
newY = _y.Calculate (superviewContentSize.Height, _height, this, Dimension.Height);
|
||||
newH = _height.Calculate (newY, superviewContentSize.Height, this, Dimension.Height);
|
||||
}
|
||||
|
||||
}
|
||||
catch (LayoutException le)
|
||||
{
|
||||
@@ -552,7 +557,8 @@ public partial class View // Layout APIs
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// INTERNAL API - Causes the view's subviews and adornments to be laid out within the view's content areas. Assumes the view's relative layout has been set via <see cref="SetRelativeLayout"/>.
|
||||
/// INTERNAL API - Causes the view's subviews and adornments to be laid out within the view's content areas. Assumes
|
||||
/// the view's relative layout has been set via <see cref="SetRelativeLayout"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
@@ -584,10 +590,12 @@ public partial class View // Layout APIs
|
||||
{
|
||||
Margin.LayoutSubviews ();
|
||||
}
|
||||
|
||||
if (Border is { Subviews.Count: > 0 })
|
||||
{
|
||||
Border.LayoutSubviews ();
|
||||
}
|
||||
|
||||
if (Padding is { Subviews.Count: > 0 })
|
||||
{
|
||||
Padding.LayoutSubviews ();
|
||||
@@ -600,6 +608,7 @@ public partial class View // Layout APIs
|
||||
List<View> ordered = TopologicalSort (SuperView!, nodes, edges);
|
||||
|
||||
List<View> redo = new ();
|
||||
|
||||
foreach (View v in ordered)
|
||||
{
|
||||
if (!v.Layout (contentSize))
|
||||
@@ -608,7 +617,7 @@ public partial class View // Layout APIs
|
||||
}
|
||||
}
|
||||
|
||||
bool layoutStillNeeded = false;
|
||||
var layoutStillNeeded = false;
|
||||
|
||||
if (redo.Count > 0)
|
||||
{
|
||||
@@ -633,7 +642,7 @@ public partial class View // Layout APIs
|
||||
}
|
||||
}
|
||||
|
||||
_needsLayout = layoutStillNeeded;
|
||||
NeedsLayout = layoutStillNeeded;
|
||||
|
||||
OnSubviewsLaidOut (new (contentSize));
|
||||
SubviewsLaidOut?.Invoke (this, new (contentSize));
|
||||
@@ -648,8 +657,10 @@ public partial class View // Layout APIs
|
||||
/// </remarks>
|
||||
protected virtual void OnSubviewLayout (LayoutEventArgs args) { }
|
||||
|
||||
/// <summary>Raised by <see cref="LayoutSubviews"/> before any subviews
|
||||
/// have been laid out.</summary>
|
||||
/// <summary>
|
||||
/// Raised by <see cref="LayoutSubviews"/> before any subviews
|
||||
/// have been laid out.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Subscribe to this event to perform tasks when the layout is changing.
|
||||
/// </remarks>
|
||||
@@ -677,65 +688,72 @@ public partial class View // Layout APIs
|
||||
#region NeedsLayout
|
||||
|
||||
// We expose no setter for this to ensure that the ONLY place it's changed is in SetNeedsLayout
|
||||
private bool _needsLayout = true;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the View's Frame or the layout of the View's subviews (including Adornments) have
|
||||
/// changed since the last time the View was laid out.
|
||||
/// changed since the last time the View was laid out.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Used to prevent <see cref="Layout()"/> from needlessly computing
|
||||
/// layout.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Used to prevent <see cref="Layout()"/> from needlessly computing
|
||||
/// layout.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if layout is needed.
|
||||
/// </value>
|
||||
public bool NeedsLayout => _needsLayout;
|
||||
public bool NeedsLayout { get; private set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="NeedsLayout"/> to return <see langword="true"/>, indicating this View and all of it's subviews (including adornments) need to be laid out in the next Application iteration.
|
||||
/// Sets <see cref="NeedsLayout"/> to return <see langword="true"/>, indicating this View and all of it's subviews
|
||||
/// (including adornments) need to be laid out in the next Application iteration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The <see cref="MainLoop"/> will cause <see cref="Layout()"/> to be called on the next <see cref="Application.Iteration"/> so there is normally no reason to call see <see cref="Layout()"/>.
|
||||
/// The <see cref="MainLoop"/> will cause <see cref="Layout()"/> to be called on the next
|
||||
/// <see cref="Application.Iteration"/> so there is normally no reason to call see <see cref="Layout()"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
|
||||
public void SetNeedsLayout ()
|
||||
{
|
||||
_needsLayout = true;
|
||||
NeedsLayout = true;
|
||||
|
||||
if (Margin is { Subviews.Count: > 0 })
|
||||
{
|
||||
Margin.SetNeedsLayout ();
|
||||
}
|
||||
|
||||
if (Border is { Subviews.Count: > 0 })
|
||||
{
|
||||
Border.SetNeedsLayout ();
|
||||
}
|
||||
|
||||
if (Padding is { Subviews.Count: > 0 })
|
||||
{
|
||||
Padding.SetNeedsLayout ();
|
||||
}
|
||||
|
||||
// Use a stack to avoid recursion
|
||||
Stack<View> stack = new Stack<View> (Subviews);
|
||||
Stack<View> stack = new (Subviews);
|
||||
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
View current = stack.Pop ();
|
||||
|
||||
if (!current.NeedsLayout)
|
||||
{
|
||||
current._needsLayout = true;
|
||||
current.NeedsLayout = true;
|
||||
|
||||
if (current.Margin is { Subviews.Count: > 0 })
|
||||
{
|
||||
current.Margin.SetNeedsLayout ();
|
||||
}
|
||||
|
||||
if (current.Border is { Subviews.Count: > 0 })
|
||||
{
|
||||
current.Border.SetNeedsLayout ();
|
||||
}
|
||||
|
||||
if (current.Padding is { Subviews.Count: > 0 })
|
||||
{
|
||||
current.Padding.SetNeedsLayout ();
|
||||
@@ -757,7 +775,7 @@ public partial class View // Layout APIs
|
||||
|
||||
if (SuperView is null)
|
||||
{
|
||||
foreach (var tl in Application.TopLevels)
|
||||
foreach (Toplevel tl in Application.TopLevels)
|
||||
{
|
||||
tl.SetNeedsDraw ();
|
||||
}
|
||||
@@ -778,7 +796,6 @@ public partial class View // Layout APIs
|
||||
|
||||
#region Topological Sort
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// INTERNAL API - Collects all views and their dependencies from a given starting view for layout purposes. Used by
|
||||
/// <see cref="TopologicalSort"/> to create an ordered list of views to layout.
|
||||
@@ -802,7 +819,7 @@ public partial class View // Layout APIs
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// INTERNAL API - Collects dimension (where Width or Height is `DimView`) dependencies for a given view.
|
||||
/// INTERNAL API - Collects dimension (where Width or Height is `DimView`) dependencies for a given view.
|
||||
/// </summary>
|
||||
/// <param name="dim">The dimension (width or height) to collect dependencies for.</param>
|
||||
/// <param name="from">The view for which to collect dimension dependencies.</param>
|
||||
@@ -813,7 +830,7 @@ public partial class View // Layout APIs
|
||||
/// </param>
|
||||
internal void CollectDim (Dim? dim, View from, ref HashSet<View> nNodes, ref HashSet<(View, View)> nEdges)
|
||||
{
|
||||
if (dim!.Has<DimView> (out DimView dv))
|
||||
if (dim!.Has (out DimView dv))
|
||||
{
|
||||
if (dv.Target != this)
|
||||
{
|
||||
@@ -821,7 +838,7 @@ public partial class View // Layout APIs
|
||||
}
|
||||
}
|
||||
|
||||
if (dim!.Has<DimCombine> (out DimCombine dc))
|
||||
if (dim!.Has (out DimCombine dc))
|
||||
{
|
||||
CollectDim (dc.Left, from, ref nNodes, ref nEdges);
|
||||
CollectDim (dc.Right, from, ref nNodes, ref nEdges);
|
||||
@@ -845,6 +862,7 @@ public partial class View // Layout APIs
|
||||
{
|
||||
case PosView pv:
|
||||
Debug.Assert (pv.Target is { });
|
||||
|
||||
if (pv.Target != this)
|
||||
{
|
||||
nEdges.Add ((pv.Target!, from));
|
||||
@@ -960,22 +978,21 @@ public partial class View // Layout APIs
|
||||
#region Utilities
|
||||
|
||||
/// <summary>
|
||||
/// INTERNAL API - Gets the size of the SuperView's content (nominally the same as
|
||||
/// the SuperView's <see cref="GetContentSize ()"/>) or the screen size if there's no SuperView.
|
||||
/// INTERNAL API - Gets the size of the SuperView's content (nominally the same as
|
||||
/// the SuperView's <see cref="GetContentSize ()"/>) or the screen size if there's no SuperView.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private Size GetContainerSize ()
|
||||
{
|
||||
// TODO: Get rid of refs to Top
|
||||
Size superViewContentSize = SuperView?.GetContentSize () ??
|
||||
(Application.Top is { } && Application.Top != this && Application.Top.IsInitialized
|
||||
? Application.Top.GetContentSize ()
|
||||
: Application.Screen.Size);
|
||||
Size superViewContentSize = SuperView?.GetContentSize ()
|
||||
?? (Application.Top is { } && Application.Top != this && Application.Top.IsInitialized
|
||||
? Application.Top.GetContentSize ()
|
||||
: Application.Screen.Size);
|
||||
|
||||
return superViewContentSize;
|
||||
}
|
||||
|
||||
|
||||
// BUGBUG: This method interferes with Dialog/MessageBox default min/max size.
|
||||
// TODO: Get rid of MenuBar coupling as part of https://github.com/gui-cs/Terminal.Gui/issues/2975
|
||||
/// <summary>
|
||||
@@ -1107,11 +1124,8 @@ public partial class View // Layout APIs
|
||||
|
||||
#endregion Utilities
|
||||
|
||||
|
||||
#region Diagnostics and Verification
|
||||
|
||||
|
||||
|
||||
// Diagnostics to highlight when X or Y is read before the view has been initialized
|
||||
private Pos VerifyIsInitialized (Pos pos, string member)
|
||||
{
|
||||
@@ -1228,12 +1242,12 @@ public partial class View // Layout APIs
|
||||
if (bad != null)
|
||||
{
|
||||
throw new LayoutException (
|
||||
$"{view.GetType ().Name}.{name} = {bad.GetType ().Name} "
|
||||
+ $"which depends on the SuperView's dimensions and the SuperView uses Dim.Auto."
|
||||
);
|
||||
$"{view.GetType ().Name}.{name} = {bad.GetType ().Name} "
|
||||
+ $"which depends on the SuperView's dimensions and the SuperView uses Dim.Auto."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion Diagnostics and Verification
|
||||
|
||||
}
|
||||
#endregion Diagnostics and Verification
|
||||
}
|
||||
|
||||
@@ -666,15 +666,15 @@ public partial class View // Mouse APIs
|
||||
|
||||
if (start is not Adornment)
|
||||
{
|
||||
if (start.Margin.Contains (currentLocation))
|
||||
if (start.Margin is {} && start.Margin.Contains (currentLocation))
|
||||
{
|
||||
found = start.Margin;
|
||||
}
|
||||
else if (start.Border.Contains (currentLocation))
|
||||
else if (start.Border is {} && start.Border.Contains (currentLocation))
|
||||
{
|
||||
found = start.Border;
|
||||
}
|
||||
else if (start.Padding.Contains (currentLocation))
|
||||
else if (start.Padding is { } && start.Padding.Contains(currentLocation))
|
||||
{
|
||||
found = start.Padding;
|
||||
}
|
||||
|
||||
@@ -87,8 +87,11 @@ public class Bar : View, IOrientation, IDesignable
|
||||
/// <inheritdoc/>
|
||||
public override void SetBorderStyle (LineStyle value)
|
||||
{
|
||||
// The default changes the thickness. We don't want that. We just set the style.
|
||||
Border.LineStyle = value;
|
||||
if (Border is { })
|
||||
{
|
||||
// The default changes the thickness. We don't want that. We just set the style.
|
||||
Border.LineStyle = value;
|
||||
}
|
||||
}
|
||||
|
||||
#region IOrientation members
|
||||
|
||||
@@ -46,6 +46,7 @@ public class Menuv2 : Bar
|
||||
// Menuv2 arranges the items horizontally.
|
||||
// The first item has no left border, the last item has no right border.
|
||||
// The Shortcuts are configured with the command, help, and key views aligned in reverse order (EndToStart).
|
||||
/// <inheritdoc />
|
||||
protected override void OnSubviewLayout (LayoutEventArgs args)
|
||||
{
|
||||
for (int index = 0; index < Subviews.Count; index++)
|
||||
|
||||
@@ -98,7 +98,11 @@ public class Shortcut : View, IOrientation, IDesignable
|
||||
CanFocus = true;
|
||||
|
||||
SuperViewRendersLineCanvas = true;
|
||||
Border.Settings &= ~BorderSettings.Title;
|
||||
|
||||
if (Border is { })
|
||||
{
|
||||
Border.Settings &= ~BorderSettings.Title;
|
||||
}
|
||||
|
||||
Width = GetWidthDimAuto ();
|
||||
Height = Dim.Auto (DimAutoStyle.Content, 1);
|
||||
@@ -237,39 +241,39 @@ public class Shortcut : View, IOrientation, IDesignable
|
||||
ShowHide ();
|
||||
ForceCalculateNaturalWidth ();
|
||||
|
||||
if (Width is DimAuto widthAuto)
|
||||
if (Width is DimAuto widthAuto || HelpView!.Margin is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
// Frame.Width is smaller than the natural width. Reduce width of HelpView.
|
||||
_maxHelpWidth = int.Max (0, GetContentSize ().Width - CommandView.Frame.Width - KeyView.Frame.Width);
|
||||
|
||||
if (_maxHelpWidth < 3)
|
||||
{
|
||||
Thickness t = GetMarginThickness ();
|
||||
|
||||
switch (_maxHelpWidth)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
// Scrunch it by removing both margins
|
||||
HelpView.Margin.Thickness = new (t.Right - 1, t.Top, t.Left - 1, t.Bottom);
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
// Scrunch just the right margin
|
||||
HelpView.Margin.Thickness = new (t.Right, t.Top, t.Left - 1, t.Bottom);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Frame.Width is smaller than the natural width. Reduce width of HelpView.
|
||||
_maxHelpWidth = int.Max (0, GetContentSize ().Width - CommandView.Frame.Width - KeyView.Frame.Width);
|
||||
if (_maxHelpWidth < 3)
|
||||
{
|
||||
Thickness t = GetMarginThickness ();
|
||||
switch (_maxHelpWidth)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
// Scrunch it by removing both margins
|
||||
HelpView.Margin.Thickness = new (t.Right - 1, t.Top, t.Left - 1, t.Bottom);
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
// Scrunch just the right margin
|
||||
HelpView.Margin.Thickness = new (t.Right, t.Top, t.Left - 1, t.Bottom);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset to default
|
||||
HelpView.Margin.Thickness = GetMarginThickness ();
|
||||
}
|
||||
// Reset to default
|
||||
HelpView.Margin.Thickness = GetMarginThickness ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,7 +526,11 @@ public class Shortcut : View, IOrientation, IDesignable
|
||||
|
||||
private void SetHelpViewDefaultLayout ()
|
||||
{
|
||||
HelpView.Margin.Thickness = GetMarginThickness ();
|
||||
if (HelpView.Margin is { })
|
||||
{
|
||||
HelpView.Margin.Thickness = GetMarginThickness ();
|
||||
}
|
||||
|
||||
HelpView.X = Pos.Align (Alignment.End, AlignmentModes);
|
||||
_maxHelpWidth = HelpView.Text.GetColumns ();
|
||||
HelpView.Width = Dim.Auto (DimAutoStyle.Text, maximumContentDim: Dim.Func ((() => _maxHelpWidth)));
|
||||
@@ -654,7 +662,11 @@ public class Shortcut : View, IOrientation, IDesignable
|
||||
|
||||
private void SetKeyViewDefaultLayout ()
|
||||
{
|
||||
KeyView.Margin.Thickness = GetMarginThickness ();
|
||||
if (KeyView.Margin is { })
|
||||
{
|
||||
KeyView.Margin.Thickness = GetMarginThickness ();
|
||||
}
|
||||
|
||||
KeyView.X = Pos.Align (Alignment.End, AlignmentModes);
|
||||
KeyView.Width = Dim.Auto (DimAutoStyle.Text, minimumContentDim: Dim.Func (() => MinimumKeyTextSize));
|
||||
KeyView.Height = Dim.Fill ();
|
||||
@@ -763,7 +775,10 @@ public class Shortcut : View, IOrientation, IDesignable
|
||||
KeyView.ColorScheme = cs;
|
||||
}
|
||||
|
||||
CommandView.Margin.ColorScheme = base.ColorScheme;
|
||||
if (CommandView.Margin is { })
|
||||
{
|
||||
CommandView.Margin.ColorScheme = base.ColorScheme;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -216,7 +216,7 @@ public class TabView : View
|
||||
/// <summary>
|
||||
/// Updates the control to use the latest state settings in <see cref="Style"/>. This can change the size of the
|
||||
/// client area of the tab (for rendering the selected tab's content). This method includes a call to
|
||||
/// <see cref="View.SetNeedsDraw"/>.
|
||||
/// <see cref="View.SetNeedsDraw()"/>.
|
||||
/// </summary>
|
||||
public void ApplyStyleChanges ()
|
||||
{
|
||||
@@ -288,7 +288,7 @@ public class TabView : View
|
||||
|
||||
/// <summary>Updates <see cref="TabScrollOffset"/> to be a valid index of <see cref="Tabs"/>.</summary>
|
||||
/// <param name="value">The value to validate.</param>
|
||||
/// <remarks>Changes will not be immediately visible in the display until you call <see cref="View.SetNeedsDraw"/>.</remarks>
|
||||
/// <remarks>Changes will not be immediately visible in the display until you call <see cref="View.SetNeedsDraw()"/>.</remarks>
|
||||
/// <returns>The valid <see cref="TabScrollOffset"/> for the given value.</returns>
|
||||
public int EnsureValidScrollOffsets (int value) { return Math.Max (Math.Min (value, Tabs.Count - 1), 0); }
|
||||
|
||||
|
||||
@@ -583,7 +583,7 @@ public class TableView : View, IDesignable
|
||||
/// not been set.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Changes will not be immediately visible in the display until you call <see cref="View.SetNeedsDraw"/>
|
||||
/// Changes will not be immediately visible in the display until you call <see cref="View.SetNeedsDraw()"/>
|
||||
/// </remarks>
|
||||
public void EnsureSelectedCellIsVisible ()
|
||||
{
|
||||
@@ -644,7 +644,7 @@ public class TableView : View, IDesignable
|
||||
/// (by adjusting them to the nearest existing cell). Has no effect if <see cref="Table"/> has not been set.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Changes will not be immediately visible in the display until you call <see cref="View.SetNeedsDraw"/>
|
||||
/// Changes will not be immediately visible in the display until you call <see cref="View.SetNeedsDraw()"/>
|
||||
/// </remarks>
|
||||
public void EnsureValidScrollOffsets ()
|
||||
{
|
||||
@@ -663,7 +663,7 @@ public class TableView : View, IDesignable
|
||||
/// <see cref="Table"/> has not been set.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Changes will not be immediately visible in the display until you call <see cref="View.SetNeedsDraw"/>
|
||||
/// Changes will not be immediately visible in the display until you call <see cref="View.SetNeedsDraw()"/>
|
||||
/// </remarks>
|
||||
public void EnsureValidSelection ()
|
||||
{
|
||||
@@ -1227,7 +1227,7 @@ public class TableView : View, IDesignable
|
||||
/// Updates the view to reflect changes to <see cref="Table"/> and to (<see cref="ColumnOffset"/> /
|
||||
/// <see cref="RowOffset"/>) etc
|
||||
/// </summary>
|
||||
/// <remarks>This always calls <see cref="View.SetNeedsDraw"/></remarks>
|
||||
/// <remarks>This always calls <see cref="View.SetNeedsDraw()"/></remarks>
|
||||
public void Update ()
|
||||
{
|
||||
if (!IsInitialized || TableIsNullOrInvisible ())
|
||||
|
||||
Reference in New Issue
Block a user