Browse Source

Dim.Auto (Content) is pretty horked. Broke Bar

Tig 1 year ago
parent
commit
9abfb1ae46

+ 66 - 82
Terminal.Gui/View/Layout/DimAuto.cs

@@ -22,6 +22,7 @@ public class DimAuto () : Dim
     /// <summary>
     ///     Gets the maximum dimension the View's ContentSize will be fit to. NOT CURRENTLY SUPPORTED.
     /// </summary>
+
     // ReSharper disable once ConvertToAutoProperty
     public required Dim? MaximumContentDim
     {
@@ -34,6 +35,7 @@ public class DimAuto () : Dim
     /// <summary>
     ///     Gets the minimum dimension the View's ContentSize will be constrained to.
     /// </summary>
+
     // ReSharper disable once ConvertToAutoProperty
     public required Dim? MinimumContentDim
     {
@@ -46,6 +48,7 @@ public class DimAuto () : Dim
     /// <summary>
     ///     Gets the style of the DimAuto.
     /// </summary>
+
     // ReSharper disable once ConvertToAutoProperty
     public required DimAutoStyle Style
     {
@@ -62,7 +65,7 @@ public class DimAuto () : Dim
         var subviewsSize = 0;
 
         int autoMin = MinimumContentDim?.GetAnchor (superviewContentSize) ?? 0;
-        int autoMax = MaximumContentDim?.GetAnchor (superviewContentSize) ?? int.MaxValue;
+        int autoMax = MaximumContentDim?.GetAnchor (superviewContentSize) ?? superviewContentSize;
 
         if (Style.FastHasFlags (DimAutoStyle.Text))
         {
@@ -83,10 +86,11 @@ public class DimAuto () : Dim
                 // TODO: This whole body of code is a WIP (for https://github.com/gui-cs/Terminal.Gui/pull/3451).
                 subviewsSize = 0;
 
-                List<View> includedSubviews = us.Subviews.ToList ();//.Where (v => !v.ExcludeFromLayout).ToList ();
+                List<View> includedSubviews = us.Subviews.ToList (); //.Where (v => !v.ExcludeFromLayout).ToList ();
                 List<View> subviews;
 
                 #region Not Anchored and Are Not Dependent
+
                 // Start with subviews that are not anchored to the end, aligned, or dependent on content size
                 // [x] PosAnchorEnd
                 // [x] PosAlign
@@ -100,19 +104,25 @@ public class DimAuto () : Dim
                 // [ ] DimView
                 if (dimension == Dimension.Width)
                 {
-                    subviews = includedSubviews.Where (v => v.X is not PosAnchorEnd
-                                                           && v.X is not PosAlign
+                    subviews = includedSubviews.Where (
+                                                       v => v.X is not PosAnchorEnd
+                                                            && v.X is not PosAlign
+
                                                             // && v.X is not PosCenter
                                                             && v.Width is not DimAuto
-                                                           && v.Width is not DimFill).ToList ();
+                                                            && v.Width is not DimFill)
+                                               .ToList ();
                 }
                 else
                 {
-                    subviews = includedSubviews.Where (v => v.Y is not PosAnchorEnd
-                                                           && v.Y is not PosAlign
+                    subviews = includedSubviews.Where (
+                                                       v => v.Y is not PosAnchorEnd
+                                                            && v.Y is not PosAlign
+
                                                             // && v.Y is not PosCenter
                                                             && v.Height is not DimAuto
-                                                           && v.Height is not DimFill).ToList ();
+                                                            && v.Height is not DimFill)
+                                               .ToList ();
                 }
 
                 for (var i = 0; i < subviews.Count; i++)
@@ -127,9 +137,11 @@ public class DimAuto () : Dim
                         subviewsSize = size;
                     }
                 }
+
                 #endregion Not Anchored and Are Not Dependent
 
                 #region Anchored
+
                 // Now, handle subviews that are anchored to the end
                 // [x] PosAnchorEnd
                 if (dimension == Dimension.Width)
@@ -142,6 +154,7 @@ public class DimAuto () : Dim
                 }
 
                 int maxAnchorEnd = 0;
+
                 for (var i = 0; i < subviews.Count; i++)
                 {
                     View v = subviews [i];
@@ -149,51 +162,8 @@ public class DimAuto () : Dim
                 }
 
                 subviewsSize += maxAnchorEnd;
-                #endregion Anchored
-
-                #region Aligned
 
-                // Now, handle subviews that are anchored to the end
-                // [x] PosAnchorEnd
-                int maxAlign = 0;
-                if (dimension == Dimension.Width)
-                {
-                    // Use Linq to get a list of distinct GroupIds from the subviews
-                    List<int> groupIds = includedSubviews.Select (v => v.X is PosAlign posAlign ? posAlign.GroupId : -1).Distinct ().ToList ();
-
-                    foreach (var groupId in groupIds)
-                    {
-                        List<int> dimensionsList = new ();
-
-                        // PERF: If this proves a perf issue, consider caching a ref to this list in each item
-                        List<PosAlign?> posAlignsInGroup = includedSubviews.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
-                                };
-                            })
-                            .Select (v => dimension == Dimension.Width ? v.X as PosAlign : v.Y as PosAlign)
-                            .ToList ();
-
-                        if (posAlignsInGroup.Count == 0)
-                        {
-                            continue;
-                        }
-
-                        maxAlign = posAlignsInGroup [0].CalculateMinDimension (groupId, includedSubviews, dimension);
-                    }
-                }
-                else
-                {
-                    subviews = includedSubviews.Where (v => v.Y is PosAlign).ToList ();
-                }
-
-                subviewsSize = int.Max (subviewsSize, maxAlign);
-                #endregion Aligned
+                #endregion Anchored
 
 
                 #region Auto
