Browse Source

Aded PosJusityf scenario . fixed issues. WIP

Tig 1 year ago
parent
commit
7fc4f5a55e

+ 14 - 1
Terminal.Gui/Drawing/Justification.cs

@@ -1,3 +1,5 @@
+using static Terminal.Gui.Pos;
+
 namespace Terminal.Gui;
 
 /// <summary>
@@ -105,7 +107,7 @@ public enum Justification
     ///     Set <see cref="Justifier.PutSpaceBetweenItems"/> to <see langword="true"/> to ensure at least one line between
     ///     each item.
     /// </summary>
-    LastBottomRestTop,
+    LastBottomRestTop = LastRightRestLeft,
 }
 
 /// <summary>
@@ -336,4 +338,15 @@ public class Justifier
             throw new ArgumentException ("The size of an item cannot be negative.");
         }
     }
+    public override bool Equals (object other)
+    {
+        if (other is Justifier justifier)
+        {
+            return Justification == justifier.Justification &&
+                   ContainerSize == justifier.ContainerSize &&
+                   PutSpaceBetweenItems == justifier.PutSpaceBetweenItems;
+        }
+
+        return false;
+    }
 }

+ 74 - 11
Terminal.Gui/View/Layout/PosDim.cs

@@ -1,4 +1,5 @@
 using System.Diagnostics;
+using static Terminal.Gui.Dim;
 
 namespace Terminal.Gui;
 
@@ -209,7 +210,7 @@ public class Pos
     /// <param name="views"></param>
     /// <param name="justification"></param>
     /// <returns></returns>
-    public static Pos Justify ( Justification justification) { return new PosJustify (justification); }
+    public static Pos Justify (Justification justification) { return new PosJustify (justification); }
 
     /// <summary>Serves as the default hash function. </summary>
     /// <returns>A hash code for the current object.</returns>
