瀏覽代碼

Progress. WIP

Tig 1 年之前
父節點
當前提交
78ab7ecec1

+ 26 - 2
Terminal.Gui/View/Layout/Dim.cs

@@ -175,6 +175,30 @@ public abstract class Dim
 
     #endregion static Dim creation methods
 
+    /// <summary>
+    ///     Indicates whether the specified type is in the hierarchy of this Dim object.
+    /// </summary>
+    /// <param name="type"></param>
+    /// <param name="dim"></param>
+    /// <returns></returns>
+    public bool Has (Type type, out Dim dim)
+    {
+        dim = this;
+        if (type == GetType ())
+        {
+            return true;
+        }
+
+        // If we are a PosCombine, we have to check the left and right
+        // to see if they are of the type we are looking for.
+        if (this is DimCombine { } combine && (combine.Left.Has (type, out dim) || combine.Right.Has (type, out dim)))
+        {
+            return true;
+        }
+
+        return false;
+    }
+
     #region virtual methods
 
     /// <summary>
@@ -224,7 +248,7 @@ public abstract class Dim
     /// <param name="left">The first <see cref="Dim"/> to add.</param>
     /// <param name="right">The second <see cref="Dim"/> to add.</param>
     /// <returns>The <see cref="Dim"/> that is the sum of the values of <c>left</c> and <c>right</c>.</returns>