@@ -208,19 +178,12 @@ public class DimAuto () : Dim
                 }
 
                 int maxAuto = 0;
+
                 for (var i = 0; i < subviews.Count; i++)
                 {
                     View v = subviews [i];
 
-                    //if (dimension == Dimension.Width)
-                    //{
-                    //    v.SetRelativeLayout (new Size (autoMax - subviewsSize, 0));
-                    //}
-                    //else
-                    //{
-                    //    v.SetRelativeLayout (new Size (0, autoMax - subviewsSize));
-                    //}
-                    maxAuto = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
+                    maxAuto = CalculateMinDimension (us, dimension);
 
                     if (maxAuto > subviewsSize)
                     {
@@ -229,32 +192,40 @@ public class DimAuto () : Dim
                     }
                 }
 
-//                subviewsSize += maxAuto;
+                //                subviewsSize += maxAuto;
 
                 #endregion Auto
 
-                //#region Center
-                //// Now, handle subviews that are Centered
-                //if (dimension == Dimension.Width)
-                //{
-                //    subviews = us.Subviews.Where (v => v.X is PosCenter).ToList ();
-                //}
-                //else
-                //{
-                //    subviews = us.Subviews.Where (v => v.Y is PosCenter).ToList ();
-                //}
-
-                //int maxCenter = 0;
-                //for (var i = 0; i < subviews.Count; i++)
-                //{
-                //    View v = subviews [i];
-                //    maxCenter = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
-                //}
-
-                //subviewsSize += maxCenter;
-                //#endregion Center
+                #region Center
+
+                // Now, handle subviews that are Centered
+                if (dimension == Dimension.Width)
+                {
+                    subviews = us.Subviews.Where (v => v.X is PosCenter).ToList ();
+                }
+                else
+                {
+                    subviews = us.Subviews.Where (v => v.Y is PosCenter).ToList ();
+                }
+
+                int maxCenter = 0;
+
+                for (var i = 0; i < subviews.Count; i++)
+                {
+                    View v = subviews [i];
+                    maxCenter = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
+
+                    if (maxCenter > subviewsSize)
+                    {
+                        // BUGBUG: Should we break here? Or choose min/max?
+                        subviewsSize = maxCenter;
+                    }
+                }
+
+                #endregion Center
 
                 #region Are Dependent
+
                 // Now, go back to those that are dependent on content size
                 // [x] DimFill
                 // [ ] DimPercent
@@ -268,6 +239,7 @@ public class DimAuto () : Dim
                 }
 
                 int maxFill = 0;
+
                 for (var i = 0; i < subviews.Count; i++)
                 {
                     View v = subviews [i];
@@ -280,10 +252,12 @@ public class DimAuto () : Dim
                     {
                         v.SetRelativeLayout (new Size (0, autoMax - subviewsSize));
                     }
+
                     maxFill = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
                 }
 
                 subviewsSize += maxFill;
+
                 #endregion Are Dependent
             }
         }
