Browse Source

Enabled EndToStart.

Tig 1 year ago
parent
commit
86139e1f5b

+ 36 - 10
Terminal.Gui/Drawing/Aligner.cs

@@ -82,14 +82,15 @@ public class Aligner : INotifyPropertyChanged
     /// <returns>The positions of the items, from left/top to right/bottom.</returns>
     public static int [] Align (in Alignment alignment, in AlignmentModes alignmentMode, in int containerSize, in int [] sizes)
     {
-        if (alignmentMode.HasFlag (AlignmentModes.EndToStart))
+        if (sizes.Length == 0)
         {
-            throw new NotImplementedException ("EndToStart is not implemented.");
+            return [];
         }
 
-        if (sizes.Length == 0)
+        var sizesCopy = sizes;
+        if (alignmentMode.HasFlag (AlignmentModes.EndToStart))
         {
-            return [];
+            sizesCopy = sizes.Reverse ().ToArray ();
         }
 
         int maxSpaceBetweenItems = alignmentMode.HasFlag (AlignmentModes.AddSpaceBetweenItems) ? 1 : 0;
@@ -113,10 +114,13 @@ public class Aligner : INotifyPropertyChanged
                 switch (alignmentMode & ~AlignmentModes.AddSpaceBetweenItems)
                 {
                     case AlignmentModes.StartToEnd:
-                        return Start (in sizes, maxSpaceBetweenItems, spacesToGive);
+                        return Start (in sizesCopy, maxSpaceBetweenItems, spacesToGive);
 
                     case AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast:
-                        return IgnoreLast (in sizes, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive);
+                        return IgnoreLast (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive);
+
+                    case AlignmentModes.EndToStart:
+                        return End (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive).Reverse ().ToArray ();
                 }
 
                 break;
@@ -125,19 +129,41 @@ public class Aligner : INotifyPropertyChanged
                 switch (alignmentMode & ~AlignmentModes.AddSpaceBetweenItems)
                 {
                     case AlignmentModes.StartToEnd:
-                        return End (in sizes, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive);
+                        return End (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive);
 
                     case AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast:
-                        return IgnoreFirst (in sizes, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive);
+                        return IgnoreFirst (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive);
+
+                    case AlignmentModes.EndToStart:
+                        return Start (in sizesCopy, maxSpaceBetweenItems, spacesToGive).Reverse ().ToArray ();
+
                 }
 
                 break;
 
             case Alignment.Center:
-                return Center (in sizes, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive);
+                switch (alignmentMode & ~AlignmentModes.AddSpaceBetweenItems)
+                {
+                    case AlignmentModes.StartToEnd:
+                        return Center (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive);
+
+                    case AlignmentModes.EndToStart:
+                        return Center (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive).Reverse ().ToArray ();
+                }
+
+                break;
 
             case Alignment.Fill:
-                return Fill (in sizes, containerSize, totalItemsSize);
+                switch (alignmentMode & ~AlignmentModes.AddSpaceBetweenItems)
+                {
+                    case AlignmentModes.StartToEnd:
+                        return Fill (in sizesCopy, containerSize, totalItemsSize);
+
+                    case AlignmentModes.EndToStart:
+                        return Fill (in sizesCopy, containerSize, totalItemsSize).Reverse ().ToArray ();
+                }
+
+                break;
 
             default:
                 throw new ArgumentOutOfRangeException (nameof (alignment), alignment, null);

+ 2 - 0
Terminal.Gui/Drawing/AlignmentModes.cs

@@ -1,3 +1,5 @@
+using Terminal.Gui.Analyzers.Internal.Attributes;
+
 namespace Terminal.Gui;
 
 /// <summary>

+ 42 - 2
UICatalog/Scenarios/PosAlignDemo.cs

@@ -9,9 +9,9 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Layout")]
 public sealed class PosAlignDemo : Scenario
 {
-    private readonly Aligner _horizAligner = new ();
+    private readonly Aligner _horizAligner = new () { AlignmentModes = AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems};
     private int _leftMargin;
-    private readonly Aligner _vertAligner = new ();
+    private readonly Aligner _vertAligner = new () { AlignmentModes = AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems };
     private int _topMargin;
 
     public override void Main ()
@@ -79,6 +79,46 @@ public sealed class PosAlignDemo : Scenario
                                                };
         appWindow.Add (alignRadioGroup);
 
+        CheckBox endToStartCheckBox = new ()
+        {
+            ColorScheme = colorScheme,
+            Text = "EndToStart"
+        };
+
+        if (dimension == Dimension.Width)
+        {
+            endToStartCheckBox.Checked = _horizAligner.AlignmentModes.HasFlag (AlignmentModes.EndToStart);
+            endToStartCheckBox.X = Pos.Align (_horizAligner.Alignment);
+            endToStartCheckBox.Y = Pos.Top (alignRadioGroup);
+        }
+        else
+        {
+            endToStartCheckBox.Checked = _vertAligner.AlignmentModes.HasFlag (AlignmentModes.EndToStart);
+            endToStartCheckBox.X = Pos.Left (alignRadioGroup);
+            endToStartCheckBox.Y = Pos.Align (_vertAligner.Alignment);
+        }
+
+        endToStartCheckBox.Toggled += (s, e) =>
+                                      {
+                                          if (dimension == Dimension.Width)
+                                          {
+                                              _horizAligner.AlignmentModes =
+                                                  e.NewValue is { } && e.NewValue.Value
+                                                      ? _horizAligner.AlignmentModes | AlignmentModes.EndToStart
+                                                      : _horizAligner.AlignmentModes & ~AlignmentModes.EndToStart;
+                                              UpdatePosAlignObjects (appWindow, dimension, _horizAligner);
+                                          }
+                                          else
+                                          {
+                                              _vertAligner.AlignmentModes =
+                                                  e.NewValue is { } && e.NewValue.Value
+                                                      ? _vertAligner.AlignmentModes | AlignmentModes.EndToStart
+                                                      : _vertAligner.AlignmentModes & ~AlignmentModes.EndToStart;
+                                              UpdatePosAlignObjects (appWindow, dimension, _vertAligner);
+                                          }
+                                      };
+        appWindow.Add (endToStartCheckBox);
+
         CheckBox ignoreFirstOrLast = new ()
         {
             ColorScheme = colorScheme,

+ 17 - 0
UnitTests/Drawing/AlignerTests.cs

@@ -70,6 +70,23 @@ public class AlignerTests (ITestOutputHelper output)
                                           }.Align (new [] { 10, 20, -30 }));
     }
 
+    // TODO: This test is woefully inadequate. Expand it to cover more cases.
+    [Theory]
+    [InlineData (Alignment.Start, new [] {9, 7, 4})]
+    [InlineData (Alignment.End, new [] { 5, 3, 0 })]
+    [InlineData (Alignment.Center, new [] { 7, 5, 2 })]
+    [InlineData (Alignment.Fill, new [] { 9, 5, 0 })]
+    public void EndToStart_Reverses (Alignment alignment, int [] expected)
+    {
+        int [] sizes = { 1, 2, 3 };
+        //int [] positions = Aligner.Align (alignment, AlignmentModes.StartToEnd, 10, sizes);
+        //Assert.Equal (new [] { 0, 1, 3 }, positions);
+
+        int [] positions = Aligner.Align (alignment, AlignmentModes.EndToStart, 10, sizes);
+        Assert.Equal (expected, positions);
+
+    }
+
     [Theory]
     [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 0 }, 1, new [] { 0 })]
     [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 0, 0 }, 1, new [] { 0, 1 })]