|
@@ -3,69 +3,6 @@ using System.Diagnostics;
|
|
|
|
|
|
namespace Terminal.Gui;
|
|
|
|
|
|
-/// <summary>
|
|
|
-/// Specifies how <see cref="Dim.Auto"/> will compute the dimension.
|
|
|
-/// </summary>
|
|
|
-[Flags]
|
|
|
-public enum DimAutoStyle
|
|
|
-{
|
|
|
- /// <summary>
|
|
|
- /// The dimension will be computed using both the view's <see cref="View.Text"/> and
|
|
|
- /// <see cref="View.Subviews"/> (whichever is larger).
|
|
|
- /// </summary>
|
|
|
- Auto = Content | Text,
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// The dimensions will be computed based on the View's non-Text content.
|
|
|
- /// <para>
|
|
|
- /// If <see cref="View.ContentSize"/> is explicitly set (is not <see langword="null"/>) then
|
|
|
- /// <see cref="View.ContentSize"/>
|
|
|
- /// will be used to determine the dimension.
|
|
|
- /// </para>
|
|
|
- /// <para>
|
|
|
- /// Otherwise, the Subview in <see cref="View.Subviews"/> with the largest corresponding position plus dimension
|
|
|
- /// will determine the dimension.
|
|
|
- /// </para>
|
|
|
- /// <para>
|
|
|
- /// The corresponding dimension of the view's <see cref="View.Text"/> will be ignored.
|
|
|
- /// </para>
|
|
|
- /// </summary>
|
|
|
- Content = 0,
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// <para>
|
|
|
- /// The corresponding dimension of the view's <see cref="View.Text"/>, formatted using the
|
|
|
- /// <see cref="View.TextFormatter"/> settings,
|
|
|
- /// will be used to determine the dimension.
|
|
|
- /// </para>
|
|
|
- /// <para>
|
|
|
- /// The corresponding dimensions of the <see cref="View.Subviews"/> will be ignored.
|
|
|
- /// </para>
|
|
|
- /// </summary>
|
|
|
- Text = 1
|
|
|
-}
|
|
|
-
|
|
|
-/// <summary>
|
|
|
-/// Indicates the dimension for <see cref="Dim"/> operations.
|
|
|
-/// </summary>
|
|
|
-public enum Dimension
|
|
|
-{
|
|
|
- /// <summary>
|
|
|
- /// No dimension specified.
|
|
|
- /// </summary>
|
|
|
- None = 0,
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// The height dimension.
|
|
|
- /// </summary>
|
|
|
- Height = 1,
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// The width dimension.
|
|
|
- /// </summary>
|
|
|
- Width = 2
|
|
|
-}
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// <para>
|
|
|
/// A Dim object describes the dimensions of a <see cref="View"/>. Dim is the type of the
|
|
@@ -337,479 +274,4 @@ public abstract class Dim
|
|
|
|
|
|
#endregion operators
|
|
|
|
|
|
-}
|
|
|
-
|
|
|
-/// <summary>
|
|
|
-/// Represents a dimension that is a fixed size.
|
|
|
-/// </summary>
|
|
|
-/// <remarks>
|
|
|
-/// <para>
|
|
|
-/// This is a low-level API that is typically used internally by the layout system. Use the various static
|
|
|
-/// methods on the <see cref="Dim"/> class to create <see cref="Dim"/> objects instead.
|
|
|
-/// </para>
|
|
|
-/// </remarks>
|
|
|
-/// <param name="size"></param>
|
|
|
-public class DimAbsolute (int size) : Dim
|
|
|
-{
|
|
|
- /// <inheritdoc/>
|
|
|
- public override bool Equals (object? other) { return other is DimAbsolute abs && abs.Size == Size; }
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override int GetHashCode () { return Size.GetHashCode (); }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets the size of the dimension.
|
|
|
- /// </summary>
|
|
|
- public int Size { get; } = size;
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override string ToString () { return $"Absolute({Size})"; }
|
|
|
-
|
|
|
- internal override int GetAnchor (int size) { return Size; }
|
|
|
-
|
|
|
- internal override int Calculate (int location, int superviewContentSize, View us, Dimension dimension)
|
|
|
- {
|
|
|
- return Math.Max (GetAnchor (0), 0);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/// <summary>
|
|
|
-/// Represents a dimension that automatically sizes the view to fit all the view's Content, SubViews, and/or Text.
|
|
|
-/// </summary>
|
|
|
-/// <remarks>
|
|
|
-/// <para>
|
|
|
-/// See <see cref="DimAutoStyle"/>.
|
|
|
-/// </para>
|
|
|
-/// <para>
|
|
|
-/// This is a low-level API that is typically used internally by the layout system. Use the various static
|
|
|
-/// methods on the <see cref="Dim"/> class to create <see cref="Dim"/> objects instead.
|
|
|
-/// </para>
|
|
|
-/// </remarks>
|
|
|
-public class DimAuto () : Dim
|
|
|
-{
|
|
|
- private readonly Dim? _maximumContentDim;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets the maximum dimension the View's ContentSize will be fit to. NOT CURRENTLY SUPPORTED.
|
|
|
- /// </summary>
|
|
|
- // ReSharper disable once ConvertToAutoProperty
|
|
|
- public required Dim? MaximumContentDim
|
|
|
- {
|
|
|
- get => _maximumContentDim;
|
|
|
- init => _maximumContentDim = value;
|
|
|
- }
|
|
|
-
|
|
|
- private readonly Dim? _minimumContentDim;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets the minimum dimension the View's ContentSize will be constrained to.
|
|
|
- /// </summary>
|
|
|
- // ReSharper disable once ConvertToAutoProperty
|
|
|
- public required Dim? MinimumContentDim
|
|
|
- {
|
|
|
- get => _minimumContentDim;
|
|
|
- init => _minimumContentDim = value;
|
|
|
- }
|
|
|
-
|
|
|
- private readonly DimAutoStyle _style;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets the style of the DimAuto.
|
|
|
- /// </summary>
|
|
|
- // ReSharper disable once ConvertToAutoProperty
|
|
|
- public required DimAutoStyle Style
|
|
|
- {
|
|
|
- get => _style;
|
|
|
- init => _style = value;
|
|
|
- }
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override string ToString () { return $"Auto({Style},{MinimumContentDim},{MaximumContentDim})"; }
|
|
|
-
|
|
|
- internal override int Calculate (int location, int superviewContentSize, View us, Dimension dimension)
|
|
|
- {
|
|
|
- var textSize = 0;
|
|
|
- var subviewsSize = 0;
|
|
|
-
|
|
|
- int autoMin = MinimumContentDim?.GetAnchor (superviewContentSize) ?? 0;
|
|
|
-
|
|
|
- if (Style.HasFlag (DimAutoStyle.Text))
|
|
|
- {
|
|
|
- textSize = int.Max (autoMin, dimension == Dimension.Width ? us.TextFormatter.Size.Width : us.TextFormatter.Size.Height);
|
|
|
- }
|
|
|
-
|
|
|
- if (Style.HasFlag (DimAutoStyle.Content))
|
|
|
- {
|
|
|
- if (us._contentSize is { })
|
|
|
- {
|
|
|
- subviewsSize = dimension == Dimension.Width ? us.ContentSize.Width : us.ContentSize.Height;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // TODO: This whole body of code is a WIP (for https://github.com/gui-cs/Terminal.Gui/pull/3451).
|
|
|
- subviewsSize = 0;
|
|
|
-
|
|
|
- List<View> subviews;
|
|
|
-
|
|
|
- if (dimension == Dimension.Width)
|
|
|
- {
|
|
|
- subviews = us.Subviews.Where (v => v.X is not PosAnchorEnd && v.Width is not DimFill).ToList ();
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- subviews = us.Subviews.Where (v => v.Y is not PosAnchorEnd && v.Height is not DimFill).ToList ();
|
|
|
- }
|
|
|
-
|
|
|
- for (var i = 0; i < subviews.Count; i++)
|
|
|
- {
|
|
|
- View v = subviews [i];
|
|
|
-
|
|
|
- int size = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
|
|
|
-
|
|
|
- if (size > subviewsSize)
|
|
|
- {
|
|
|
- subviewsSize = size;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (dimension == Dimension.Width)
|
|
|
- {
|
|
|
- subviews = us.Subviews.Where (v => v.X is PosAnchorEnd).ToList ();
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- subviews = us.Subviews.Where (v => v.Y is PosAnchorEnd).ToList ();
|
|
|
- }
|
|
|
-
|
|
|
- int maxAnchorEnd = 0;
|
|
|
- for (var i = 0; i < subviews.Count; i++)
|
|
|
- {
|
|
|
- View v = subviews [i];
|
|
|
- maxAnchorEnd = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
|
|
|
- }
|
|
|
-
|
|
|
- subviewsSize += maxAnchorEnd;
|
|
|
-
|
|
|
-
|
|
|
- if (dimension == Dimension.Width)
|
|
|
- {
|
|
|
- subviews = us.Subviews.Where (v => v.Width is DimFill).ToList ();
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- subviews = us.Subviews.Where (v => v.Height is DimFill).ToList ();
|
|
|
- }
|
|
|
-
|
|
|
- for (var i = 0; i < subviews.Count; i++)
|
|
|
- {
|
|
|
- View v = subviews [i];
|
|
|
-
|
|
|
- if (dimension == Dimension.Width)
|
|
|
- {
|
|
|
- v.SetRelativeLayout (new Size (autoMin - subviewsSize, 0));
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- v.SetRelativeLayout (new Size (0, autoMin - subviewsSize));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // All sizes here are content-relative; ignoring adornments.
|
|
|
- // We take the largest of text and content.
|
|
|
- int max = int.Max (textSize, subviewsSize);
|
|
|
-
|
|
|
- // And, if min: is set, it wins if larger
|
|
|
- max = int.Max (max, autoMin);
|
|
|
-
|
|
|
- // Factor in adornments
|
|
|
- Thickness thickness = us.GetAdornmentsThickness ();
|
|
|
-
|
|
|
- max += dimension switch
|
|
|
- {
|
|
|
- Dimension.Width => thickness.Horizontal,
|
|
|
- Dimension.Height => thickness.Vertical,
|
|
|
- Dimension.None => 0,
|
|
|
- _ => throw new ArgumentOutOfRangeException (nameof (dimension), dimension, null)
|
|
|
- };
|
|
|
-
|
|
|
- return int.Min (max, MaximumContentDim?.GetAnchor (superviewContentSize) ?? max);
|
|
|
- }
|
|
|
-
|
|
|
- internal override bool ReferencesOtherViews ()
|
|
|
- {
|
|
|
- // BUGBUG: This is not correct. _contentSize may be null.
|
|
|
- return false; //_style.HasFlag (DimAutoStyle.Content);
|
|
|
- }
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override bool Equals (object? other)
|
|
|
- {
|
|
|
- if (other is not DimAuto auto)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- return auto.MinimumContentDim == MinimumContentDim &&
|
|
|
- auto.MaximumContentDim == MaximumContentDim &&
|
|
|
- auto.Style == Style;
|
|
|
- }
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override int GetHashCode ()
|
|
|
- {
|
|
|
- return HashCode.Combine (MinimumContentDim, MaximumContentDim, Style);
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-/// <summary>
|
|
|
-/// Represents a dimension that is a combination of two other dimensions.
|
|
|
-/// </summary>
|
|
|
-/// <param name="add">
|
|
|
-/// Indicates whether the two dimensions are added or subtracted.
|
|
|
-/// </param>
|
|
|
-/// <remarks>
|
|
|
-/// This is a low-level API that is typically used internally by the layout system. Use the various static
|
|
|
-/// methods on the <see cref="Dim"/> class to create <see cref="Dim"/> objects instead.
|
|
|
-/// </remarks>
|
|
|
-/// <param name="left">The left dimension.</param>
|
|
|
-/// <param name="right">The right dimension.</param>
|
|
|
-public class DimCombine (AddOrSubtract add, Dim? left, Dim? right) : Dim
|
|
|
-{
|
|
|
- /// <summary>
|
|
|
- /// Gets whether the two dimensions are added or subtracted.
|
|
|
- /// </summary>
|
|
|
- public AddOrSubtract Add { get; } = add;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets the left dimension.
|
|
|
- /// </summary>
|
|
|
- public Dim? Left { get; } = left;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets the right dimension.
|
|
|
- /// </summary>
|
|
|
- public Dim? Right { get; } = right;
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override string ToString () { return $"Combine({Left}{(Add == AddOrSubtract.Add ? '+' : '-')}{Right})"; }
|
|
|
-
|
|
|
- internal override int GetAnchor (int size)
|
|
|
- {
|
|
|
- int la = Left!.GetAnchor (size);
|
|
|
- int ra = Right!.GetAnchor (size);
|
|
|
-
|
|
|
- if (Add == AddOrSubtract.Add)
|
|
|
- {
|
|
|
- return la + ra;
|
|
|
- }
|
|
|
-
|
|
|
- return la - ra;
|
|
|
- }
|
|
|
-
|
|
|
- internal override int Calculate (int location, int superviewContentSize, View us, Dimension dimension)
|
|
|
- {
|
|
|
- int leftNewDim = Left!.Calculate (location, superviewContentSize, us, dimension);
|
|
|
- int rightNewDim = Right!.Calculate (location, superviewContentSize, us, dimension);
|
|
|
-
|
|
|
- int newDimension;
|
|
|
-
|
|
|
- if (Add == AddOrSubtract.Add)
|
|
|
- {
|
|
|
- newDimension = leftNewDim + rightNewDim;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- newDimension = Math.Max (0, leftNewDim - rightNewDim);
|
|
|
- }
|
|
|
-
|
|
|
- return newDimension;
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Diagnostics API to determine if this Dim object references other views.
|
|
|
- /// </summary>
|
|
|
- /// <returns></returns>
|
|
|
- internal override bool ReferencesOtherViews ()
|
|
|
- {
|
|
|
- if (Left!.ReferencesOtherViews ())
|
|
|
- {
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- if (Right!.ReferencesOtherViews ())
|
|
|
- {
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/// <summary>
|
|
|
-/// Represents a dimension that is a percentage of the width or height of the SuperView.
|
|
|
-/// </summary>
|
|
|
-/// <remarks>
|
|
|
-/// This is a low-level API that is typically used internally by the layout system. Use the various static
|
|
|
-/// methods on the <see cref="Dim"/> class to create <see cref="Dim"/> objects instead.
|
|
|
-/// </remarks>
|
|
|
-/// <param name="percent">The percentage.</param>
|
|
|
-/// <param name="usePosition">
|
|
|
-/// If <see langword="true"/> the dimension is computed using the View's position (<see cref="View.X"/> or
|
|
|
-/// <see cref="View.Y"/>).
|
|
|
-/// If <see langword="false"/> the dimension is computed using the View's <see cref="View.ContentSize"/>.
|
|
|
-/// </param>
|
|
|
-public class DimPercent (float percent, bool usePosition = false) : Dim
|
|
|
-{
|
|
|
- /// <inheritdoc/>
|
|
|
- public override bool Equals (object? other) { return other is DimPercent f && f.Percent == Percent && f.UsePosition == UsePosition; }
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override int GetHashCode () { return Percent.GetHashCode (); }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets the percentage.
|
|
|
- /// </summary>
|
|
|
- public new float Percent { get; } = percent;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// </summary>
|
|
|
- /// <returns></returns>
|
|
|
- public override string ToString () { return $"Percent({Percent},{UsePosition})"; }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets whether the dimension is computed using the View's position or ContentSize.
|
|
|
- /// </summary>
|
|
|
- public bool UsePosition { get; } = usePosition;
|
|
|
-
|
|
|
- internal override int GetAnchor (int size) { return (int)(size * Percent); }
|
|
|
-
|
|
|
- internal override int Calculate (int location, int superviewContentSize, View us, Dimension dimension)
|
|
|
- {
|
|
|
- return UsePosition ? Math.Max (GetAnchor (superviewContentSize - location), 0) : GetAnchor (superviewContentSize);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/// <summary>
|
|
|
-/// Represents a dimension that fills the dimension, leaving the specified margin.
|
|
|
-/// </summary>
|
|
|
-/// <remarks>
|
|
|
-/// This is a low-level API that is typically used internally by the layout system. Use the various static
|
|
|
-/// methods on the <see cref="Dim"/> class to create <see cref="Dim"/> objects instead.
|
|
|
-/// </remarks>
|
|
|
-/// <param name="margin">The margin to not fill.</param>
|
|
|
-public class DimFill (int margin) : Dim
|
|
|
-{
|
|
|
- /// <inheritdoc/>
|
|
|
- public override bool Equals (object? other) { return other is DimFill fill && fill.Margin == Margin; }
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override int GetHashCode () { return Margin.GetHashCode (); }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets the margin to not fill.
|
|
|
- /// </summary>
|
|
|
- public int Margin { get; } = margin;
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override string ToString () { return $"Fill({Margin})"; }
|
|
|
-
|
|
|
- internal override int GetAnchor (int size) { return size - Margin; }
|
|
|
-}
|
|
|
-
|
|
|
-/// <summary>
|
|
|
-/// Represents a function <see cref="Dim"/> object that computes the dimension by executing the provided function.
|
|
|
-/// </summary>
|
|
|
-/// <remarks>
|
|
|
-/// This is a low-level API that is typically used internally by the layout system. Use the various static
|
|
|
-/// methods on the <see cref="Dim"/> class to create <see cref="Dim"/> objects instead.
|
|
|
-/// </remarks>
|
|
|
-/// <param name="dim"></param>
|
|
|
-public class DimFunc (Func<int> dim) : Dim
|
|
|
-{
|
|
|
- /// <inheritdoc/>
|
|
|
- public override bool Equals (object? other) { return other is DimFunc f && f.Func () == Func (); }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets the function that computes the dimension.
|
|
|
- /// </summary>
|
|
|
- public new Func<int> Func { get; } = dim;
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override int GetHashCode () { return Func.GetHashCode (); }
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override string ToString () { return $"DimFunc({Func ()})"; }
|
|
|
-
|
|
|
- internal override int GetAnchor (int size) { return Func (); }
|
|
|
-}
|
|
|
-
|
|
|
-/// <summary>
|
|
|
-/// Represents a dimension that tracks the Height or Width of the specified View.
|
|
|
-/// </summary>
|
|
|
-/// <remarks>
|
|
|
-/// This is a low-level API that is typically used internally by the layout system. Use the various static
|
|
|
-/// methods on the <see cref="Dim"/> class to create <see cref="Dim"/> objects instead.
|
|
|
-/// </remarks>
|
|
|
-public class DimView : Dim
|
|
|
-{
|
|
|
- /// <summary>
|
|
|
- /// Initializes a new instance of the <see cref="DimView"/> class.
|
|
|
- /// </summary>
|
|
|
- /// <param name="view">The view the dimension is anchored to.</param>
|
|
|
- /// <param name="dimension">Indicates which dimension is tracked.</param>
|
|
|
- public DimView (View view, Dimension dimension)
|
|
|
- {
|
|
|
- Target = view;
|
|
|
- Dimension = dimension;
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets the indicated dimension of the View.
|
|
|
- /// </summary>
|
|
|
- public Dimension Dimension { get; }
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override bool Equals (object? other) { return other is DimView abs && abs.Target == Target && abs.Dimension == Dimension; }
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override int GetHashCode () { return Target.GetHashCode (); }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets the View the dimension is anchored to.
|
|
|
- /// </summary>
|
|
|
- public View Target { get; init; }
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public override string ToString ()
|
|
|
- {
|
|
|
- if (Target == null)
|
|
|
- {
|
|
|
- throw new NullReferenceException ();
|
|
|
- }
|
|
|
-
|
|
|
- string dimString = Dimension switch
|
|
|
- {
|
|
|
- Dimension.Height => "Height",
|
|
|
- Dimension.Width => "Width",
|
|
|
- _ => "unknown"
|
|
|
- };
|
|
|
-
|
|
|
- return $"View({dimString},{Target})";
|
|
|
- }
|
|
|
-
|
|
|
- internal override int GetAnchor (int size)
|
|
|
- {
|
|
|
- return Dimension switch
|
|
|
- {
|
|
|
- Dimension.Height => Target.Frame.Height,
|
|
|
- Dimension.Width => Target.Frame.Width,
|
|
|
- _ => 0
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- internal override bool ReferencesOtherViews () { return true; }
|
|
|
-}
|
|
|
+}
|