@@ -309,6 +283,16 @@ public class DimAuto () : Dim
         return int.Min (max, autoMax);
     }
 
+    internal int CalculateMinDimension (View us, Dimension dimension)
+    {
+
+
+        int min = dimension == Dimension.Width ? us.Frame.Width : us.Frame.Height;
+
+        return min;
+    }
+
+
     internal override bool ReferencesOtherViews ()
     {
         // BUGBUG: This is not correct. _contentSize may be null.

+ 1 - 0
Terminal.Gui/View/Layout/PosAlign.cs

@@ -198,6 +198,7 @@ public class PosAlign : Pos
         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 { })

+ 67 - 15
Terminal.Gui/Views/Bar.cs

@@ -99,13 +99,45 @@ public class Bar : View
                     }
 
                     barItem.Y = Pos.Center ();
-                    barItem.SetRelativeLayout(new Size(int.MaxValue, int.MaxValue));
+                    barItem.SetRelativeLayout (new Size (int.MaxValue, int.MaxValue));
                     prevBarItem = barItem;
                 }
 
                 break;
 
             case Orientation.Vertical:
+                // CommandView is aligned left, HelpView is aligned right, KeyView is aligned right
+                // All CommandView's are the same width, all HelpView's are the same width,
+                // all KeyView's are the same width
+
+                int maxCommandWidth = 0;
+                int maxHelpWidth = 0;
+
+                List<Shortcut> shortcuts = Subviews.Where (s => s is Shortcut && s.Visible).Cast<Shortcut> ().ToList ();
+
+                foreach (Shortcut shortcut in shortcuts)
+                {
+                    // Let AutoSize do its thing to get the minimum width of each CommandView and HelpView
+                    shortcut.CommandView.SetRelativeLayout (new Size (int.MaxValue, int.MaxValue));
+                    shortcut.KeyView.SetRelativeLayout (new Size (int.MaxValue, int.MaxValue));
+                    shortcut.HelpView.SetRelativeLayout (new Size (int.MaxValue, int.MaxValue));
+                }
+
+                maxCommandWidth = shortcuts.Max (s => s.CommandView.Frame.Width);
+                maxHelpWidth = shortcuts.Max (s => s.HelpView.Frame.Width);
+
+                // Set the width of all CommandView's and HelpView's to the max width
+                foreach (Shortcut shortcut in shortcuts)
+                {
+                    shortcut.CommandView.Width = Dim.Auto (minimumContentDim: maxCommandWidth);
+                    shortcut.KeyView.Width = Dim.Auto ();
+                    shortcut.HelpView.Width = Dim.Auto (minimumContentDim: maxHelpWidth);
+
+                   // shortcut.LayoutSubviews ();
+                }
+
+                // Set the overall size of the Bar and arrange the views vertically
+
                 var maxBarItemWidth = 0;
 
                 for (var index = 0; index < Subviews.Count; index++)
@@ -128,6 +160,7 @@ public class Bar : View
                     }
 
                     prevBarItem = barItem;
+
                     if (barItem is Shortcut shortcut)
                     {
                         //shortcut.SetRelativeLayout (new (int.MaxValue, int.MaxValue));
@@ -137,32 +170,51 @@ public class Bar : View
                     {
                         maxBarItemWidth = Math.Max (maxBarItemWidth, barItem.Frame.Width);
                     }
+
                     barItem.X = 0;
                 }
 
-                for (var index = 0; index < Subviews.Count; index++)
+                foreach (Shortcut shortcut in shortcuts)
                 {
-                    var shortcut = Subviews [index] as Shortcut;
-
-                    if (shortcut is { Visible: false })
-                    {
-                        continue;
-                    }
-
                     if (Width is DimAuto)
                     {
-                        shortcut._container.Width = Dim.Auto (DimAutoStyle.Content, minimumContentDim: maxBarItemWidth);
+                        shortcut.Width = Dim.Auto (DimAutoStyle.Content, minimumContentDim: maxBarItemWidth);
                     }
                     else
                     {
-                        shortcut._container.Width = Dim.Fill ();
-                        shortcut.Width = Dim.Fill ();
+                        //shortcut._container.Width = Dim.Fill ();
+                       // shortcut.Width = Dim.Fill ();
                     }
 
-                    //shortcut.SetContentSize (new (maxBarItemWidth, 1));
-                    //shortcut.Width = Dim.Auto (DimAutoStyle.Content, minimumContentDim: int.Max(maxBarItemWidth, GetContentSize().Width));
-
+                    shortcut.LayoutSubviews ();
                 }