@@ -469,8 +470,74 @@ public class Pos
     /// </summary>
     public class PosJustify : Pos
     {
-        internal readonly Justifier _justifier;
-        internal int? _location;
+        public Justifier Justifier { get; } = new ();
+        public int? _location;
+
+        public int GroupId { get; set; }
+
+        public static void JustifyGroup (int groupId, IList<View> views, Dim.Dimension dimension, int size)
+        {
+            if (views is null)
+            {
+                return;
+            }
+            Justifier firstInGroup = null;
+            List<int> dimensionsList = new ();
+            List<View> viewsInGroup = views.Where (
+                                                   v =>
+                                                   {
+                                                       if (dimension == Dimension.Width && v.X is PosJustify justifyX)
+                                                       {
+                                                           return justifyX.GroupId == groupId;
+                                                       }
+
+                                                       if (dimension == Dimension.Height && v.Y is PosJustify justifyY)
+                                                       {
+                                                           return justifyY.GroupId == groupId;
+                                                       }
+
+                                                       return false;
+                                                   }).ToList ();
+            if (viewsInGroup.Count == 0)
+            {
+                return;
+            }
+
+            foreach (var view in viewsInGroup)
+            {
+                var posJustify = dimension == Dimension.Width ? view.X as PosJustify : view.Y as PosJustify;
+
+                if (posJustify is { })
+                {
+                    if (firstInGroup is null)
+                    {
+                        firstInGroup = posJustify.Justifier;
+                    }
+
+                    dimensionsList.Add (dimension == Dimension.Width ? view.Frame.Width : view.Frame.Height);
+                }
+            }
+
+            if (firstInGroup is null)
+            {
+                return;
+            }
+
+            firstInGroup.ContainerSize = size;
+
+            var locations = firstInGroup.Justify (dimensionsList.ToArray ());
+
+            for (var index = 0; index < viewsInGroup.Count; index++)
+            {
+                View view = viewsInGroup [index];
+                PosJustify justify = dimension == Dimension.Width ? view.X as PosJustify : view.Y as PosJustify;
+
+                if (justify is { })
+                {
+                    justify._location = locations [index];
+                }
+            }
+        }
 
         /// <summary>
         /// Enables justification of a set of views.
@@ -479,24 +546,20 @@ public class Pos
         /// <param name="justification"></param>
         public PosJustify (Justification justification)
         {
-            _justifier = new ()
-            {
-                PutSpaceBetweenItems = false,
-                Justification = justification,
-            };
+            Justifier.Justification = justification;
         }
 
         public override bool Equals (object other)
         {
-            return other is PosJustify justify && justify._justifier == _justifier;
+            return other is PosJustify justify && justify.Justifier.Equals (Justifier);
         }
 
-        public override int GetHashCode () { return _justifier.GetHashCode (); }
+        public override int GetHashCode () { return Justifier.GetHashCode (); }
 
 
         public override string ToString ()
         {
-            return $"Justify(justification={_justifier.Justification})";
+            return $"Justify(justification={Justifier.Justification})";
         }
 
         internal override int Anchor (int width)

+ 5 - 52
Terminal.Gui/View/Layout/ViewLayout.cs

@@ -193,7 +193,7 @@ public partial class View
         get => VerifyIsInitialized (_x, nameof (X));
         set
         {
-            if (Equals (_x, value))
+            if (_x.Equals (value))
             {
                 return;
             }
@@ -232,7 +232,7 @@ public partial class View
         get => VerifyIsInitialized (_y, nameof (Y));
         set
         {
-            if (Equals (_y, value))
+            if (_y.Equals (value))
             {
                 return;
             }
@@ -843,6 +843,9 @@ public partial class View
 
         SetTextFormatterSize ();
 
+        PosJustify.JustifyGroup (0, SuperView?.Subviews, Dim.Dimension.Width, Viewport.Width);
+        PosJustify.JustifyGroup (0, SuperView?.Subviews, Dim.Dimension.Height, Viewport.Height);
+
         // Sort out the dependencies of the X, Y, Width, Height properties
         HashSet<View> nodes = new ();
         HashSet<(View, View)> edges = new ();
@@ -851,56 +854,6 @@ public partial class View
 
         foreach (View v in ordered)
         {
-            var justifyX = v.X as PosJustify;
-            var justifyY = v.Y as PosJustify;
-
-            if (justifyX is { } || justifyY is { })
-            {
-                int xIndex = 0;
-                int yIndex = 0;
-                List<int> XdimensionsList = new ();
-                List<int> 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)
             {

+ 25 - 12
Terminal.Gui/Views/RadioGroup.cs

@@ -80,6 +80,11 @@ public class RadioGroup : View
         HighlightStyle = Gui.HighlightStyle.PressedOutside | Gui.HighlightStyle.Pressed;
 
         MouseClick += RadioGroup_MouseClick;
+
+        // TOOD: Hack - using Text when we should use SubViews
+        Add (_dummyView);
+        Width = Dim.Auto (Dim.DimAutoStyle.Subviews);
+        Height = Dim.Auto (Dim.DimAutoStyle.Subviews);
     }
 
     // TODO: Fix InvertColorsOnPress - only highlight the selected item
@@ -172,7 +177,7 @@ public class RadioGroup : View
                 }
             }
 
-            if (IsInitialized && prevCount != _radioLabels.Count)
+            if (prevCount != _radioLabels.Count)
             {
                 SetWidthHeight (_radioLabels);
             }
@@ -439,21 +444,25 @@ public class RadioGroup : View
         }
     }
 
-    private void RadioGroup_LayoutStarted (object sender, EventArgs e) { SetWidthHeight (_radioLabels); }
+    private void RadioGroup_LayoutStarted (object sender, EventArgs e) { /*SetWidthHeight (_radioLabels);*/ }
     private void SelectItem () { SelectedItem = _cursor; }
 
