#nullable enable namespace Terminal.Gui; using System.Numerics; /// /// /// A Dim object describes the dimensions of a . Dim is the type of the /// and properties of . /// /// /// Integer values are implicitly convertible to an absolute . These objects are created using /// the static methods described below. The objects can be combined with the addition and /// subtraction operators. /// /// /// /// /// /// /// Dim Object Description /// /// /// /// /// /// /// Creates a that is a fixed size. /// /// /// /// /// /// /// /// Creates a object that automatically sizes the view to fit /// the view's Text, SubViews, or ContentArea. /// /// /// /// /// /// /// /// Creates a object that computes the dimension by executing the provided /// function. The function will be called every time the dimension is needed. /// /// /// /// /// /// /// /// Creates a object that is a percentage of the width or height of the /// SuperView. /// /// /// /// /// /// /// /// Creates a object that fills the dimension from the View's X position /// to the end of the super view's width, leaving the specified number of columns for a margin. /// /// /// /// /// /// /// /// Creates a object that tracks the Width of the specified /// . /// /// /// /// /// /// /// /// Creates a object that tracks the Height of the specified /// . /// /// /// /// /// /// public abstract record Dim : IEqualityOperators { #region static Dim creation methods /// Creates an Absolute from the specified integer value. /// The Absolute . /// The value to convert to the . public static Dim? Absolute (int size) { return new DimAbsolute (size); } /// /// Creates a object that automatically sizes the view to fit all the view's Content, Subviews, and/or Text. /// /// /// /// See . /// /// /// /// This initializes a with two SubViews. The view will be automatically sized to fit the two /// SubViews. /// /// var button = new Button () { Text = "Click Me!", X = 1, Y = 1, Width = 10, Height = 1 }; /// var textField = new TextField { Text = "Type here", X = 1, Y = 2, Width = 20, Height = 1 }; /// var view = new Window () { Title = "MyWindow", X = 0, Y = 0, Width = Dim.Auto (), Height = Dim.Auto () }; /// view.Add (button, textField); /// /// /// The object. /// /// Specifies how will compute the dimension. The default is . /// /// The minimum dimension the View's ContentSize will be constrained to. /// The maximum dimension the View's ContentSize will be fit to. public static Dim? Auto (DimAutoStyle style = DimAutoStyle.Auto, Dim? minimumContentDim = null, Dim? maximumContentDim = null) { return new DimAuto ( MinimumContentDim: minimumContentDim, MaximumContentDim: maximumContentDim, Style: style); } /// /// Creates a object that fills the dimension, leaving no margin. /// /// The Fill dimension. public static Dim? Fill () { return new DimFill (0); } /// /// Creates a object that fills the dimension, leaving the specified margin. /// /// The Fill dimension. /// Margin to use. public static Dim? Fill (Dim margin) { return new DimFill (margin); } /// /// Creates a function object that computes the dimension by executing the provided function. /// The function will be called every time the dimension is needed. /// /// The function to be executed. /// The returned from the function. public static Dim Func (Func function) { return new DimFunc (function); } /// Creates a object that tracks the Height of the specified . /// The height of the other . /// The view that will be tracked. public static Dim Height (View? view) { return new DimView (view, Dimension.Height); } /// Creates a percentage object that is a percentage of the width or height of the SuperView. /// The percent object. /// A value between 0 and 100 representing the percentage. /// the mode. Defaults to . /// /// This initializes a that will be centered horizontally, is 50% of the way down, is 30% the /// height, /// and is 80% the width of the SuperView. /// /// var textView = new TextField { /// X = Pos.Center (), /// Y = Pos.Percent (50), /// Width = Dim.Percent (80), /// Height = Dim.Percent (30), /// }; /// /// public static Dim? Percent (int percent, DimPercentMode mode = DimPercentMode.ContentSize) { ArgumentOutOfRangeException.ThrowIfNegative (percent, nameof (percent)); return new DimPercent (percent, mode); } /// Creates a object that tracks the Width of the specified . /// The width of the other . /// The view that will be tracked. public static Dim Width (View? view) { return new DimView (view, Dimension.Width); } #endregion static Dim creation methods /// /// Indicates whether the specified type is in the hierarchy of this Dim object. /// /// A reference to this instance. /// public bool Has (out T dim) where T : Dim { dim = (this as T)!; return this switch { DimCombine combine => combine.Left.Has (out dim) || combine.Right.Has (out dim), T => true, _ => false }; } #region virtual methods /// /// Gets a dimension that is anchored to a certain point in the layout. /// This method is typically used internally by the layout system to determine the size of a View. /// /// The width of the area where the View is being sized (Superview.GetContentSize ()). /// /// An integer representing the calculated dimension. The way this dimension is calculated depends on the specific /// subclass of Dim that is used. For example, DimAbsolute returns a fixed dimension, DimFactor returns a /// dimension that is a certain percentage of the super view's size, and so on. /// internal abstract int GetAnchor (int size); /// /// Calculates and returns the dimension of a object. It takes into account the location of the /// , it's SuperView's ContentSize, and whether it should automatically adjust its size based on its /// content. /// /// /// The starting point from where the size calculation begins. It could be the left edge for width calculation or the /// top edge for height calculation. /// /// The size of the SuperView's content. It could be width or height. /// The View that holds this Pos object. /// Width or Height /// /// The calculated size of the View. The way this size is calculated depends on the specific subclass of Dim that /// is used. /// internal virtual int Calculate (int location, int superviewContentSize, View us, Dimension dimension) { return Math.Clamp (GetAnchor (superviewContentSize - location), 0, short.MaxValue); } /// /// Diagnostics API to determine if this Dim object references other views. /// /// internal virtual bool ReferencesOtherViews () { return false; } #endregion virtual methods #region operators /// Adds a to a , yielding a new . /// The first to add. /// The second to add. /// The that is the sum of the values of left and right. public static Dim operator + (Dim left, Dim right) { if (left is DimAbsolute && right is DimAbsolute) { return new DimAbsolute (left.GetAnchor (0) + right.GetAnchor (0)); } var newDim = new DimCombine (AddOrSubtract.Add, left, right); (left as DimView)?.Target?.SetNeedsLayout (); return newDim; } /// Creates an Absolute from the specified integer value. /// The Absolute . /// The value to convert to the pos. public static implicit operator Dim (int n) { return new DimAbsolute (n); } /// /// Subtracts a from a , yielding a new /// . /// /// The to subtract from (the minuend). /// The to subtract (the subtrahend). /// The that is the left minus right. public static Dim operator - (Dim left, Dim right) { if (left is DimAbsolute && right is DimAbsolute) { return new DimAbsolute (left.GetAnchor (0) - right.GetAnchor (0)); } var newDim = new DimCombine (AddOrSubtract.Subtract, left, right); (left as DimView)?.Target?.SetNeedsLayout (); return newDim; } #endregion operators }