diff --git a/Terminal.Gui/View/Layout/DimAbsolute.cs b/Terminal.Gui/View/Layout/DimAbsolute.cs index aa2108cc2..cb078a121 100644 --- a/Terminal.Gui/View/Layout/DimAbsolute.cs +++ b/Terminal.Gui/View/Layout/DimAbsolute.cs @@ -10,13 +10,13 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -/// -public record DimAbsolute (int size) : Dim +/// +public record DimAbsolute (int Size) : Dim { /// /// Gets the size of the dimension. /// - public int Size { get; } = size; + public int Size { get; } = Size; /// public override string ToString () { return $"Absolute({Size})"; } diff --git a/Terminal.Gui/View/Layout/DimCombine.cs b/Terminal.Gui/View/Layout/DimCombine.cs index bf2006153..7a5d23614 100644 --- a/Terminal.Gui/View/Layout/DimCombine.cs +++ b/Terminal.Gui/View/Layout/DimCombine.cs @@ -4,31 +4,31 @@ namespace Terminal.Gui; /// /// Represents a dimension that is a combination of two other dimensions. /// -/// +/// /// Indicates whether the two dimensions are added or subtracted. /// /// /// This is a low-level API that is typically used internally by the layout system. Use the various static /// methods on the class to create objects instead. /// -/// The left dimension. -/// The right dimension. -public record DimCombine (AddOrSubtract add, Dim left, Dim right) : Dim +/// The left dimension. +/// The right dimension. +public record DimCombine (AddOrSubtract Add, Dim Left, Dim Right) : Dim { /// /// Gets whether the two dimensions are added or subtracted. /// - public AddOrSubtract Add { get; } = add; + public AddOrSubtract Add { get; } = Add; /// /// Gets the left dimension. /// - public Dim Left { get; } = left; + public Dim Left { get; } = Left; /// /// Gets the right dimension. /// - public Dim Right { get; } = right; + public Dim Right { get; } = Right; /// public override string ToString () { return $"Combine({Left}{(Add == AddOrSubtract.Add ? '+' : '-')}{Right})"; } diff --git a/Terminal.Gui/View/Layout/DimFill.cs b/Terminal.Gui/View/Layout/DimFill.cs index a5c964f51..27caa6aba 100644 --- a/Terminal.Gui/View/Layout/DimFill.cs +++ b/Terminal.Gui/View/Layout/DimFill.cs @@ -8,13 +8,13 @@ namespace Terminal.Gui; /// This is a low-level API that is typically used internally by the layout system. Use the various static /// methods on the class to create objects instead. /// -/// The margin to not fill. -public record DimFill (int margin) : Dim +/// The margin to not fill. +public record DimFill (int Margin) : Dim { /// /// Gets the margin to not fill. /// - public int Margin { get; } = margin; + public int Margin { get; } = Margin; /// public override string ToString () { return $"Fill({Margin})"; } diff --git a/Terminal.Gui/View/Layout/DimFunc.cs b/Terminal.Gui/View/Layout/DimFunc.cs index 042f85318..8e110d8cd 100644 --- a/Terminal.Gui/View/Layout/DimFunc.cs +++ b/Terminal.Gui/View/Layout/DimFunc.cs @@ -2,19 +2,19 @@ namespace Terminal.Gui; /// -/// Represents a function object that computes the dimension by executing the provided function. +/// Represents a function object that computes the dimension by executing the provided function. /// /// /// This is a low-level API that is typically used internally by the layout system. Use the various static -/// methods on the class to create objects instead. +/// methods on the class to create objects instead. /// -/// -public record DimFunc (Func dim) : Dim +/// +public record DimFunc (Func Dim) : Dim { /// /// Gets the function that computes the dimension. /// - public new Func Func { get; } = dim; + public new Func Func { get; } = Dim; /// public override int GetHashCode () { return Func.GetHashCode (); } diff --git a/Terminal.Gui/View/Layout/DimPercent.cs b/Terminal.Gui/View/Layout/DimPercent.cs index b1bf7e7c6..e62e4500d 100644 --- a/Terminal.Gui/View/Layout/DimPercent.cs +++ b/Terminal.Gui/View/Layout/DimPercent.cs @@ -8,17 +8,17 @@ namespace Terminal.Gui; /// This is a low-level API that is typically used internally by the layout system. Use the various static /// methods on the class to create objects instead. /// -/// The percentage. -/// +/// The percentage. +/// /// If the dimension is computed using the View's position ( or /// ); otherwise, the dimension is computed using the View's . /// -public record DimPercent (int percent, DimPercentMode mode = DimPercentMode.ContentSize) : Dim +public record DimPercent (int Percent, DimPercentMode Mode = DimPercentMode.ContentSize) : Dim { /// /// Gets the percentage. /// - public new int Percent { get; } = percent; + public new int Percent { get; } = Percent; /// /// @@ -28,7 +28,7 @@ public record DimPercent (int percent, DimPercentMode mode = DimPercentMode.Cont /// /// Gets whether the dimension is computed using the View's position or GetContentSize (). /// - public DimPercentMode Mode { get; } = mode; + public DimPercentMode Mode { get; } = Mode; internal override int GetAnchor (int size) { return (int)(size * (Percent / 100f)); } diff --git a/Terminal.Gui/View/Layout/PosAbsolute.cs b/Terminal.Gui/View/Layout/PosAbsolute.cs index 173d5a5b0..b71da5013 100644 --- a/Terminal.Gui/View/Layout/PosAbsolute.cs +++ b/Terminal.Gui/View/Layout/PosAbsolute.cs @@ -10,13 +10,13 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -/// -public record PosAbsolute (int position) : Pos +/// +public record PosAbsolute (int Position) : Pos { /// /// The position of the in the layout. /// - public int Position { get; } = position; + public int Position { get; } = Position; /// public override string ToString () { return $"Absolute({Position})"; } diff --git a/Terminal.Gui/View/Layout/PosAlign.cs b/Terminal.Gui/View/Layout/PosAlign.cs index 8ec4e754b..d3873a4c0 100644 --- a/Terminal.Gui/View/Layout/PosAlign.cs +++ b/Terminal.Gui/View/Layout/PosAlign.cs @@ -1,7 +1,6 @@ #nullable enable using System.ComponentModel; -using System.Drawing; namespace Terminal.Gui; @@ -31,12 +30,6 @@ public record PosAlign : Pos /// public int? _cachedLocation; - /// - /// Gets the identifier of a set of views that should be aligned together. When only a single - /// set of views in a SuperView is aligned, setting is not needed because it defaults to 0. - /// - public int GroupId { get; init; } - private readonly Aligner? _aligner; /// @@ -57,6 +50,88 @@ public record PosAlign : Pos } } + // TODO: PosAlign.CalculateMinDimension is a hack. Need to figure out a better way of doing this. + /// + /// Returns the minimum size a group of views with the same can be. + /// + /// + /// + /// + /// + public static int CalculateMinDimension (int groupId, IList views, Dimension dimension) + { + List dimensionsList = new (); + + // PERF: If this proves a perf issue, consider caching a ref to this list in each item + List viewsInGroup = views.Where ( + v => + { + return dimension switch + { + Dimension.Width when v.X is PosAlign alignX => alignX.GroupId == groupId, + Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId == groupId, + _ => false + }; + }) + .ToList (); + + if (viewsInGroup.Count == 0) + { + return 0; + } + + // PERF: We iterate over viewsInGroup multiple times here. + + // Update the dimensionList with the sizes of the views + for (var index = 0; index < viewsInGroup.Count; index++) + { + View view = viewsInGroup [index]; + + PosAlign? posAlign = dimension == Dimension.Width ? view.X as PosAlign : view.Y as PosAlign; + + if (posAlign is { }) + { + dimensionsList.Add (dimension == Dimension.Width ? view.Frame.Width : view.Frame.Height); + } + } + + // Align + return dimensionsList.Sum (); + } + + /// + /// Gets the identifier of a set of views that should be aligned together. When only a single + /// set of views in a SuperView is aligned, setting is not needed because it defaults to 0. + /// + public int GroupId { get; init; } + + /// + public override string ToString () { return $"Align(alignment={Aligner.Alignment},modes={Aligner.AlignmentModes},groupId={GroupId})"; } + + internal override int Calculate (int superviewDimension, Dim dim, View us, Dimension dimension) + { + if (_cachedLocation.HasValue && Aligner.ContainerSize == superviewDimension) + { + return _cachedLocation.Value; + } + + if (us?.SuperView is null) + { + return 0; + } + + AlignAndUpdateGroup (GroupId, us.SuperView.Subviews, dimension, superviewDimension); + + if (_cachedLocation.HasValue) + { + return _cachedLocation.Value; + } + + return 0; + } + + internal override int GetAnchor (int width) { return _cachedLocation ?? 0 - width; } + /// /// Aligns the views in that have the same group ID as . /// Updates each view's cached _location. @@ -71,30 +146,30 @@ public record PosAlign : Pos // PERF: If this proves a perf issue, consider caching a ref to this list in each item List posAligns = views.Select ( - v => - { - switch (dimension) - { - case Dimension.Width when v.X.Has (typeof (PosAlign), out var pos): + v => + { + switch (dimension) + { + case Dimension.Width when v.X.Has (typeof (PosAlign), out Pos pos): - if (pos is PosAlign posAlignX && posAlignX.GroupId == groupId) - { - return posAlignX; - } + if (pos is PosAlign posAlignX && posAlignX.GroupId == groupId) + { + return posAlignX; + } - break; - case Dimension.Height when v.Y.Has (typeof (PosAlign), out var pos): - if (pos is PosAlign posAlignY && posAlignY.GroupId == groupId) - { - return posAlignY; - } + break; + case Dimension.Height when v.Y.Has (typeof (PosAlign), out Pos pos): + if (pos is PosAlign posAlignY && posAlignY.GroupId == groupId) + { + return posAlignY; + } - break; - } + break; + } - return null; - }) - .ToList (); + return null; + }) + .ToList (); // PERF: We iterate over viewsInGroup multiple times here. @@ -136,80 +211,4 @@ public record PosAlign : Pos } private void Aligner_PropertyChanged (object? sender, PropertyChangedEventArgs e) { _cachedLocation = null; } - - /// - public override string ToString () { return $"Align(alignment={Aligner.Alignment},modes={Aligner.AlignmentModes},groupId={GroupId})"; } - - internal override int GetAnchor (int width) { return _cachedLocation ?? 0 - width; } - - internal override int Calculate (int superviewDimension, Dim dim, View us, Dimension dimension) - { - if (_cachedLocation.HasValue && Aligner.ContainerSize == superviewDimension) - { - return _cachedLocation.Value; - } - - if (us?.SuperView is null) - { - return 0; - } - - AlignAndUpdateGroup (GroupId, us.SuperView.Subviews, dimension, superviewDimension); - - if (_cachedLocation.HasValue) - { - return _cachedLocation.Value; - } - - return 0; - } - - // TODO: PosAlign.CalculateMinDimension is a hack. Need to figure out a better way of doing this. - /// - /// Returns the minimum size a group of views with the same can be. - /// - /// - /// - /// - /// - public static int CalculateMinDimension (int groupId, IList views, Dimension dimension) - { - List dimensionsList = new (); - - // PERF: If this proves a perf issue, consider caching a ref to this list in each item - List viewsInGroup = views.Where ( - v => - { - return dimension switch - { - Dimension.Width when v.X is PosAlign alignX => alignX.GroupId == groupId, - Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId == groupId, - _ => false - }; - }) - .ToList (); - - if (viewsInGroup.Count == 0) - { - return 0; - } - - // PERF: We iterate over viewsInGroup multiple times here. - - // Update the dimensionList with the sizes of the views - for (var index = 0; index < viewsInGroup.Count; index++) - { - View view = viewsInGroup [index]; - - PosAlign? posAlign = dimension == Dimension.Width ? view.X as PosAlign : view.Y as PosAlign; - - if (posAlign is { }) - { - dimensionsList.Add (dimension == Dimension.Width ? view.Frame.Width : view.Frame.Height); - } - } - - // Align - return dimensionsList.Sum (); - } } diff --git a/Terminal.Gui/View/Layout/PosCombine.cs b/Terminal.Gui/View/Layout/PosCombine.cs index 63ae05dde..884bb2704 100644 --- a/Terminal.Gui/View/Layout/PosCombine.cs +++ b/Terminal.Gui/View/Layout/PosCombine.cs @@ -10,27 +10,27 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -/// +/// /// Indicates whether the two positions are added or subtracted. /// -/// The left position. -/// The right position. -public record PosCombine (AddOrSubtract add, Pos left, Pos right) : Pos +/// The left position. +/// The right position. +public record PosCombine (AddOrSubtract Add, Pos Left, Pos Right) : Pos { /// /// Gets whether the two positions are added or subtracted. /// - public AddOrSubtract Add { get; } = add; + public AddOrSubtract Add { get; } = Add; /// /// Gets the left position. /// - public new Pos Left { get; } = left; + public new Pos Left { get; } = Left; /// /// Gets the right position. /// - public new Pos Right { get; } = right; + public new Pos Right { get; } = Right; /// public override string ToString () { return $"Combine({Left}{(Add == AddOrSubtract.Add ? '+' : '-')}{Right})"; } diff --git a/Terminal.Gui/View/Layout/PosFunc.cs b/Terminal.Gui/View/Layout/PosFunc.cs index a46367f34..4b06d180c 100644 --- a/Terminal.Gui/View/Layout/PosFunc.cs +++ b/Terminal.Gui/View/Layout/PosFunc.cs @@ -7,16 +7,16 @@ namespace Terminal.Gui; /// /// /// This is a low-level API that is typically used internally by the layout system. Use the various static -/// methods on the class to create objects instead. +/// methods on the class to create objects instead. /// /// -/// The position. -public record PosFunc (Func pos) : Pos +/// The position. +public record PosFunc (Func Pos) : Pos { /// /// Gets the function that computes the position. /// - public new Func Func { get; } = pos; + public new Func Func { get; } = Pos; /// public override string ToString () { return $"PosFunc({Func ()})"; } diff --git a/Terminal.Gui/View/Layout/PosPercent.cs b/Terminal.Gui/View/Layout/PosPercent.cs index d38b503fe..17b99cb69 100644 --- a/Terminal.Gui/View/Layout/PosPercent.cs +++ b/Terminal.Gui/View/Layout/PosPercent.cs @@ -10,13 +10,13 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -/// -public record PosPercent (int percent) : Pos +/// +public record PosPercent (int Percent) : Pos { /// /// Gets the percentage of the width or height of the SuperView. /// - public new int Percent { get; } = percent; + public new int Percent { get; } = Percent; /// public override string ToString () { return $"Percent({Percent})"; } diff --git a/Terminal.Gui/View/Layout/PosView.cs b/Terminal.Gui/View/Layout/PosView.cs index 13e2981ec..92748d88b 100644 --- a/Terminal.Gui/View/Layout/PosView.cs +++ b/Terminal.Gui/View/Layout/PosView.cs @@ -10,19 +10,19 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -/// The View the position is anchored to. -/// The side of the View the position is anchored to. -public record PosView (View? view, Side side) : Pos +/// The View the position is anchored to. +/// The side of the View the position is anchored to. +public record PosView (View? View, Side Side) : Pos { /// /// Gets the View the position is anchored to. /// - public View? Target { get; } = view; + public View? Target { get; } = View; /// /// Gets the side of the View the position is anchored to. /// - public Side Side { get; } = side; + public Side Side { get; } = Side; /// public override string ToString ()