+    private View _dummyView = new View () {};
     private void SetWidthHeight (List<string> radioLabels)
     {
         switch (_orientation)
         {
             case Orientation.Vertical:
                 Rectangle r = MakeRect (0, 0, radioLabels);
+                // TODO: Hack
+                _dummyView.X = r.Width + +GetAdornmentsThickness ().Horizontal;
+                _dummyView.Y = radioLabels.Count + GetAdornmentsThickness ().Vertical;
 
-                if (IsInitialized)
-                {
-                    Width = r.Width + GetAdornmentsThickness ().Horizontal;
-                    Height = radioLabels.Count + GetAdornmentsThickness ().Vertical;
-                }
+                //if (IsInitialized)
+                //{
+                //    Width = r.Width + GetAdornmentsThickness ().Horizontal;
+                //    Height = radioLabels.Count + GetAdornmentsThickness ().Vertical;
+                //}
 
                 break;
 
@@ -466,11 +475,15 @@ public class RadioGroup : View
                     length += item.length;
                 }
 
-                if (IsInitialized)
-                {
-                    Width = length + GetAdornmentsThickness ().Vertical;
-                    Height = 1 + GetAdornmentsThickness ().Horizontal;
-                }
+                // TODO: Hack
+                _dummyView.X = length + GetAdornmentsThickness ().Horizontal;
+                _dummyView.Y = 1 + GetAdornmentsThickness ().Vertical;
+
+                //if (IsInitialized)
+                //{
+                //    Width = length + GetAdornmentsThickness ().Vertical;
+                //    Height = 1 + GetAdornmentsThickness ().Horizontal;
+                //}
 
                 break;
         }

+ 1 - 73
UICatalog/Scenarios/Generic.cs

@@ -17,82 +17,10 @@ public sealed class MyScenario : Scenario
             Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
         };
 
-        int leftMargin = 0;
-        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);
+        var button = new Button { X = Pos.Center (), Y = Pos.Center (), Text = "Press me!" };
         button.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed the button!", "Ok");
         appWindow.Add (button);
 
-        button = new Button { X = Pos.Justify (just), Y = Pos.Center (), Text = "Two" };
-        button.Margin.Thickness = new Thickness (leftMargin, 0, 0, 0);
-        button.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Two!", "Ok");
-        appWindow.Add (button);
-
-        button = new Button { X = Pos.Justify (just), Y = Pos.Center (), Text = "Three" };
-        button.Margin.Thickness = new Thickness (leftMargin, 0, 0, 0);
-        button.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
-        appWindow.Add (button);
-
-        button = new Button { X = Pos.Justify (just), Y = Pos.Center (), Text = "Four" };
-        button.Margin.Thickness = new Thickness (leftMargin, 0, 0, 0);
-        button.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
-        appWindow.Add (button);
-
-        button = new Button { X = Pos.Justify (just), Y = Pos.Center (), Text = "Five" };
-        button.Margin.Thickness = new Thickness (leftMargin, 0, 0, 0);
-        button.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
-        appWindow.Add (button);
-
-        button = new Button { X = Pos.Justify (just), Y = Pos.Center (), Text = "Six" };
-        button.Margin.Thickness = new Thickness (leftMargin, 0, 0, 0);
-        button.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
-        appWindow.Add (button);
-
-        button = new Button { X = Pos.Justify (just), Y = Pos.Center (), Text = "Seven" };
-        button.Margin.Thickness = new Thickness (leftMargin, 0, 0, 0);
-        button.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
-        appWindow.Add (button);
-
-        button = new Button { X = Pos.Justify (just), Y = Pos.Center (), Text = "Eight" };
-        button.Margin.Thickness = new Thickness (leftMargin, 0, 0, 0);
-        button.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
-        appWindow.Add (button);
-
-        just = Justification.FirstLeftRestRight;
-        var checkbox = new CheckBox { X = 5, Y = Pos.Justify (just), Text = "Check boxes!" };
-        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed the checkbox!", "Ok");
-        appWindow.Add (checkbox);
-
-        checkbox = new CheckBox { X = 5, Y = Pos.Justify (just), Text = "CheckTwo" };
-        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Two!", "Ok");
-        appWindow.Add (checkbox);
-
-        checkbox = new CheckBox { X = 5, Y = Pos.Justify (just), Text = "CheckThree" };
-        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
-        appWindow.Add (checkbox);
-
-        checkbox = new CheckBox { X = 5, Y = Pos.Justify (just), Text = "CheckFour" };
-        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
-        appWindow.Add (checkbox);
-
-        checkbox = new CheckBox { X = 5, Y = Pos.Justify (just), Text = "CheckFive" };
-        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
-        appWindow.Add (checkbox);
-
-        checkbox = new CheckBox { X = 5, Y = Pos.Justify (just), Text = "CheckSix" };
-        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
-        appWindow.Add (checkbox);
-
-        checkbox = new CheckBox { X = 5, Y = Pos.Justify (just), Text = "CheckSeven" };
-        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
-        appWindow.Add (checkbox);
-
-        checkbox = new CheckBox { X = 5, Y = Pos.Justify (just), Text = "CheckEight" };
-        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
-        appWindow.Add (checkbox);
-
         // Run - Start the application.
         Application.Run (appWindow);
         appWindow.Dispose ();