+                
+
+                //for (var index = 0; index < Subviews.Count; index++)
+                //{
+                //    var shortcut = Subviews [index] as Shortcut;
+
+                //    if (shortcut is { Visible: false })
+                //    {
+                //        continue;
+                //    }
+
+                //    if (Width is DimAuto)
+                //    {
+                //        shortcut._container.Width = Dim.Auto (DimAutoStyle.Content, minimumContentDim: maxBarItemWidth);
+                //    }
+                //    else
+                //    {
+                //        shortcut._container.Width = Dim.Fill ();
+                //        shortcut.Width = Dim.Fill ();
+                //    }
+
+                //    //shortcut.SetContentSize (new (maxBarItemWidth, 1));
+                //    //shortcut.Width = Dim.Auto (DimAutoStyle.Content, minimumContentDim: int.Max(maxBarItemWidth, GetContentSize().Width));
+
+                //}
+
+
 
                 break;
         }

+ 10 - 3
Terminal.Gui/Views/Shortcut.cs

@@ -59,7 +59,8 @@ public class Shortcut : View
             // Only the Shortcut (_container) should be able to have focus, not any subviews.
             CanFocus = true,
             Width = Dim.Auto (DimAutoStyle.Content, 1),
-            Height = Dim.Auto (DimAutoStyle.Content, 1)
+            Height = Dim.Auto (DimAutoStyle.Content, 1),
+            BorderStyle = LineStyle.Dashed
         };
 
         CommandView = new ();
@@ -71,8 +72,11 @@ public class Shortcut : View
             CanFocus = false,
             X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast | AlignmentModes.AddSpaceBetweenItems),
             Y = Pos.Center (),
+
+            // Helpview is the only subview that doesn't have a min width
             Width = Dim.Auto (DimAutoStyle.Text),
-            Height = Dim.Auto (DimAutoStyle.Text)
+            Height = Dim.Auto (DimAutoStyle.Text),
+            ColorScheme = Colors.ColorSchemes ["Error"]
         };
         _container.Add (HelpView);
 
@@ -86,8 +90,10 @@ public class Shortcut : View
             CanFocus = false,
             X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast | AlignmentModes.AddSpaceBetweenItems),
             Y = Pos.Center (),
+
+            // Bar will set the width of all KeyViews to the width of the widest KeyView.
             Width = Dim.Auto (DimAutoStyle.Text),
-            Height = Dim.Auto (DimAutoStyle.Text)
+            Height = Dim.Auto (DimAutoStyle.Text),
         };
         _container.Add (KeyView);
 
@@ -259,6 +265,7 @@ public class Shortcut : View
             // Right now, we don't set CanFocus to false here.
             _commandView.CanFocus = false;
 
+            // Bar will set the width of all CommandViews to the width of the widest CommandViews.
             _commandView.Width = Dim.Auto (DimAutoStyle.Text);
             _commandView.Height = Dim.Auto (DimAutoStyle.Text);
             _commandView.X = X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast | AlignmentModes.AddSpaceBetweenItems);

+ 75 - 71
UICatalog/Scenarios/Bars.cs

@@ -40,17 +40,21 @@ public class Bars : Scenario
         };
         Application.Top.Add (eventLog);
 
-        //var shortcut1 = new Shortcut
-        //{
-        //    Title = "_Zigzag",
-        //    Key = Key.Z.WithAlt,
-        //    Text = "Gonna zig zag",
-        //    KeyBindingScope = KeyBindingScope.HotKey,
-        //    Command = Command.Accept,
-        //    X = 10,// Pos.Center (),
-        //    Y = 10,//Pos.Center ()
-        //    //Width = Dim.Auto(DimAutoStyle.Content, minimumContentDim: 50),
-        //};
+        var shortcut1 = new Shortcut
+        {
+            Title = "_Zigzag",
+            Key = Key.Z.WithAlt,
+            Text = "Gonna zig zag",
+            KeyBindingScope = KeyBindingScope.HotKey,
+            Command = Command.Accept,
+        };
+        shortcut1.Accept += (s, e) =>
+                            {
+                                eventSource.Add ($"Accept: {s}");
+                                eventLog.MoveDown ();
+                            };
+        Application.Top.Add (shortcut1);
+        shortcut1.SetFocus ();
 
         //var shortcut2 = new Shortcut
         //{
