From 57670c4a6446c8f87495824a317965f5c6d377f8 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Mon, 18 Dec 2023 01:10:46 -0700 Subject: [PATCH] Revamped Pos / Dim API docs --- Terminal.Gui/View/Layout/PosDim.cs | 375 +++++++++++++++++++---------- 1 file changed, 253 insertions(+), 122 deletions(-) diff --git a/Terminal.Gui/View/Layout/PosDim.cs b/Terminal.Gui/View/Layout/PosDim.cs index 79b7acd79..e932decae 100644 --- a/Terminal.Gui/View/Layout/PosDim.cs +++ b/Terminal.Gui/View/Layout/PosDim.cs @@ -6,8 +6,9 @@ // using System; +using static Terminal.Gui.Dim; -namespace Terminal.Gui; +namespace Terminal.Gui; /// /// Describes the position of a which can be an absolute value, a percentage, centered, or @@ -31,44 +32,120 @@ namespace Terminal.Gui; /// Left(View), Right(View), Bottom(View), Top(View). The X(View) and Y(View) are /// aliases to Left(View) and Top(View) respectively. /// +/// +/// +/// +/// Pos Object +/// Description +/// +/// +/// +/// +/// Creates a object that computes the position by executing the provided function. The function will be called every time the position is needed. +/// +/// +/// +/// +/// +/// Creates a object that is a percentage of the width or height of the SuperView. +/// +/// +/// +/// +/// +/// Creates a object that is anchored to the end (right side or bottom) of the dimension, +/// useful to flush the layout from the right or bottom. +/// +/// +/// +/// +/// +/// Creates a object that can be used to center the . +/// +/// +/// +/// +/// +/// Creates a object that is an absolute position based on the specified integer value. +/// +/// +/// +/// +/// +/// Creates a object that tracks the Left (X) position of the specified . +/// +/// +/// +/// +/// +/// Creates a object that tracks the Left (X) position of the specified . +/// +/// +/// +/// +/// +/// Creates a object that tracks the Top (Y) position of the specified . +/// +/// +/// +/// +/// +/// Creates a object that tracks the Top (Y) position of the specified . +/// +/// +/// +/// +/// +/// Creates a object that tracks the Right (X+Width) coordinate of the specified . +/// +/// +/// +/// +/// +/// Creates a object that tracks the Bottom (Y+Height) coordinate of the specified +/// +/// +/// +/// +/// /// public class Pos { internal virtual int Anchor (int width) => 0; - // Helper class to provide dynamic value by the execution of a function that returns an integer. - internal class PosFunc : Pos { - Func function; - - public PosFunc (Func n) => function = n; - - internal override int Anchor (int width) => function (); - - public override string ToString () => $"PosFunc({function ()})"; - - public override int GetHashCode () => function.GetHashCode (); - - public override bool Equals (object other) => other is PosFunc f && f.function () == function (); - } - /// - /// Creates a "PosFunc" from the specified function. + /// Creates a object that computes the position by executing the provided function. The function will be called every time the position is needed. /// /// The function to be executed. /// The returned from the function. public static Pos Function (Func function) => new PosFunc (function); internal class PosFactor : Pos { - float factor; + readonly float _factor; - public PosFactor (float n) => factor = n; + public PosFactor (float n) => _factor = n; - internal override int Anchor (int width) => (int)(width * factor); + internal override int Anchor (int width) => (int)(width * _factor); - public override string ToString () => $"Factor({factor})"; + public override string ToString () => $"Factor({_factor})"; - public override int GetHashCode () => factor.GetHashCode (); + public override int GetHashCode () => _factor.GetHashCode (); - public override bool Equals (object other) => other is PosFactor f && f.factor == factor; + public override bool Equals (object other) => other is PosFactor f && f._factor == _factor; + } + + // Helper class to provide dynamic value by the execution of a function that returns an integer. + internal class PosFunc : Pos { + readonly Func _function; + + public PosFunc (Func n) => _function = n; + + internal override int Anchor (int width) => _function (); + + public override string ToString () => $"PosFunc({_function ()})"; + + public override int GetHashCode () => _function.GetHashCode (); + + public override bool Equals (object other) => other is PosFunc f && f._function () == _function (); } /// @@ -90,27 +167,13 @@ public class Pos { /// public static Pos Percent (float n) { - if (n < 0 || n > 100) { + if (n is < 0 or > 100) { throw new ArgumentException ("Percent value must be between 0 and 100"); } return new PosFactor (n / 100); } - internal class PosAnchorEnd : Pos { - int n; - - public PosAnchorEnd (int n) => this.n = n; - - internal override int Anchor (int width) => width - n; - - public override string ToString () => $"AnchorEnd({n})"; - - public override int GetHashCode () => n.GetHashCode (); - - public override bool Equals (object other) => other is PosAnchorEnd anchorEnd && anchorEnd.n == n; - } - /// /// Creates a object that is anchored to the end (right side or bottom) of the dimension, /// useful to flush the layout from the right or bottom. @@ -134,14 +197,22 @@ public class Pos { return new PosAnchorEnd (margin); } - internal class PosCenter : Pos { - internal override int Anchor (int width) => width / 2; + internal class PosAnchorEnd : Pos { + readonly int _p; - public override string ToString () => "Center"; + public PosAnchorEnd (int n) => _p = n; + + internal override int Anchor (int width) => width - _p; + + public override string ToString () => $"AnchorEnd({_p})"; + + public override int GetHashCode () => _p.GetHashCode (); + + public override bool Equals (object other) => other is PosAnchorEnd anchorEnd && anchorEnd._p == _p; } /// - /// Returns a object that can be used to center the + /// Creates a object that can be used to center the . /// /// The center Pos. /// @@ -159,27 +230,26 @@ public class Pos { public static Pos Center () => new PosCenter (); internal class PosAbsolute : Pos { - int n; - public PosAbsolute (int n) => this.n = n; + readonly int _n; + public PosAbsolute (int n) => _n = n; - public override string ToString () => $"Absolute({n})"; + public override string ToString () => $"Absolute({_n})"; - internal override int Anchor (int width) => n; + internal override int Anchor (int width) => _n; - public override int GetHashCode () => n.GetHashCode (); + public override int GetHashCode () => _n.GetHashCode (); - public override bool Equals (object other) => other is PosAbsolute abs && abs.n == n; + public override bool Equals (object other) => other is PosAbsolute abs && abs._n == _n; + } + + internal class PosCenter : Pos { + internal override int Anchor (int width) => width / 2; + + public override string ToString () => "Center"; } /// - /// Creates an Absolute from the specified integer value. - /// - /// The Absolute . - /// The value to convert to the . - public static implicit operator Pos (int n) => new PosAbsolute (n); - - /// - /// Creates an Absolute from the specified integer value. + /// Creates a object that is an absolute position based on the specified integer value. /// /// The Absolute . /// The value to convert to the . @@ -210,6 +280,13 @@ public class Pos { public override string ToString () => $"Combine({left}{(add ? '+' : '-')}{right})"; } + /// + /// Creates an Absolute from the specified integer value. + /// + /// The Absolute . + /// The value to convert to the . + public static implicit operator Pos (int n) => new PosAbsolute (n); + /// /// Adds a to a , yielding a new . /// @@ -302,42 +379,42 @@ public class Pos { } /// - /// Returns a object tracks the Left (X) position of the specified . + /// Creates a object that tracks the Left (X) position of the specified . /// /// The that depends on the other view. /// The that will be tracked. public static Pos Left (View view) => new PosCombine (true, new PosView (view, 0), new PosAbsolute (0)); /// - /// Returns a object tracks the Left (X) position of the specified . + /// Creates a object that tracks the Left (X) position of the specified . /// /// The that depends on the other view. /// The that will be tracked. public static Pos X (View view) => new PosCombine (true, new PosView (view, 0), new PosAbsolute (0)); /// - /// Returns a object tracks the Top (Y) position of the specified . + /// Creates a object that tracks the Top (Y) position of the specified . /// /// The that depends on the other view. /// The that will be tracked. public static Pos Top (View view) => new PosCombine (true, new PosView (view, 1), new PosAbsolute (0)); /// - /// Returns a object tracks the Top (Y) position of the specified . + /// Creates a object that tracks the Top (Y) position of the specified . /// /// The that depends on the other view. /// The that will be tracked. public static Pos Y (View view) => new PosCombine (true, new PosView (view, 1), new PosAbsolute (0)); /// - /// Returns a object tracks the Right (X+Width) coordinate of the specified . + /// Creates a object that tracks the Right (X+Width) coordinate of the specified . /// /// The that depends on the other view. /// The that will be tracked. public static Pos Right (View view) => new PosCombine (true, new PosView (view, 2), new PosAbsolute (0)); /// - /// Returns a object tracks the Bottom (Y+Height) coordinate of the specified + /// Creates a object that tracks the Bottom (Y+Height) coordinate of the specified /// /// The that depends on the other view. /// The that will be tracked. @@ -355,59 +432,88 @@ public class Pos { } /// -/// Dim properties of a to control the dimensions. +/// +/// A Dim object describes the dimensions of a . Dim is the type of the and +/// properties of . Dim objects enable Computed Layout (see ) +/// to automatically manage the dimensions of a view. +/// +/// +/// 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. +/// /// /// -/// -/// Use the Dim objects on the Width or Height properties of a to control the dimensions. -/// -/// -/// +/// +/// +/// +/// Dim Object +/// Description +/// +/// +/// +/// +/// 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, leaving the specified number of columns for a margin. +/// +/// +/// +/// +/// +/// Creates a object that automatically sizes the view to fit all of the view's SubViews. +/// +/// +/// +/// +/// +/// Creates a object that tracks the Width of the specified . +/// +/// +/// +/// +/// +/// Creates a object that tracks the Height of the specified . +/// +/// +/// +/// +/// +/// /// public class Dim { internal virtual int Anchor (int width) => 0; - // Helper class to provide dynamic value by the execution of a function that returns an integer. - internal class DimFunc : Dim { - Func function; - - public DimFunc (Func n) => function = n; - - internal override int Anchor (int width) => function (); - - public override string ToString () => $"DimFunc({function ()})"; - - public override int GetHashCode () => function.GetHashCode (); - - public override bool Equals (object other) => other is DimFunc f && f.function () == function (); - } - /// - /// Creates a "DimFunc" from the specified function. + /// 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 Function (Func function) => new DimFunc (function); - internal class DimFactor : Dim { - float factor; - bool remaining; + // Helper class to provide dynamic value by the execution of a function that returns an integer. + internal class DimFunc : Dim { + readonly Func _function; - public DimFactor (float n, bool r = false) - { - factor = n; - remaining = r; - } + public DimFunc (Func n) => _function = n; - internal override int Anchor (int width) => (int)(width * factor); + internal override int Anchor (int width) => _function (); - public bool IsFromRemaining () => remaining; + public override string ToString () => $"DimFunc({_function ()})"; - public override string ToString () => $"Factor({factor},{remaining})"; + public override int GetHashCode () => _function.GetHashCode (); - public override int GetHashCode () => factor.GetHashCode (); - - public override bool Equals (object other) => other is DimFactor f && f.factor == factor && f.remaining == remaining; + public override bool Equals (object other) => other is DimFunc f && f._function () == _function (); } /// @@ -438,6 +544,28 @@ public class Dim { return new DimFactor (n / 100, r); } + internal class DimFactor : Dim { + readonly float _factor; + readonly bool _remaining; + + public DimFactor (float n, bool r = false) + { + _factor = n; + _remaining = r; + } + + internal override int Anchor (int width) => (int)(width * _factor); + + public bool IsFromRemaining () => _remaining; + + public override string ToString () => $"Factor({_factor},{_remaining})"; + + public override int GetHashCode () => _factor.GetHashCode (); + + public override bool Equals (object other) => other is DimFactor f && f._factor == _factor && f._remaining == _remaining; + } + + internal class DimAbsolute : Dim { readonly int _n; public DimAbsolute (int n) => _n = n; @@ -465,12 +593,31 @@ public class Dim { } /// - /// Initializes a new instance of the class that fills the dimension, but leaves the specified number of columns for a margin. + /// Creates a object that fills the dimension, leaving the specified number of columns for a margin. /// /// The Fill dimension. /// Margin to use. public static Dim Fill (int margin = 0) => new DimFill (margin); + /// + /// Creates a object that automatically sizes the view to fit all of the view's SubViews. + /// + /// The AutoSize object. + /// Margin to use. + /// + /// 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.AutoSize (), Height = Dim.AutoSize () }; + /// view.Add (button, textField); + /// + /// + public static Dim AutoSize (int margin = 0) + { + return new DimAutoSize (margin); + } + internal class DimAutoSize : Dim { readonly int _margin; public DimAutoSize (int margin) @@ -490,25 +637,6 @@ public class Dim { public override bool Equals (object other) => other is DimAutoSize autoSize && autoSize._margin == _margin; } - /// - /// Creates an AutoSize object that is the size required to fit all of the view's SubViews. - /// - /// The AutoSize object. - /// Margin to use. - /// - /// 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.AutoSize (), Height = Dim.AutoSize () }; - /// view.Add (button, textField); - /// - /// - public static Dim AutoSize (int margin = 0) - { - return new DimAutoSize (margin); - } - /// /// Creates an Absolute from the specified integer value. /// @@ -601,6 +729,9 @@ public class Dim { public override string ToString () { + if (Target == null) { + throw new NullReferenceException (); + } string tside = _side switch { 0 => "Height", 1 => "Width", @@ -615,16 +746,16 @@ public class Dim { } /// - /// Returns a object tracks the Width of the specified . + /// Creates a object that tracks the Width of the specified . /// - /// The of the other . + /// The width of the other . /// The view that will be tracked. public static Dim Width (View view) => new DimView (view, 1); /// - /// Returns a object tracks the Height of the specified . + /// Creates a object that tracks the Height of the specified . /// - /// The of the other . + /// The height of the other . /// The view that will be tracked. public static Dim Height (View view) => new DimView (view, 0);