diff --git a/Terminal.Gui/Drawing/Justification.cs b/Terminal.Gui/Drawing/Justification.cs
index e9a9bdbf9..16c76c372 100644
--- a/Terminal.Gui/Drawing/Justification.cs
+++ b/Terminal.Gui/Drawing/Justification.cs
@@ -85,17 +85,31 @@ public enum Justification
///
public class Justifier
{
- private int _maxSpaceBetweenItems;
+ ///
+ /// Gets or sets how the justifies items within a container.
+ ///
+ public Justification Justification { get; set; }
+
+ ///
+ /// The size of the container.
+ ///
+ public int ContainerSize { get; set; }
///
/// Gets or sets whether puts a space is placed between items. Default is . If , a space will be
- /// placed between each item, which is useful for
- /// justifying text.
+ /// placed between each item, which is useful for justifying text.
///
- public bool PutSpaceBetweenItems
+ public bool PutSpaceBetweenItems { get; set; }
+
+ ///
+ /// Takes a list of items and returns their positions when justified within a container wide based on the specified
+ /// .
+ ///
+ /// The sizes of the items to justify.
+ /// The locations of the items, from left to right.
+ public int [] Justify (int [] sizes)
{
- get => _maxSpaceBetweenItems == 1;
- set => _maxSpaceBetweenItems = value ? 1 : 0;
+ return Justify (Justification, PutSpaceBetweenItems, ContainerSize, sizes);
}
///
@@ -104,28 +118,23 @@ public class Justifier
///
/// The sizes of the items to justify.
/// The justification style.
- /// The width of the container.
+ /// The size of the container.
/// The locations of the items, from left to right.
- public int [] Justify (int [] sizes, Justification justification, int containerSize)
+ public static int [] Justify (Justification justification, bool putSpaceBetweenItems, int containerSize, int [] sizes)
{
if (sizes.Length == 0)
{
return new int [] { };
}
+ int maxSpaceBetweenItems = putSpaceBetweenItems ? 1 : 0;
+
+ var positions = new int [sizes.Length]; // positions of the items. the return value.
int totalItemsSize = sizes.Sum ();
+ int totalGaps = sizes.Length - 1; // total gaps between items
+ int totalItemsAndSpaces = totalItemsSize + totalGaps * maxSpaceBetweenItems; // total size of items and spaces if we had enough room
- if (totalItemsSize > containerSize)
- {
- // throw new ArgumentException ("The sum of the sizes is greater than the total size.");
- }
-
- var positions = new int [sizes.Length];
- totalItemsSize = sizes.Sum (); // total size of items
- int totalGaps = sizes.Length - 1; // total gaps (MinimumSpaceBetweenItems)
- int totalItemsAndSpaces = totalItemsSize + totalGaps * _maxSpaceBetweenItems; // total size of items and spaces if we had enough room
- int spaces = totalGaps * _maxSpaceBetweenItems; // We'll decrement this below to place one space between each item until we run out
-
+ int spaces = totalGaps * maxSpaceBetweenItems; // We'll decrement this below to place one space between each item until we run out
if (totalItemsSize >= containerSize)
{
spaces = 0;
@@ -154,7 +163,7 @@ public class Justifier
continue;
}
- int spaceBefore = spaces-- > 0 ? _maxSpaceBetweenItems : 0;
+ int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
// subsequent items are placed one space after the previous item
positions [i] = positions [i - 1] + sizes [i - 1] + spaceBefore;
@@ -171,7 +180,7 @@ public class Justifier
throw new ArgumentException ("The size of an item cannot be negative.");
}
- int spaceBefore = spaces-- > 0 ? _maxSpaceBetweenItems : 0;
+ int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
positions [i] = currentPosition;
currentPosition += sizes [i] + spaceBefore;
@@ -199,7 +208,7 @@ public class Justifier
continue;
}
- int spaceBefore = spaces-- > 0 ? _maxSpaceBetweenItems : 0;
+ int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
// subsequent items are placed one space after the previous item
positions [i] = positions [i - 1] + sizes [i - 1] + spaceBefore;
@@ -251,7 +260,7 @@ public class Justifier
if (i < sizes.Length - 1)
{
- int spaceBefore = spaces-- > 0 ? _maxSpaceBetweenItems : 0;
+ int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
positions [i] = currentPosition;
currentPosition += sizes [i] + spaceBefore;
@@ -295,7 +304,7 @@ public class Justifier
if (i < sizes.Length - 1 && i > 0)
{
- int spaceBefore = spaces-- > 0 ? _maxSpaceBetweenItems : 0;
+ int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
positions [i] = currentPosition - sizes [i] - spaceBefore;
currentPosition = positions [i];
diff --git a/Terminal.Gui/View/Layout/PosDim.cs b/Terminal.Gui/View/Layout/PosDim.cs
index 5e1b2a58b..37e8580df 100644
--- a/Terminal.Gui/View/Layout/PosDim.cs
+++ b/Terminal.Gui/View/Layout/PosDim.cs
@@ -469,7 +469,8 @@ public class Pos
///
public class PosJustify : Pos
{
- private readonly Justification _justification;
+ internal readonly Justifier _justifier;
+ internal int? _location;
///
/// Enables justification of a set of views.
@@ -478,81 +479,39 @@ public class Pos
///
public PosJustify (Justification justification)
{
- _justification = justification;
+ _justifier = new ()
+ {
+ PutSpaceBetweenItems = false,
+ Justification = justification,
+ };
}
public override bool Equals (object other)
{
- return other is PosJustify justify && justify._justification == _justification;
+ return other is PosJustify justify && justify._justifier == _justifier;
}
- public override int GetHashCode () { return _justification.GetHashCode (); }
+ public override int GetHashCode () { return _justifier.GetHashCode (); }
public override string ToString ()
{
- return $"Justify(alignment={_justification})";
+ return $"Justify(justification={_justifier.Justification})";
}
internal override int Anchor (int width)
{
- return width;
+ return _location ?? 0 - width;
}
internal override int Calculate (int superviewDimension, Dim dim, View us, Dim.Dimension dimension)
{
- if (us.SuperView is null)
+ if (_location.HasValue)
{
- return 0;
- }
- // Find all the views that are being justified - they have the same justification and opposite position as us
- // Then, pass the array of views to the Justify method
- int [] dimensions;
- int [] positions;
-
- int ourIndex = 0;
- if (dimension == Dim.Dimension.Width)
- {
- List dimensionsList = new List ();
- for (int i = 0; i < us.SuperView.Subviews.Count; i++)
- {
- var v = us.SuperView.Subviews [i];
- var j = v.X as PosJustify;
- if (j?._justification == _justification && v.Frame.Y == us.Frame.Y)
- {
- dimensionsList.Add (v.Frame.Width);
-
- if (v == us)
- {
- ourIndex = dimensionsList.Count - 1;
- }
- }
- }
- dimensions = dimensionsList.ToArray ();
- positions = new Justifier () { PutSpaceBetweenItems = true }.Justify (dimensions, _justification, superviewDimension);
- }
- else
- {
- List dimensionsList = new List ();
- for (int i = 0; i < us.SuperView.Subviews.Count; i++)
- {
- var v = us.SuperView.Subviews [i];
- var j = v.Y as PosJustify;
- if (j?._justification == _justification && v.Frame.X == us.Frame.X)
- {
- dimensionsList.Add (v.Frame.Height);
-
- if (v == us)
- {
- ourIndex = dimensionsList.Count - 1;
- }
- }
- }
- dimensions = dimensionsList.ToArray ();
- positions = new Justifier () { PutSpaceBetweenItems = false }.Justify (dimensions, _justification, superviewDimension);
+ return _location.Value;
}
- return positions [ourIndex];
+ return 0;
}
}
diff --git a/Terminal.Gui/View/Layout/ViewLayout.cs b/Terminal.Gui/View/Layout/ViewLayout.cs
index e112100bc..877d07bfb 100644
--- a/Terminal.Gui/View/Layout/ViewLayout.cs
+++ b/Terminal.Gui/View/Layout/ViewLayout.cs
@@ -1,4 +1,5 @@
using System.Diagnostics;
+using static Terminal.Gui.Pos;
namespace Terminal.Gui;
@@ -850,13 +851,62 @@ public partial class View
foreach (View v in ordered)
{
- // TODO: Move this logic into the Pos/Dim classes
+ var justifyX = v.X as PosJustify;
+ var justifyY = v.Y as PosJustify;
+ if (justifyX is { } || justifyY is { })
+ {
+ int xIndex = 0;
+ int yIndex = 0;
+ List XdimensionsList = new ();
+ List YdimensionsList = new ();
+ for (int i = 0; i < v.SuperView.Subviews.Count; i++)
+ {
+ var viewI = v.SuperView.Subviews [i];
+
+ var jX = viewI.X as PosJustify;
+ var jY = viewI.Y as PosJustify;
+
+ if (jX?._justifier.Justification == justifyX?._justifier.Justification && viewI.Frame.Y == v.Frame.Y)
+ {
+ XdimensionsList.Add (viewI.Frame.Width);
+
+ if (viewI == v)
+ {
+ xIndex = XdimensionsList.Count - 1;
+ }
+ }
+
+ if (jY?._justifier.Justification == justifyY?._justifier.Justification && viewI.Frame.X == v.Frame.X)
+ {
+ YdimensionsList.Add (viewI.Frame.Height);
+
+ if (viewI == v)
+ {
+ yIndex = YdimensionsList.Count - 1;
+ }
+ }
+ }
+
+ if (justifyX is { })
+ {
+ justifyX._justifier.ContainerSize = Viewport.Size.Width;
+ justifyX._location = justifyX._justifier.Justify (XdimensionsList.ToArray ()) [xIndex];
+ }
+
+ if (justifyY is { })
+ {
+ justifyY._justifier.ContainerSize = Viewport.Size.Height;
+ justifyY._location = justifyY._justifier.Justify (YdimensionsList.ToArray ()) [yIndex];
+ }
+ }
+
+ // TODO: Move this logic into the Pos/Dim classes
if (v.Width is Dim.DimAuto || v.Height is Dim.DimAuto)
{
// If the view is auto-sized...
Rectangle f = v.Frame;
- v._frame = new (v.Frame.X, v.Frame.Y, 0, 0);
+ v._frame = v.Frame with { Width = 0, Height = 0 };
LayoutSubview (v, Viewport.Size);
if (v.Frame != f)
@@ -1005,8 +1055,8 @@ public partial class View
{
//if (AutoSize)
{
- // SetFrameToFitText ();
- SetTextFormatterSize ();
+ // SetFrameToFitText ();
+ SetTextFormatterSize ();
}
LayoutAdornments ();
@@ -1064,15 +1114,6 @@ public partial class View
CheckDimAuto ();
- SetTextFormatterSize ();
-
- var autoSize = Size.Empty;
-
- //if (AutoSize)
- //{
- // // TODO: Nuke this from orbit once Dim.Auto is fully implemented
- // autoSize = GetTextAutoSize ();
- //}
SetTextFormatterSize ();
if (TextFormatter.NeedsFormat)
{
diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs
index 15a30def0..dc10b4397 100644
--- a/Terminal.Gui/Views/Button.cs
+++ b/Terminal.Gui/Views/Button.cs
@@ -45,7 +45,7 @@ public class Button : View
_leftDefault = Glyphs.LeftDefaultIndicator;
_rightDefault = Glyphs.RightDefaultIndicator;
- Height = 1;
+ Height = Dim.Auto (Dim.DimAutoStyle.Text);
Width = Dim.Auto (Dim.DimAutoStyle.Text);
CanFocus = true;
diff --git a/UICatalog/Scenarios/Generic.cs b/UICatalog/Scenarios/Generic.cs
index ca5ee4d35..b4da21031 100644
--- a/UICatalog/Scenarios/Generic.cs
+++ b/UICatalog/Scenarios/Generic.cs
@@ -18,9 +18,10 @@ public sealed class MyScenario : Scenario
};
int leftMargin = 0;
- var just = Justification.Justified;
+ var just = Justification.Centered;
var button = new Button { X = Pos.Justify(just), Y = Pos.Center (), Text = "Press me!" };
+ //button.Margin.Thickness = new Thickness (leftMargin, 0, 0, 0);
button.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed the button!", "Ok");
appWindow.Add (button);
diff --git a/UnitTests/Drawing/JustifierTests.cs b/UnitTests/Drawing/JustifierTests.cs
index 3f0a08188..2f98ec430 100644
--- a/UnitTests/Drawing/JustifierTests.cs
+++ b/UnitTests/Drawing/JustifierTests.cs
@@ -19,26 +19,30 @@ public class JustifierTests (ITestOutputHelper output)
[MemberData (nameof (JustificationEnumValues))]
public void NoItems_Works (Justification justification)
{
- int [] sizes = { };
- int [] positions = new Justifier ().Justify (sizes, justification, 100);
+ int [] sizes = [];
+ int [] positions = Justifier.Justify (justification, false, 100, sizes);
Assert.Equal (new int [] { }, positions);
}
- //[Theory]
- //[MemberData (nameof (JustificationEnumValues))]
- //public void Items_Width_Cannot_Exceed_TotalSize (Justification justification)
- //{
- // int [] sizes = { 1000, 2000, 3000 };
- // Assert.Throws (() => new Justifier ().Justify (sizes, justification, 100));
- //}
-
[Theory]
[MemberData (nameof (JustificationEnumValues))]
public void Negative_Widths_Not_Allowed (Justification justification)
{
- Assert.Throws (() => new Justifier ().Justify (new [] { -10, 20, 30 }, justification, 100));
- Assert.Throws (() => new Justifier ().Justify (new [] { 10, -20, 30 }, justification, 100));
- Assert.Throws (() => new Justifier ().Justify (new [] { 10, 20, -30 }, justification, 100));
+ Assert.Throws (() => new Justifier ()
+ {
+ Justification = justification,
+ ContainerSize = 100
+ }.Justify (new [] { -10, 20, 30 }));
+ Assert.Throws (() => new Justifier ()
+ {
+ Justification = justification,
+ ContainerSize = 100
+ }.Justify (new [] { 10, -20, 30 }));
+ Assert.Throws (() => new Justifier ()
+ {
+ Justification = justification,
+ ContainerSize = 100
+ }.Justify (new [] { 10, 20, -30 }));
}
[Theory]
@@ -197,10 +201,15 @@ public class JustifierTests (ITestOutputHelper output)
[InlineData (Justification.FirstLeftRestRight, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 10, 30, 60, 101 })]
[InlineData (Justification.FirstLeftRestRight, new [] { 3, 3, 3 }, 21, new [] { 0, 14, 18 })]
[InlineData (Justification.FirstLeftRestRight, new [] { 3, 4, 5 }, 21, new [] { 0, 11, 16 })]
- public void TestJustifications_PutSpaceBetweenItems (Justification justification, int [] sizes, int totalSize, int [] expected)
+ public void TestJustifications_PutSpaceBetweenItems (Justification justification, int [] sizes, int containerSize, int [] expected)
{
- int [] positions = new Justifier { PutSpaceBetweenItems = true }.Justify (sizes, justification, totalSize);
- AssertJustification (justification, sizes, totalSize, positions, expected);
+ int [] positions = new Justifier
+ {
+ PutSpaceBetweenItems = true,
+ Justification = justification,
+ ContainerSize = containerSize
+ }.Justify (sizes);
+ AssertJustification (justification, sizes, containerSize, positions, expected);
}
[Theory]
@@ -341,10 +350,15 @@ public class JustifierTests (ITestOutputHelper output)
[InlineData (Justification.FirstLeftRestRight, new [] { 10, 20, 30 }, 101, new [] { 0, 51, 71 })]
[InlineData (Justification.FirstLeftRestRight, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
[InlineData (Justification.FirstLeftRestRight, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
- public void TestJustifications_NoSpaceBetweenItems (Justification justification, int [] sizes, int totalSize, int [] expected)
+ public void TestJustifications_NoSpaceBetweenItems (Justification justification, int [] sizes, int containerSize, int [] expected)
{
- int [] positions = new Justifier { PutSpaceBetweenItems = false }.Justify (sizes, justification, totalSize);
- AssertJustification (justification, sizes, totalSize, positions, expected);
+ int [] positions = new Justifier
+ {
+ PutSpaceBetweenItems = false,
+ Justification = justification,
+ ContainerSize = containerSize
+ }.Justify (sizes);
+ AssertJustification (justification, sizes, containerSize, positions, expected);
}
public void AssertJustification (Justification justification, int [] sizes, int totalSize, int [] positions, int [] expected)