@@ -64,74 +68,74 @@ public class Bars : Scenario
         //    //Width = 50,
         //};
 
-        //Application.Top.Add (shortcut1, shortcut2);
-        //shortcut1.SetFocus ();
 
-        var shortcut3 = new Shortcut
-        {
-            Title = "Shortcut3",
-            Key = Key.D3.WithCtrl,
-            Text = "Number Three",
-            KeyBindingScope = KeyBindingScope.Application,
-            Command = Command.Accept,
-        };
-
-        shortcut3.Accept += (s, e) =>
-                            {
-                                eventSource.Add ($"Accept: {s}");
-                                eventLog.MoveDown ();
-                            };
+        //var shortcut3 = new Shortcut
+        //{
+        //    Title = "Shortcut3",
+        //    Key = Key.D3.WithCtrl,
+        //    Text = "Number Three",
+        //    KeyBindingScope = KeyBindingScope.Application,
+        //    Command = Command.Accept,
+        //};
 
-        var shortcut4 = new Shortcut
-        {
-            Title = "Shortcut4",
-            Text = "Number 4",
-            Key = Key.F4,
-            KeyBindingScope = KeyBindingScope.Application,
-            Command = Command.Accept,
-        };
+        //shortcut3.Accept += (s, e) =>
+        //                    {
+        //                        eventSource.Add ($"Accept: {s}");
+        //                        eventLog.MoveDown ();
+        //                    };
 
-        var cb = new CheckBox ()
-        {
-            Title = "Hello",// shortcut4.Text
-        };
+        //var shortcut4 = new Shortcut
+        //{
+        //    Title = "Shortcut4",
+        //    Text = "Number 4",
+        //    Key = Key.F4,
+        //    KeyBindingScope = KeyBindingScope.Application,
+        //    Command = Command.Accept,
+        //};
 
-        cb.Toggled += (s, e) =>
-                     {
-                         eventSource.Add ($"Toggled: {s}");
-                         eventLog.MoveDown ();
-                     };
+        //var cb = new CheckBox ()
+        //{
+        //    Title = "Hello",// shortcut4.Text
+        //};
 
-        shortcut4.CommandView = cb;
+        //cb.Toggled += (s, e) =>
+        //             {
+        //                 eventSource.Add ($"Toggled: {s}");
+        //                 eventLog.MoveDown ();
+        //             };
 
-        shortcut4.Accept += (s, e) =>
-                            {
-                                eventSource.Add ($"Accept: {s}");
-                                eventLog.MoveDown ();
-                            };
+        //shortcut4.CommandView = cb;
 
-        var bar = new Bar
-        {
-            X = 2,
-            Y = 2,
-            Orientation = Orientation.Vertical,
-            StatusBarStyle = false,
-            Width = Dim.Percent(40)
-        };
-        bar.Add (shortcut3, shortcut4);
+        //shortcut4.Accept += (s, e) =>
+        //                    {
+        //                        eventSource.Add ($"Accept: {s}");
+        //                        eventLog.MoveDown ();
+        //                    };
 
-        CheckBox hello = new ()
-        {
-            Title = "Hello",
-        };
-        Application.Top.Add (hello);
-        hello.Toggled += (s, e) =>
-                         {
-                             eventSource.Add ($"Toggled: {s}");
-                             eventLog.MoveDown ();
-                         };
-
-        Application.Top.Add (bar);
+        //var bar = new Bar
+        //{
+        //    X = 2,
+        //    Y = Pos.Bottom(shortcut1),
+        //    Orientation = Orientation.Vertical,
+        //    StatusBarStyle = false,
+        //    Width = Dim.Percent(40)
+        //};
+        //bar.Add (shortcut3, shortcut4);
+
+        ////CheckBox hello = new ()
+        ////{
+        ////    Title = "Hello",
+        ////    X = 0,
+        ////    Y = 1,
+        ////};
+        ////Application.Top.Add (hello);
+        ////hello.Toggled += (s, e) =>
+        ////                 {
+        ////                     eventSource.Add ($"Toggled: {s}");
+        ////                     eventLog.MoveDown ();
+        ////                 };
+
+        //Application.Top.Add (bar);
 
         // BUGBUG: This should not be needed
         //Application.Top.LayoutSubviews ();