+ 221 - 0
UICatalog/Scenarios/PosJustification.cs

@@ -0,0 +1,221 @@
+using System.Collections.Generic;
+using System;
+using Terminal.Gui;
+using System.Linq;
+using System.Reflection.Emit;
+
+namespace UICatalog.Scenarios;
+
+[ScenarioMetadata ("PosJustification", "Shows off Pos.Justify")]
+[ScenarioCategory ("Layout")]
+public sealed class PosJustification : Scenario
+{
+
+    private Justifier _horizJustifier = new Justifier ();
+    private int _leftMargin = 0;
+
+    public override void Main ()
+    {
+        // Init
+        Application.Init ();
+
+        // Setup - Create a top-level application window and configure it.
+        Window appWindow = new ()
+        {
+            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()} - {GetDescription ()}"
+        };
+
+        SetupHorizontalControls (appWindow);
+
+        var checkbox = new CheckBox { X = 5, Y = Pos.Justify (_horizJustifier.Justification), Text = "Check boxes!" };
+        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed the checkbox!", "Ok");
+        appWindow.Add (checkbox);
+
+        checkbox = new CheckBox { X = 5, Y = Pos.Justify (_horizJustifier.Justification), Text = "CheckTwo" };
+        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Two!", "Ok");
+        appWindow.Add (checkbox);
+
+        checkbox = new CheckBox { X = 5, Y = Pos.Justify (_horizJustifier.Justification), Text = "CheckThree" };
+        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
+        appWindow.Add (checkbox);
+
+        checkbox = new CheckBox { X = 5, Y = Pos.Justify (_horizJustifier.Justification), Text = "CheckFour" };
+        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
+        appWindow.Add (checkbox);
+
+        checkbox = new CheckBox { X = 5, Y = Pos.Justify (_horizJustifier.Justification), Text = "CheckFive" };
+        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
+        appWindow.Add (checkbox);
+
+        checkbox = new CheckBox { X = 5, Y = Pos.Justify (_horizJustifier.Justification), Text = "CheckSix" };
+        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
+        appWindow.Add (checkbox);
+
+        checkbox = new CheckBox { X = 5, Y = Pos.Justify (_horizJustifier.Justification), Text = "CheckSeven" };
+        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
+        appWindow.Add (checkbox);
+
+        checkbox = new CheckBox { X = 5, Y = Pos.Justify (_horizJustifier.Justification), Text = "CheckEight" };
+        checkbox.Accept += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed Three!", "Ok");
+        appWindow.Add (checkbox);
+
+        // Run - Start the application.
+        Application.Run (appWindow);
+        appWindow.Dispose ();
+
+        // Shutdown - Calling Application.Shutdown is required.
+        Application.Shutdown ();
+    }
+
+    private void SetupHorizontalControls (Window appWindow)
+    {
+        ColorScheme colorScheme = Colors.ColorSchemes ["Toplevel"];
+        RadioGroup justification = new ()
+        {
+            X = Pos.Justify (_horizJustifier.Justification),
+            Y = Pos.Center (),
+            RadioLabels = GetUniqueEnumNames<Justification> ().ToArray (),
+            ColorScheme = colorScheme
+        };
+
+        justification.SelectedItemChanged += (s, e) =>
+        {
+            _horizJustifier.Justification = (Justification)Enum.Parse (typeof (Justification), justification.SelectedItem.ToString ());
+            foreach (var view in appWindow.Subviews.Where (v => v.X is Pos.PosJustify))
+            {
+                if (view.X is Pos.PosJustify j)
+                {
+                    var newJust = new Pos.PosJustify (_horizJustifier.Justification)
+                    {
+                        Justifier =
+                        {
+                            PutSpaceBetweenItems = _horizJustifier.PutSpaceBetweenItems
+                        }
+                    };
+                    view.X = newJust;
+                }
+            }
+        };
+        appWindow.Add (justification);
+
+        CheckBox putSpaces = new ()
+        {
+            X = Pos.Justify (_horizJustifier.Justification),
+            Y = Pos.Top (justification),
+            ColorScheme = colorScheme,
+            Text = "Spaces",
+        };
+        putSpaces.Toggled += (s, e) =>
+                             {
+                                 _horizJustifier.PutSpaceBetweenItems = e.NewValue is { } && e.NewValue.Value;
+                                 foreach (var view in appWindow.Subviews.Where (v => v.X is Pos.PosJustify))
+                                 {
+                                     if (view != justification)
+                                     {
+                                         if (view.X is Pos.PosJustify j)
+                                         {
+                                             j.Justifier.PutSpaceBetweenItems = _horizJustifier.PutSpaceBetweenItems;
+                                         }
+
+                                     }
+                                 }
+                             };
+        appWindow.Add (putSpaces);
+
+        CheckBox margin = new ()
+        {
+            X = Pos.Left (putSpaces),
+            Y = Pos.Bottom(putSpaces),
+            ColorScheme = colorScheme,
+            Text = "Margin",
+        };
+        margin.Toggled += (s, e) =>
+        {
+            _leftMargin = e.NewValue is { } && e.NewValue.Value ? 1 : 0;
+            foreach (var view in appWindow.Subviews.Where (v => v.X is Pos.PosJustify))
+            {
+                if (view != justification)
+                {
+                    view.Margin.Thickness = new Thickness (_leftMargin, 0, 0, 0);
+                }
+            }
+        };
+        appWindow.Add (margin);
+
+        var addedViews = new List<Button> ();
+        addedViews.Add (new Button
+        {
+            X = Pos.Justify (_horizJustifier.Justification),
+            Y = Pos.Center (),
+            Text = NumberToWords.Convert (0)
+        });
+
+        var addedViewsUpDown = new Buttons.NumericUpDown<int> ()
+        {
+            X = Pos.Justify (_horizJustifier.Justification),
+            Y = Pos.Top (justification),
+            Height = 3,
+            Width = 9,
+            Title = "Added",
+            ColorScheme = colorScheme,
+            BorderStyle = LineStyle.None,
+            Value = addedViews.Count
+        };
+        addedViewsUpDown.Border.Thickness = new Thickness (0, 1, 0, 0);
+        addedViewsUpDown.ValueChanging += (s, e) =>
+                                            {
+                                                if (e.NewValue < 0)
+                                                {
+                                                    e.Cancel = true;
+
+                                                    return;
+                                                }
+
+                                                // Add or remove buttons
+                                                if (e.NewValue < e.OldValue)
+                                                {
+                                                    // Remove buttons
+                                                    for (int i = e.OldValue - 1; i >= e.NewValue; i--)
+                                                    {
+                                                        var button = addedViews [i];
+                                                        appWindow.Remove (button);
+                                                        addedViews.RemoveAt (i);
+                                                        button.Dispose ();
+                                                    }
+                                                }
+
+                                                if (e.NewValue > e.OldValue)
+                                                {
+                                                    // Add buttons
+                                                    for (int i = e.OldValue; i < e.NewValue; i++)
+                                                    {
+                                                        var button = new Button
+                                                        {
+                                                            X = Pos.Justify (_horizJustifier.Justification),
+                                                            Y = Pos.Center (), 
+                                                            Text = NumberToWords.Convert (i + 1)
+                                                        };
+                                                        appWindow.Add (button);
+                                                        addedViews.Add (button);
+                                                    }
+                                                }
+                                            };
+        appWindow.Add (addedViewsUpDown);
+
+        appWindow.Add (addedViews [0]);
+
+    }
+
+    static IEnumerable<string> GetUniqueEnumNames<T> () where T : Enum
+    {
+        var values = new HashSet<int> ();
+        foreach (var name in Enum.GetNames (typeof (T)))
+        {
+            var value = (int)Enum.Parse (typeof (T), name);
+            if (values.Add (value))
+            {
+                yield return name;
+            }
+        }
+    }
+}