-    public static Dim operator + (Dim? left, Dim? right)
+    public static Dim operator + (Dim left, Dim right)
     {
         if (left is DimAbsolute && right is DimAbsolute)
         {
@@ -249,7 +273,7 @@ public abstract class Dim
     /// <param name="left">The <see cref="Dim"/> to subtract from (the minuend).</param>
     /// <param name="right">The <see cref="Dim"/> to subtract (the subtrahend).</param>
     /// <returns>The <see cref="Dim"/> that is the <c>left</c> minus <c>right</c>.</returns>
-    public static Dim operator - (Dim? left, Dim? right)
+    public static Dim operator - (Dim left, Dim right)
     {
         if (left is DimAbsolute && right is DimAbsolute)
         {

+ 440 - 158
Terminal.Gui/View/Layout/DimAuto.cs

@@ -59,242 +59,507 @@ public class DimAuto () : Dim
     internal override int Calculate (int location, int superviewContentSize, View us, Dimension dimension)
     {
         var textSize = 0;
-        var subviewsSize = 0;
+        var maxCalculatedSize = 0;
 
         int autoMin = MinimumContentDim?.GetAnchor (superviewContentSize) ?? 0;
-        int autoMax = MaximumContentDim?.GetAnchor (superviewContentSize) ?? int.MaxValue;
+        int autoMax = MaximumContentDim?.GetAnchor (superviewContentSize) ?? (dimension == Dimension.Width ? Application.Driver.Screen.Width : Application.Driver.Screen.Height);
 
         if (Style.FastHasFlags (DimAutoStyle.Text))
         {
-            textSize = int.Max (autoMin, dimension == Dimension.Width ? us.TextFormatter.Size.Width : us.TextFormatter.Size.Height);
+            if (dimension == Dimension.Width)
+            {
+                //us.TextFormatter.Size = us.GetContentSize ();
+                textSize = int.Max (autoMin, us.TextFormatter.FormatAndGetSize ().Width);
+            }
+            else
+            {
+                us.TextFormatter.Size = us.GetContentSize () with { Height = Application.Driver.Screen.Height };
+                textSize = int.Max (autoMin, us.TextFormatter.FormatAndGetSize ().Height);
+            }
         }
 
         if (Style.FastHasFlags (DimAutoStyle.Content))
         {
             if (!us.ContentSizeTracksViewport)
             {
-                // ContentSize was explicitly set. Ignore subviews.
-                subviewsSize = dimension == Dimension.Width ? us.GetContentSize ().Width : us.GetContentSize ().Height;
+                // ContentSize was explicitly set. Use `us.ContentSize` to determine size.
+                maxCalculatedSize = dimension == Dimension.Width ? us.GetContentSize ().Width : us.GetContentSize ().Height;
             }
             else
             {
-                // ContentSize was NOT explicitly set. Use subviews to determine size.
-
-                // 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> 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
-                // [ ] PosCenter
-                // [ ] PosPercent
-                // [ ] PosView
-                // [ ] PosFunc
-                // [x] DimFill
-                // [ ] DimPercent
-                // [ ] DimFunc
-                // [ ] DimView
+                maxCalculatedSize = textSize;
+                // ContentSize was NOT explicitly set. Use `us.Subviews` to determine size.
+
+                List<View> includedSubviews = us.Subviews.ToList ();
+
+                // If [x] it can cause `us.ContentSize` to change.
+                // If [ ] it doesn't need special processing for us to determine `us.ContentSize`.
+
+                // -------------------- Pos types that are dependent on `us.Subviews`
+                // [ ] PosAlign     - Position is dependent on other views with `GroupId` AND `us.ContentSize`
+                // [x] PosView      - Position is dependent on `subview.Target` - it can cause a change in `us.ContentSize`
+                // [x] PosCombine   - Position is dependent if `Pos.Has ([one of the above]` - it can cause a change in `us.ContentSize`
+
+                // -------------------- Pos types that are dependent on `us.ContentSize`
+                // [ ] PosAlign     - Position is dependent on other views with `GroupId` AND `us.ContentSize`
+                // [x] PosAnchorEnd - Position is dependent on `us.ContentSize` AND `subview.Frame` - it can cause a change in `us.ContentSize`
+                // [ ] PosCenter    - Position is dependent `us.ContentSize` AND `subview.Frame`
+                // [ ] PosPercent   - Position is dependent `us.ContentSize`
+                // [x] PosCombine   - Position is dependent if `Pos.Has ([one of the above]` - it can cause a change in `us.ContentSize`
+
+                // -------------------- Pos types that are not dependent on either `us.Subviews` or `us.ContentSize`
+                // [ ] PosAbsolute  - Position is fixed.
+                // [ ] PosFunc      - Position is internally calculated.
+
+                // -------------------- Dim types that are dependent on `us.Subviews`
+                // [x] DimView      - Dimension is dependent on `subview.Target`
+                // [x] DimCombine   - Dimension is dependent if `Dim.Has ([one of the above]` - it can cause a change in `us.ContentSize`
+
+                // -------------------- Dim types that are dependent on `us.ContentSize`
+                // [ ] DimFill      - Dimension is dependent on `us.ContentSize`
+                // [ ] DimPercent   - Dimension is dependent on `us.ContentSize`
+                // [ ] DimCombine   - Dimension is dependent if `Dim.Has ([one of the above]`
+
+                // -------------------- Dim types that are not dependent on either `us.Subviews` or `us.ContentSize`
+                // [ ] DimAuto      - Dimension is internally calculated
+                // [ ] DimAbsolute  - Dimension is fixed
+                // [ ] DimFunc      - Dimension is internally calculated
+
+                // ======================================================
+                // Do the easy stuff first - subviews whose position and size are not dependent on other views or content size
+                // ======================================================
+                // [ ] PosAbsolute  - Position is fixed.
+                // [ ] PosFunc      - Position is internally calculated
+                // [ ] DimAuto      - Dimension is internally calculated
+                // [ ] DimAbsolute  - Dimension is fixed
+                // [ ] DimFunc      - Dimension is internally calculated
+                List<View> notDependentSubViews;
                 if (dimension == Dimension.Width)
                 {
-                    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 ();
+                    notDependentSubViews = includedSubviews.Where (v => v.Width is { } &&
+                                                                        (v.X is PosAbsolute or PosFunc || v.Width is DimAuto or DimAbsolute or DimFunc) &&
+                                                                        !v.X.Has (typeof (PosAnchorEnd), out _) &&
+                                                                        !v.X.Has (typeof (PosAlign), out _) &&
+                                                                        !v.X.Has (typeof (PosView), out _) &&
+                                                                        !v.Width.Has (typeof (DimView), out _) &&
+                                                                        !v.X.Has (typeof (PosCenter), out _)).ToList ();
                 }
                 else
                 {
-                    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 ();
+                    notDependentSubViews = includedSubviews.Where (v => v.Height is { } &&
+                                                                        (v.Y is PosAbsolute or PosFunc || v.Height is DimAuto or DimAbsolute or DimFunc) &&
+                                                                        !v.Y.Has (typeof (PosAnchorEnd), out _) &&
+                                                                        !v.Y.Has (typeof (PosAlign), out _) &&
+                                                                        !v.Y.Has (typeof (PosView), out _) &&
+                                                                        !v.Height.Has (typeof (DimView), out _) &&
+                                                                        !v.Y.Has (typeof (PosCenter), out _)).ToList ();
                 }
 
-                for (var i = 0; i < subviews.Count; i++)
+                for (var i = 0; i < notDependentSubViews.Count; i++)
                 {
-                    View v = subviews [i];
+                    View v = notDependentSubViews [i];
 
-                    int size = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
+                    int size = dimension == Dimension.Width ? v.X.GetAnchor (maxCalculatedSize) + v.Width.GetAnchor (maxCalculatedSize) : v.Y.GetAnchor (maxCalculatedSize) + v.Height.GetAnchor (maxCalculatedSize);
 
-                    if (size > subviewsSize)
+                    if (size > maxCalculatedSize)
                     {
-                        // BUGBUG: Should we break here? Or choose min/max?
-                        subviewsSize = size;
+                        maxCalculatedSize = size;
                     }
                 }
-                #endregion Not Anchored and Are Not Dependent
 
-                #region Anchored
-                // Now, handle subviews that are anchored to the end
-                // [x] PosAnchorEnd
+                // ************** We now have some idea of `us.ContentSize` ***************
+
+
+                // [ ] PosCenter    - Position is dependent `us.ContentSize` AND `subview.Frame`
+                List<View> centeredSubViews;
                 if (dimension == Dimension.Width)
                 {
-                    subviews = includedSubviews.Where (v => v.X is PosAnchorEnd).ToList ();
+                    centeredSubViews = us.Subviews.Where (v => v.X.Has (typeof (PosCenter), out _)).ToList ();
                 }
                 else
                 {
-                    subviews = includedSubviews.Where (v => v.Y is PosAnchorEnd).ToList ();
+                    centeredSubViews = us.Subviews.Where (v => v.Y.Has (typeof (PosCenter), out _)).ToList ();
                 }
 
-                int maxAnchorEnd = 0;
-                for (var i = 0; i < subviews.Count; i++)
+                for (var i = 0; i < centeredSubViews.Count; i++)
                 {
-                    View v = subviews [i];
-                    maxAnchorEnd = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
-                }
-
-                subviewsSize += maxAnchorEnd;
-                #endregion Anchored
+                    View v = centeredSubViews [i];
 
-                //#region Aligned
+                    int maxCentered = dimension == Dimension.Width ?/* v.X.GetAnchor (maxCalculatedSize) +*/ v.Width.GetAnchor (maxCalculatedSize) : /*v.Y.GetAnchor (maxCalculatedSize) + */v.Height.GetAnchor(maxCalculatedSize);
 
-                //// 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 ();
+                    if (maxCentered > maxCalculatedSize)
+                    {
+                        maxCalculatedSize = maxCentered;
+                    }
+                }
 
-                //    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;
-                //        }
+                #region Anchored
+                // [x] PosAnchorEnd - Position is dependent on `us.ContentSize` AND `subview.Frame` 
+                List<View> anchoredSubViews;
+                if (dimension == Dimension.Width)
+                {
+                    anchoredSubViews = includedSubviews.Where (v => v.X.Has (typeof (PosAnchorEnd), out _)).ToList ();
+                }
+                else
+                {
+                    anchoredSubViews = includedSubviews.Where (v => v.Y.Has (typeof (PosAnchorEnd), out _)).ToList ();
+                }
 
-                //        maxAlign = PosAlign.CalculateMinDimension (groupId, includedSubviews, dimension);
-                //    }
-                //}
-                //else
-                //{
-                //    subviews = includedSubviews.Where (v => v.Y is PosAlign).ToList ();
-                //}
+                int maxAnchorEnd = 0;
+                for (var i = 0; i < anchoredSubViews.Count; i++)
+                {
+                    View v = anchoredSubViews [i];
 
-                //subviewsSize = int.Max (subviewsSize, maxAlign);
-                //#endregion Aligned
+                    // Need to set the relative layout for PosAnchorEnd subviews to calculate the size
+                    if (dimension == Dimension.Width)
+                    {
+                        v.SetRelativeLayout (new Size (maxCalculatedSize, 0));
+                    }
+                    else
+                    {
+                        v.SetRelativeLayout (new Size (0, maxCalculatedSize));
+                    }
+                    maxAnchorEnd = dimension == Dimension.Width ? v.X.GetAnchor (maxCalculatedSize) + v.Frame.Width : v.Y.GetAnchor (maxCalculatedSize) + v.Frame.Height;
+                }
 
+                maxCalculatedSize = Math.Max (maxCalculatedSize, maxAnchorEnd);
+                #endregion Anchored
 
-                #region Auto
 
+                #region PosView
+                // [x] PosView      - Position is dependent on `subview.Target` - it can cause a change in `us.ContentSize`
+                List<View> posViewSubViews;
                 if (dimension == Dimension.Width)
                 {
-                    subviews = includedSubviews.Where (v => v.Width is DimAuto).ToList ();
+                    posViewSubViews = includedSubviews.Where (v => v.X.Has (typeof (PosView), out _)).ToList ();
                 }
                 else
                 {
-                    subviews = includedSubviews.Where (v => v.Height is DimAuto).ToList ();
+                    posViewSubViews = includedSubviews.Where (v => v.Y.Has (typeof (PosView), out _)).ToList ();
                 }
 
-                int maxAuto = 0;
-                for (var i = 0; i < subviews.Count; i++)
+                for (var i = 0; i < posViewSubViews.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;
-
-                    if (maxAuto > subviewsSize)
+                    View v = posViewSubViews [i];
+
+                    // BUGBUG: The order may not be correct. May need to call TopologicalSort?
+                    if (dimension == Dimension.Width)
                     {
-                        // BUGBUG: Should we break here? Or choose min/max?
-                        subviewsSize = maxAuto;
+                        v.SetRelativeLayout (new Size (maxCalculatedSize, 0));
+                    }
+                    else
+                    {
+                        v.SetRelativeLayout (new Size (0, maxCalculatedSize));
+                    }
+                    int maxPosView = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
+
+                    if (maxPosView > maxCalculatedSize)
+                    {
+                        maxCalculatedSize = maxPosView;
                     }
                 }
+                #endregion PosView
+
+                // [x] PosCombine   - Position is dependent if `Pos.Has ([one of the above]` - it can cause a change in `us.ContentSize`
 
-//                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 Are Dependent
-                // Now, go back to those that are dependent on content size
-                // [x] DimFill
-                // [ ] DimPercent
+                #region DimView
+                // [x] DimView      - Dimension is dependent on `subview.Target` - it can cause a change in `us.ContentSize`
+                List<View> dimViewSubViews;
                 if (dimension == Dimension.Width)
                 {
-                    subviews = includedSubviews.Where (v => v.Width is DimFill).ToList ();
+                    dimViewSubViews = includedSubviews.Where (v => v.Width is { } && v.Width.Has (typeof (DimView), out _)).ToList ();
                 }
                 else
                 {
-                    subviews = includedSubviews.Where (v => v.Height is DimFill).ToList ();
+                    dimViewSubViews = includedSubviews.Where (v => v.Height is { } && v.Height.Has (typeof (DimView), out _)).ToList ();
                 }
 
-                int maxFill = 0;
-                for (var i = 0; i < subviews.Count; i++)
+                for (var i = 0; i < dimViewSubViews.Count; i++)
                 {
-                    View v = subviews [i];
+                    View v = dimViewSubViews [i];
 
-                    if (autoMax == int.MaxValue)
-                    {
-                        autoMax = superviewContentSize;
-                    }
+                    // BUGBUG: The order may not be correct. May need to call TopologicalSort?
                     if (dimension == Dimension.Width)
                     {
-                        v.SetRelativeLayout (new Size (autoMax - subviewsSize, 0));
+                        v.SetRelativeLayout (new Size (maxCalculatedSize, 0));
                     }
                     else
                     {
-                        v.SetRelativeLayout (new Size (0, autoMax - subviewsSize));
+                        v.SetRelativeLayout (new Size (0, maxCalculatedSize));
+                    }
+
+                    int maxDimView = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
+
+                    if (maxDimView > maxCalculatedSize)
+                    {
+                        maxCalculatedSize = maxDimView;
                     }
-                    maxFill = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
                 }
+                #endregion DimView
+
+
+                // [x] DimCombine   - Dimension is dependent if `Dim.Has ([one of the above]` - it can cause a change in `us.ContentSize`
+
+
+
+
+
+
+
+                //        // ======================================================
+                //        // Now do PosAlign - It's dependent on other views with `GroupId` AND `us.ContentSize`
+                //        // ======================================================
+                //        // [ ] PosAlign     - Position is dependent on other views with `GroupId` AND `us.ContentSize`
+                //        #region Aligned
+
+                //        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;
+                //                }
+                //                // BUGBUG: ignores adornments
+
+                //                maxAlign = PosAlign.CalculateMinDimension (groupId, includedSubviews, dimension);
+                //            }
+                //        }
+                //        else
+                //        {
+
+                //            // BUGBUG: Incompletge
+                //            subviews = includedSubviews.Where (v => v.Y is PosAlign).ToList ();
+                //        }
+
+                //        maxCalculatedSize = int.Max (maxCalculatedSize, maxAlign);
+                //        #endregion Aligned
+
+                //        // TODO: This whole body of code is a WIP (forhttps://github.com/gui-cs/Terminal.Gui/issues/3499).
+
+
+                //        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
+                //        // [ ] PosCenter
+                //        // [ ] PosPercent
+                //        // [ ] PosView
+                //        // [ ] PosFunc
+                //        // [x] DimFill
+                //        // [ ] DimPercent
+                //        // [ ] DimFunc
+                //        // [ ] DimView
+                //        if (dimension == Dimension.Width)
+                //        {
+                //            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 ();
+                //        }
+                //        else
+                //        {
+                //            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 ();
+                //        }
+
+                //        for (var i = 0; i < subviews.Count; i++)
+                //        {
+                //            View v = subviews [i];
+
+                //            int size = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
+
+                //            if (size > maxCalculatedSize)
+                //            {
+                //                // BUGBUG: Should we break here? Or choose min/max?
+                //                maxCalculatedSize = size;
+                //            }
+                //        }
+                //        #endregion Not Anchored and Are Not Dependent
+
+
+                //        //#region Aligned
+
+                //        //// Now, handle subviews that are aligned
+                //        //// [x] PosAlign
+                //        //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;
+                //        //        }
+                //        // BUGBUG: ignores adornments
+
+                //        //        maxAlign = PosAlign.CalculateMinDimension (groupId, includedSubviews, dimension);
+                //        //    }
+                //        //}
+                //        //else
+                //        //{
+                //        //    subviews = includedSubviews.Where (v => v.Y is PosAlign).ToList ();
+                //        //}
+
+                //        //subviewsSize = int.Max (subviewsSize, maxAlign);
+                //        //#endregion Aligned
+
+
+                //        #region Auto
+
+
+
+                //        #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 Are Dependent
+                //        // Now, go back to those that are dependent on content size
+
+
+                //        // Set relative layout for all DimAuto subviews
+                //        List<View> dimAutoSubViews;
+                //        int maxAuto = 0;
+                //        if (dimension == Dimension.Width)
+                //        {
+                //            dimAutoSubViews = includedSubviews.Where (v => v.Width is DimAuto).ToList ();
+                //        }
+                //        else
+                //        {
+                //            dimAutoSubViews = includedSubviews.Where (v => v.Height is DimAuto).ToList ();
+                //        }
+                //        for (var i = 0; i < dimAutoSubViews.Count; i++)
+                //        {
+                //            View v = dimAutoSubViews [i];
+
+                //            if (dimension == Dimension.Width)
+                //            {
+                //                // BUGBUG: ignores adornments
 
-                subviewsSize += maxFill;
-                #endregion Are Dependent
+                //                v.SetRelativeLayout (new Size (autoMax - maxCalculatedSize, 0));
+                //            }
+                //            else
+                //            {
+                //                // BUGBUG: ignores adornments
+
+                //                v.SetRelativeLayout (new Size (0, autoMax - maxCalculatedSize));
+                //            }
+
+                //            maxAuto = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
+
+                //            if (maxAuto > maxCalculatedSize)
+                //            {
+                //                // BUGBUG: Should we break here? Or choose min/max?
+                //                maxCalculatedSize = maxAuto;
+                //            }
+                //        }
+
+                //        // [x] DimFill
+                //        // [ ] DimPercent
+                //        if (dimension == Dimension.Width)
+                //        {
+                //            subviews = includedSubviews.Where (v => v.Width is DimFill).ToList ();
+                //        }
+                //        else
+                //        {
+                //            subviews = includedSubviews.Where (v => v.Height is DimFill).ToList ();
+                //        }
+
+                //        int maxFill = 0;
+                //        for (var i = 0; i < subviews.Count; i++)
+                //        {
+                //            View v = subviews [i];
+
+                //            if (autoMax == int.MaxValue)
+                //            {
+                //                autoMax = superviewContentSize;
+                //            }
+                //            if (dimension == Dimension.Width)
+                //            {
+                //                // BUGBUG: ignores adornments
+                //                v.SetRelativeLayout (new Size (autoMax - maxCalculatedSize, 0));
+                //            }
+                //            else
+                //            {
+                //                // BUGBUG: ignores adornments
+                //                v.SetRelativeLayout (new Size (0, autoMax - maxCalculatedSize));
+                //            }
+                //            maxFill = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
+                //        }
+
+                //        maxCalculatedSize += maxFill;
+                //        #endregion Are Dependent
             }
         }
 
         // All sizes here are content-relative; ignoring adornments.
         // We take the largest of text and content.
-        int max = int.Max (textSize, subviewsSize);
+        int max = int.Max (textSize, maxCalculatedSize);
 
         // And, if min: is set, it wins if larger
         max = int.Max (max, autoMin);
@@ -302,9 +567,24 @@ public class DimAuto () : Dim
         // And, if max: is set, it wins if smaller
         max = int.Min (max, autoMax);
 
+
+        // ************** We now definitively know `us.ContentSize` ***************
+
+        foreach (var v in us.Subviews)
+        {
+            if (dimension == Dimension.Width)
+            {
+                v.SetRelativeLayout (new Size (max, Application.Driver.Screen.Width));
+            }
+            else
+            {
+                v.SetRelativeLayout (new Size (Application.Driver.Screen.Height, max));
+            }
+        }
+
         // Factor in adornments
         Thickness thickness = us.GetAdornmentsThickness ();
-        max += dimension switch
+        var adornmentThickness = dimension switch
         {
             Dimension.Width => thickness.Horizontal,
             Dimension.Height => thickness.Vertical,
@@ -312,6 +592,8 @@ public class DimAuto () : Dim
             _ => throw new ArgumentOutOfRangeException (nameof (dimension), dimension, null)
         };
 
+        max += adornmentThickness;
+
         return max;
     }
 

+ 3 - 3
Terminal.Gui/View/Layout/DimCombine.cs

@@ -13,7 +13,7 @@ namespace Terminal.Gui;
 /// </remarks>
 /// <param name="left">The left dimension.</param>
 /// <param name="right">The right dimension.</param>
-public class DimCombine (AddOrSubtract add, Dim? left, Dim? right) : Dim
+public class DimCombine (AddOrSubtract add, Dim left, Dim right) : Dim
 {
     /// <summary>
     ///     Gets whether the two dimensions are added or subtracted.
@@ -23,12 +23,12 @@ public class DimCombine (AddOrSubtract add, Dim? left, Dim? right) : Dim
     /// <summary>
     ///     Gets the left dimension.
     /// </summary>
-    public Dim? Left { get; } = left;
+    public Dim Left { get; } = left;
 
     /// <summary>
     ///     Gets the right dimension.
     /// </summary>
-    public Dim? Right { get; } = right;
+    public Dim Right { get; } = right;
 
     /// <inheritdoc/>
     public override string ToString () { return $"Combine({Left}{(Add == AddOrSubtract.Add ? '+' : '-')}{Right})"; }

+ 112 - 85
Terminal.Gui/View/Layout/ViewLayout.cs

@@ -546,15 +546,106 @@ public partial class View
     public event EventHandler<LayoutEventArgs> LayoutStarted;
 
     /// <summary>
-    ///     Invoked when a view starts executing or when the dimensions of the view have changed, for example in response to
-    ///     the container view or terminal resizing.
+    ///     Adjusts <see cref="Frame"/> given the SuperView's ContentSize (nominally the same as
+    ///     <c>this.SuperView.GetContentSize ()</c>)
+    ///     and the position (<see cref="X"/>, <see cref="Y"/>) and dimension (<see cref="Width"/>, and
+    ///     <see cref="Height"/>).
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         If <see cref="X"/>, <see cref="Y"/>, <see cref="Width"/>, or <see cref="Height"/> are
+    ///         absolute, they will be updated to reflect the new size and position of the view. Otherwise, they
+    ///         are left unchanged.
+    ///     </para>
+    ///     <para>
+    ///         If any of the view's subviews have a position or dimension dependent on either <see cref="GetContentSize"/> or other subviews, <see cref="LayoutSubview"/> on
+    ///         will be called for that subview.
+    ///     </para>
+    /// </remarks>
+    /// <param name="superviewContentSize">
+    ///     The size of the SuperView's content (nominally the same as <c>this.SuperView.GetContentSize ()</c>).
+    /// </param>
+    internal void SetRelativeLayout (Size superviewContentSize)
+    {
+        Debug.Assert (_x is { });
+        Debug.Assert (_y is { });
+        Debug.Assert (_width is { });
+        Debug.Assert (_height is { });
+
+        CheckDimAuto ();
+        int newX, newW, newY, newH;
+
+        // Calculate the new X, Y, Width, and Height
+        // If the Width or Height is Dim.Auto, calculate the Width or Height first. Otherwise, calculate the X or Y first.
+        if (_width is DimAuto)
+        {
+            newW = _width.Calculate (0, superviewContentSize.Width, this, Dimension.Width);
+            newX = _x.Calculate (superviewContentSize.Width, newW, this, Dimension.Width);
+        }
+        else
+        {
+            newX = _x.Calculate (superviewContentSize.Width, _width, this, Dimension.Width);
+            newW = _width.Calculate (newX, superviewContentSize.Width, this, Dimension.Width);
+        }
+
+        if (_height is DimAuto)
+        {
+            newH = _height.Calculate (0, superviewContentSize.Height, this, Dimension.Height);
+            newY = _y.Calculate (superviewContentSize.Height, newH, this, Dimension.Height);
+        }
+        else
+        {
+            newY = _y.Calculate (superviewContentSize.Height, _height, this, Dimension.Height);
+            newH = _height.Calculate (newY, superviewContentSize.Height, this, Dimension.Height);
+        }
+
+        Rectangle newFrame = new (newX, newY, newW, newH);
+
+        if (Frame != newFrame)
+        {
+            // Set the frame. Do NOT use `Frame` as it overwrites X, Y, Width, and Height
+            SetFrame (newFrame);
+
+            if (_x is PosAbsolute)
+            {
+                _x = Frame.X;
+            }
+
+            if (_y is PosAbsolute)
+            {
+                _y = Frame.Y;
+            }
+
+            if (_width is DimAbsolute)
+            {
+                _width = Frame.Width;
+            }
+
+            if (_height is DimAbsolute)
+            {
+                _height = Frame.Height;
+            }
+
+            if (!string.IsNullOrEmpty (Title))
+            {
+                SetTitleTextFormatterSize ();
+            }
+
+            SetNeedsLayout ();
+            SetNeedsDisplay ();
+        }
+    }
+
+
+    /// <summary>
+    ///     Invoked when the dimensions of the view have changed, for example in response to the container view or terminal resizing.
     /// </summary>
     /// <remarks>
     ///     <para>
     ///         The position and dimensions of the view are indeterminate until the view has been initialized. Therefore, the
     ///         behavior of this method is indeterminate if <see cref="IsInitialized"/> is <see langword="false"/>.
     ///     </para>
-    ///     <para>Raises the <see cref="LayoutComplete"/> event) before it returns.</para>
+    ///     <para>Raises the <see cref="LayoutComplete"/> event before it returns.</para>
     /// </remarks>
     public virtual void LayoutSubviews ()
     {
@@ -689,89 +780,11 @@ public partial class View
     }
 
     /// <summary>
-    ///     Adjusts <see cref="Frame"/> given the SuperView's ContentSize (nominally the same as
-    ///     <c>this.SuperView.GetContentSize ()</c>)
-    ///     and the position (<see cref="X"/>, <see cref="Y"/>) and dimension (<see cref="Width"/>, and
-    ///     <see cref="Height"/>).
+    /// Collects all views and their dependencies from a given starting view for layout purposes. Used by <see cref="TopologicalSort"/> to create an ordered list of views to layout.
     /// </summary>
-    /// <remarks>
-    ///     <para>
-    ///         If <see cref="X"/>, <see cref="Y"/>, <see cref="Width"/>, or <see cref="Height"/> are
-    ///         absolute, they will be updated to reflect the new size and position of the view. Otherwise, they
-    ///         are left unchanged.
-    ///     </para>
-    /// </remarks>
-    /// <param name="superviewContentSize">
-    ///     The size of the SuperView's content (nominally the same as <c>this.SuperView.GetContentSize ()</c>).
-    /// </param>
-    internal void SetRelativeLayout (Size superviewContentSize)
-    {
-        Debug.Assert (_x is { });
-        Debug.Assert (_y is { });
-        Debug.Assert (_width is { });
-        Debug.Assert (_height is { });
-
-        CheckDimAuto ();
-        int newX, newW, newY, newH;
-
-        if (_width is DimAuto)
-        {
-            newW = _width.Calculate (0, superviewContentSize.Width, this, Dimension.Width);
-            newX = _x.Calculate (superviewContentSize.Width, newW, this, Dimension.Width);
-        }
-        else
-        {
-            newX = _x.Calculate (superviewContentSize.Width, _width, this, Dimension.Width);
-            newW = _width.Calculate (newX, superviewContentSize.Width, this, Dimension.Width);
-        }
-
-        if (_height is DimAuto)
-        {
-            newH = _height.Calculate (0, superviewContentSize.Height, this, Dimension.Height);
-            newY = _y.Calculate (superviewContentSize.Height, newH, this, Dimension.Height);
-        }
-        else
-        {
-            newY = _y.Calculate (superviewContentSize.Height, _height, this, Dimension.Height);
-            newH = _height.Calculate (newY, superviewContentSize.Height, this, Dimension.Height);
-        }
-
-        Rectangle newFrame = new (newX, newY, newW, newH);
-
-        if (Frame != newFrame)
-        {
-            // Set the frame. Do NOT use `Frame` as it overwrites X, Y, Width, and Height
-            SetFrame (newFrame);
-
-            if (_x is PosAbsolute)
-            {
-                _x = Frame.X;
-            }
-
-            if (_y is PosAbsolute)
-            {
-                _y = Frame.Y;
-            }
-
-            if (_width is DimAbsolute)
-            {
-                _width = Frame.Width;
-            }
-
-            if (_height is DimAbsolute)
-            {
-                _height = Frame.Height;
-            }
-
-            if (!string.IsNullOrEmpty (Title))
-            {
-                SetTitleTextFormatterSize ();
-            }
-
-            SetNeedsLayout ();
-            SetNeedsDisplay ();
-        }
-    }
+    /// <param name="from">The starting view from which to collect dependencies.</param>
+    /// <param name="nNodes">A reference to a set of views representing nodes in the layout graph.</param>
+    /// <param name="nEdges">A reference to a set of tuples representing edges in the layout graph, where each tuple consists of a pair of views indicating a dependency.</param>
 
     internal void CollectAll (View from, ref HashSet<View> nNodes, ref HashSet<(View, View)> nEdges)
     {
@@ -784,6 +797,13 @@ public partial class View
             CollectDim (v.Height, v, ref nNodes, ref nEdges);
         }
     }
+    /// <summary>
+    /// Collects dimension (where Width or Height is `DimView`) dependencies for a given view.
+    /// </summary>
+    /// <param name="dim">The dimension (width or height) to collect dependencies for.</param>
+    /// <param name="from">The view for which to collect dimension dependencies.</param>
+    /// <param name="nNodes">A reference to a set of views representing nodes in the layout graph.</param>
+    /// <param name="nEdges">A reference to a set of tuples representing edges in the layout graph, where each tuple consists of a pair of views indicating a dependency.</param>
 
     internal void CollectDim (Dim? dim, View from, ref HashSet<View> nNodes, ref HashSet<(View, View)> nEdges)
     {
@@ -808,6 +828,13 @@ public partial class View
         }
     }
 
+    /// <summary>
+    /// Collects position (where X or Y is `PosView`) dependencies for a given view.
+    /// </summary>
+    /// <param name="pos">The position (X or Y) to collect dependencies for.</param>
+    /// <param name="from">The view for which to collect position dependencies.</param>
+    /// <param name="nNodes">A reference to a set of views representing nodes in the layout graph.</param>
+    /// <param name="nEdges">A reference to a set of tuples representing edges in the layout graph, where each tuple consists of a pair of views indicating a dependency.</param>
     internal void CollectPos (Pos pos, View from, ref HashSet<View> nNodes, ref HashSet<(View, View)> nEdges)
     {
         switch (pos)

+ 5 - 4
Terminal.Gui/Views/Dialog.cs

@@ -33,14 +33,14 @@ public class Dialog : Window
     ///     <see cref="ConfigurationManager"/>.
     /// </summary>
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
-    public static int DefaultMinimumWidth { get; set; } = 25;
+    public static int DefaultMinimumWidth { get; set; } = 0;
 
     /// <summary>
     ///     Defines the default minimum Dialog height, as a percentage of the container width. Can be configured via
     ///     <see cref="ConfigurationManager"/>.
     /// </summary>
     [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
-    public static int DefaultMinimumHeight { get; set; } = 25;
+    public static int DefaultMinimumHeight { get; set; } = 0;
 
 
     /// <summary>
@@ -79,8 +79,8 @@ public class Dialog : Window
         X = Pos.Center ();
         Y = Pos.Center ();
 
-        Width = Dim.Auto (DimAutoStyle.Content, Dim.Percent (DefaultMinimumWidth), Dim.Percent (90));
-        Height = Dim.Auto (DimAutoStyle.Content, Dim.Percent (DefaultMinimumHeight), Dim.Percent (90));
+        Width = Dim.Auto (DimAutoStyle.Auto, Dim.Percent (DefaultMinimumWidth), Dim.Percent (90));
+        Height = Dim.Auto (DimAutoStyle.Auto, Dim.Percent (DefaultMinimumHeight), Dim.Percent (90));
         ColorScheme = Colors.ColorSchemes ["Dialog"];
 
         Modal = true;
@@ -169,6 +169,7 @@ public class Dialog : Window
         // Use a distinct GroupId so users can use Pos.Align for other views in the Dialog
         button.X = Pos.Align (ButtonAlignment, ButtonAlignmentModes, GetHashCode ());
         button.Y = Pos.AnchorEnd ();
+        button.Margin.Thickness = button.Margin.Thickness with { Top = 1 };
 
         _buttons.Add (button);
         Add (button);

+ 34 - 28
Terminal.Gui/Views/MessageBox.cs

@@ -1,4 +1,5 @@
-using System.Text.Json.Serialization;
+using System.Diagnostics;
+using System.Text.Json.Serialization;
 
 namespace Terminal.Gui;
 
@@ -368,8 +369,8 @@ public static class MessageBox
             ButtonAlignment = Alignment.Center,
             ButtonAlignmentModes = AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems,
             BorderStyle = MessageBox.DefaultBorderStyle,
-            Width = Dim.Auto (DimAutoStyle.Content, minimumContentDim: 1, Dim.Percent (90)),
-            Height = Dim.Auto (DimAutoStyle.Content, minimumContentDim: 1, Dim.Percent (90)),
+            Width = Dim.Auto (DimAutoStyle.Auto, minimumContentDim: 1, maximumContentDim: Dim.Percent (90)),
+            Height = Dim.Auto (DimAutoStyle.Auto, minimumContentDim: 2, maximumContentDim: Dim.Percent (90)),
         };
 
         if (width != 0)
@@ -384,36 +385,41 @@ public static class MessageBox
 
         d.ColorScheme = useErrorColors ? Colors.ColorSchemes ["Error"] : Colors.ColorSchemes ["Dialog"];
 
-        var messageLabel = new Label
+        d.LayoutComplete += (s, e) =>
         {
-            HotKeySpecifier = new Rune ('\xFFFF'),
-            Width = Dim.Auto (DimAutoStyle.Text),
-            Height = Dim.Auto (DimAutoStyle.Text),
-            Text = message,
-            TextAlignment = Alignment.Center,
-            X = Pos.Center (),
-            Y = 0,
-            //ColorScheme = Colors.ColorSchemes ["Error"],
-        };
+            if (wrapMessage)
+            {
+                int buttonHeight = buttonList.Count > 0 ? buttonList [0].Frame.Height : 0;
+                Debug.Assert (d.TextFormatter.WordWrap);
+                d.TextFormatter.Size = new Size (d.GetContentSize ().Width, Application.Driver.Screen.Height);
+                Size textSize = d.TextFormatter.GetAutoSize ();
+                textSize.Height += buttonHeight;
 
-        messageLabel.TextFormatter.WordWrap = wrapMessage;
-        messageLabel.TextFormatter.MultiLine = !wrapMessage;
+                if (textSize != d.TextFormatter.Size)
+                {
+                    //d.TextFormatter.Size = textSize;
+                    //d.SetContentSize (textSize);
+                    d.SetNeedsLayout ();
+                    //d.SetRelativeLayout (Application.Driver.Screen.Size);
+                }
+            }
+        };
 
-        if (wrapMessage)
-        {
-            int buttonHeight = buttonList.Count > 0 ? buttonList [0].Frame.Height : 0;
+        d.HotKeySpecifier = new Rune ('\xFFFF');
+        d.Text = message;
+        d.TextAlignment = Alignment.Center;
+        d.VerticalTextAlignment = Alignment.Start;
+        d.TextFormatter.WordWrap = wrapMessage;
+        d.TextFormatter.MultiLine = !wrapMessage;
 
-            messageLabel.Width = Dim.Fill ();
-            messageLabel.Height = Dim.Func (() => GetWrapSize ().Height);
-            Size GetWrapSize ()
-            {
-                // A bit of a hack to get the height of the wrapped text.
-                messageLabel.TextFormatter.Size = d.GetContentSize () with { Height = 1000 };
-                return messageLabel.TextFormatter.FormatAndGetSize ();
-            }
-        }
+        // Add two lines to push buttons down two rows
+        // BUGBUG: The " " are here due to a bug in TextFormater.Format that strips trailing newlines when .Wordwrap = true
+       // d.Text += Environment.NewLine + " " + Environment.NewLine + " ";
 
-        d.Add (messageLabel);
+        d.ColorScheme = new ColorScheme (d.ColorScheme)
+        {
+            Focus = d.ColorScheme.Normal
+        };
 
         // Setup actions
         Clicked = -1;

+ 26 - 22
UICatalog/Scenarios/DimAutoDemo.cs

@@ -23,21 +23,21 @@ public class DimAutoDemo : Scenario
 
         FrameView dimAutoFrameView = CreateDimAutoContentFrameView ();
 
-        FrameView sliderFrameView = CreateSliderFrameView ();
-        sliderFrameView.X = Pos.Right(dimAutoFrameView) + 1;
-        sliderFrameView.Width = Dim.Fill ();
-        sliderFrameView.Height = Dim.Fill ();
+        //FrameView sliderFrameView = CreateSliderFrameView ();
+        //sliderFrameView.X = Pos.Right(dimAutoFrameView) + 1;
+        //sliderFrameView.Width = Dim.Fill ();
+        //sliderFrameView.Height = Dim.Fill ();
 
 
-        //var dlgButton = new Button
-        //{
-        //    Text = "Open Test _Dialog",
-        //    X = Pos.Right (dimAutoFrameView),
-        //    Y = Pos.Top (dimAutoFrameView)
-        //};
-        //dlgButton.Accept += DlgButton_Clicked;
+        ////var dlgButton = new Button
+        ////{
+        ////    Text = "Open Test _Dialog",
+        ////    X = Pos.Right (dimAutoFrameView),
+        ////    Y = Pos.Top (dimAutoFrameView)
+        ////};
+        ////dlgButton.Accept += DlgButton_Clicked;
 
-        appWindow.Add (dimAutoFrameView, sliderFrameView /*dlgButton*/);
+        appWindow.Add (dimAutoFrameView/*, sliderFrameView dlgButton*/);
 
         // Run - Start the application.
         Application.Run (appWindow);
@@ -140,23 +140,27 @@ public class DimAutoDemo : Scenario
                                         bothAuto.Text = textEdit.Text;
                                     };
 
-        var movingButton = new Button
-        {
-            Text = "_Click\nTo Move\nDown",
-            X = Pos.Right (vlabel),
-            Y = Pos.Bottom (vlabel)
-        };
-        movingButton.Accept += (s, e) => { movingButton.Y = movingButton.Frame.Y + 1; };
-        dimAutoFrameView.Add (movingButton);
+        //var movingButton = new Button
+        //{
+        //    Text = "_Click\nTo Move\nDown",
+        //    X = Pos.Right (vlabel),
+        //    Y = Pos.Bottom (vlabel)
+        //};
+        //movingButton.Accept += (s, e) => { movingButton.Y = movingButton.Frame.Y + 1; };
+        //dimAutoFrameView.Add (movingButton);
 
         var resetButton = new Button
         {
             Text = "_Reset Button (AnchorEnd)",
             X = Pos.AnchorEnd (),
-            Y = Pos.AnchorEnd (1)
+            Y = Pos.AnchorEnd ()
         };
 
-        resetButton.Accept += (s, e) => { movingButton.Y = Pos.Bottom (hlabel); };
+        resetButton.Accept += (s, e) =>
+        {
+            //movingButton.Y = Pos.Bottom (hlabel);
+            //movingButton.X = 0;
+        };
         dimAutoFrameView.Add (resetButton);
 
         return dimAutoFrameView;

+ 7 - 6
UICatalog/UICatalog.cs

@@ -305,12 +305,12 @@ internal class UICatalogApp
         _aboutMessage = new ();
         _aboutMessage.AppendLine (@"A comprehensive sample library for");
         _aboutMessage.AppendLine (@"");
-        _aboutMessage.AppendLine (@"  _______                  _             _   _____       _  ");
-        _aboutMessage.AppendLine (@" |__   __|                (_)           | | / ____|     (_) ");
-        _aboutMessage.AppendLine (@"    | | ___ _ __ _ __ ___  _ _ __   __ _| || |  __ _   _ _  ");
-        _aboutMessage.AppendLine (@"    | |/ _ \ '__| '_ ` _ \| | '_ \ / _` | || | |_ | | | | | ");
-        _aboutMessage.AppendLine (@"    | |  __/ |  | | | | | | | | | | (_| | || |__| | |_| | | ");
-        _aboutMessage.AppendLine (@"    |_|\___|_|  |_| |_| |_|_|_| |_|\__,_|_(_)_____|\__,_|_| ");
+        _aboutMessage.AppendLine (@" _______                  _             _   _____       _ ");
+        _aboutMessage.AppendLine (@"|__   __|                (_)           | | / ____|     (_)");
+        _aboutMessage.AppendLine (@"   | | ___ _ __ _ __ ___  _ _ __   __ _| || |  __ _   _ _ ");
+        _aboutMessage.AppendLine (@"   | |/ _ \ '__| '_ ` _ \| | '_ \ / _` | || | |_ | | | | |");
+        _aboutMessage.AppendLine (@"   | |  __/ |  | | | | | | | | | | (_| | || |__| | |_| | |");
+        _aboutMessage.AppendLine (@"   |_|\___|_|  |_| |_| |_|_|_| |_|\__,_|_(_)_____|\__,_|_|");
         _aboutMessage.AppendLine (@"");
         _aboutMessage.AppendLine (@"v2 - Work in Progress");
         _aboutMessage.AppendLine (@"");
@@ -346,6 +346,7 @@ internal class UICatalogApp
         // 'app' closed cleanly.
         foreach (Responder? inst in Responder.Instances)
         {
+            
             Debug.Assert (inst.WasDisposed);
         }