Sfoglia il codice sorgente

WIP: Fixing MessagBox to use Dim.Auto

Tig 1 anno fa
parent
commit
01c30ef99f

+ 76 - 33
Terminal.Gui/View/Layout/Dim.cs

@@ -1,4 +1,5 @@
 using System.Diagnostics;
 using System.Diagnostics;
+using System.Drawing;
 
 
 namespace Terminal.Gui;
 namespace Terminal.Gui;
 
 
@@ -176,10 +177,10 @@ public class Dim
     /// <param name="maximumContentDim">The maximum dimension the View's ContentSize will be fit to. NOT CURRENTLY SUPPORTED.</param>
     /// <param name="maximumContentDim">The maximum dimension the View's ContentSize will be fit to. NOT CURRENTLY SUPPORTED.</param>
     public static Dim Auto (DimAutoStyle style = DimAutoStyle.Auto, Dim minimumContentDim = null, Dim maximumContentDim = null)
     public static Dim Auto (DimAutoStyle style = DimAutoStyle.Auto, Dim minimumContentDim = null, Dim maximumContentDim = null)
     {
     {
-        if (maximumContentDim != null)
-        {
-            throw new NotImplementedException (@"maximumContentDim is not implemented");
-        }
+        //if (maximumContentDim != null)
+        //{
+        //    throw new NotImplementedException (@"maximumContentDim is not implemented");
+        //}
 
 
         return new DimAuto (style, minimumContentDim, maximumContentDim);
         return new DimAuto (style, minimumContentDim, maximumContentDim);
     }
     }
@@ -459,29 +460,71 @@ public class DimAuto (DimAutoStyle style, Dim minimumContentDim, Dim maximumCont
                 // TODO: If _min > 0 we can SetRelativeLayout for the subviews?
                 // TODO: If _min > 0 we can SetRelativeLayout for the subviews?
                 subviewsSize = 0;
                 subviewsSize = 0;
 
 
-                if (us.Subviews.Count > 0)
+                List<View> subviews;
+
+                if (dimension == Dimension.Width)
+                {
+                    subviews = us.Subviews.Where (v => v.X is not PosAnchorEnd && v.Width is not DimFill).ToList ();
+                }
+                else
+                {
+                    subviews = us.Subviews.Where (v => v.Y is not PosAnchorEnd && 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 > subviewsSize)
+                    {
+                        subviewsSize = size;
+                    }
+                }
+
+                if (dimension == Dimension.Width)
+                {
+                    subviews = us.Subviews.Where (v => v.X is PosAnchorEnd).ToList ();
+                }
+                else
+                {
+                    subviews = us.Subviews.Where (v => v.Y is PosAnchorEnd).ToList ();
+                }
+
+                int maxAnchorEnd = 0;
+                for (var i = 0; i < subviews.Count; i++)
+                {
+                    View v = subviews [i];
+                    maxAnchorEnd = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
+                }
+
+                subviewsSize += maxAnchorEnd;
+
+
+                if (dimension == Dimension.Width)
+                {
+                    subviews = us.Subviews.Where (v => v.Width is DimFill).ToList ();
+                }
+                else
+                {
+                    subviews = us.Subviews.Where (v => v.Height is DimFill).ToList ();
+                }
+
+                for (var i = 0; i < subviews.Count; i++)
                 {
                 {
-                    for (var i = 0; i < us.Subviews.Count; i++)
+                    View v = subviews [i];
+
+                    if (dimension == Dimension.Width)
                     {
                     {
-                        View v = us.Subviews [i];
-                        bool isNotPosAnchorEnd = dimension == Dimension.Width ? v.X is not PosAnchorEnd : v.Y is not PosAnchorEnd;
-
-                        //if (!isNotPosAnchorEnd)
-                        //{
-                        //    v.SetRelativeLayout(dimension == Dimension.Width ? (new Size (autoMin, 0)) : new Size (0, autoMin));
-                        //}
-
-                        if (isNotPosAnchorEnd)
-                        {
-                            int size = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
-
-                            if (size > subviewsSize)
-                            {
-                                subviewsSize = size;
-                            }
-                        }
+                        v.SetRelativeLayout (new Size (subviewsSize, 0));
+                    }
+                    else
+                    {
+                        v.SetRelativeLayout (new Size (0, autoMin - subviewsSize));
                     }
                     }
                 }
                 }
+
             }
             }
         }
         }
 
 
@@ -743,11 +786,11 @@ public class DimView : Dim
         }
         }
 
 
         string dimString = Dimension switch
         string dimString = Dimension switch
-                           {
-                               Dimension.Height => "Height",
-                               Dimension.Width => "Width",
-                               _ => "unknown"
-                           };
+        {
+            Dimension.Height => "Height",
+            Dimension.Width => "Width",
+            _ => "unknown"
+        };
 
 
         return $"View({dimString},{Target})";
         return $"View({dimString},{Target})";
     }
     }
@@ -755,11 +798,11 @@ public class DimView : Dim
     internal override int Anchor (int size)
     internal override int Anchor (int size)
     {
     {
         return Dimension switch
         return Dimension switch
-               {
-                   Dimension.Height => Target.Frame.Height,
-                   Dimension.Width => Target.Frame.Width,
-                   _ => 0
-               };
+        {
+            Dimension.Height => Target.Frame.Height,
+            Dimension.Width => Target.Frame.Width,
+            _ => 0
+        };
     }
     }
 
 
     internal override bool ReferencesOtherViews () { return true; }
     internal override bool ReferencesOtherViews () { return true; }

+ 8 - 8
Terminal.Gui/View/ViewContent.cs

@@ -314,14 +314,14 @@ public partial class View
     {
     {
         get
         get
         {
         {
-#if DEBUG
-            if ((_width.ReferencesOtherViews () || _height.ReferencesOtherViews ()) && !IsInitialized)
-            {
-                Debug.WriteLine (
-                                 $"WARNING: The dimensions of {this} are dependent on other views and Viewport is being accessed before the View has been initialized. This is likely a bug."
-                                );
-            }
-#endif // DEBUG
+//#if DEBUG
+//            if ((_width.ReferencesOtherViews () || _height.ReferencesOtherViews ()) && !IsInitialized)
+//            {
+//                Debug.WriteLine (
+//                                 $"WARNING: The dimensions of {this} are dependent on other views and Viewport is being accessed before the View has been initialized. This is likely a bug."
+//                                );
+//            }
+//#endif // DEBUG
 
 
             if (Margin is null || Border is null || Padding is null)
             if (Margin is null || Border is null || Padding is null)
             {
             {

+ 22 - 15
Terminal.Gui/Views/Dialog.cs

@@ -75,8 +75,14 @@ public class Dialog : Window
                                               return true;
                                               return true;
                                           });
                                           });
         KeyBindings.Add (Key.Esc, Command.QuitToplevel);
         KeyBindings.Add (Key.Esc, Command.QuitToplevel);
+
+        Initialized += Dialog_Initialized; ;
     }
     }
 
 
+    private void Dialog_Initialized (object sender, EventArgs e)
+    {
+        LayoutButtons ();
+    }
 
 
     private bool _canceled;
     private bool _canceled;
 
 
@@ -158,18 +164,19 @@ public class Dialog : Window
     }
     }
 
 
     /// <inheritdoc/>
     /// <inheritdoc/>
-    public override void LayoutSubviews ()
-    {
-        if (_inLayout)
-        {
-            return;
-        }
-
-        _inLayout = true;
-        LayoutButtons ();
-        base.LayoutSubviews ();
-        _inLayout = false;
-    }
+    //public override void LayoutSubviews ()
+    //{
+    //    if (_inLayout)
+    //    {
+    //        return;
+    //    }
+
+    //    _inLayout = true;
+    //    SetRelativeLayout(SuperView?.ContentSize ?? Driver.Screen.Size);
+    //    LayoutButtons ();
+    //    base.LayoutSubviews ();
+    //    _inLayout = false;
+    //}
 
 
     // Get the width of all buttons, not including any Margin.
     // Get the width of all buttons, not including any Margin.
     internal int GetButtonsWidth ()
     internal int GetButtonsWidth ()
@@ -216,7 +223,7 @@ public class Dialog : Window
                         button.X = Viewport.Width - shiftLeft;
                         button.X = Viewport.Width - shiftLeft;
                     }
                     }
 
 
-                    button.Y = Pos.AnchorEnd (1);
+                    button.Y = Pos.AnchorEnd ();
                 }
                 }
 
 
                 break;
                 break;
@@ -251,7 +258,7 @@ public class Dialog : Window
                         }
                         }
                     }
                     }
 
 
-                    button.Y = Pos.AnchorEnd (1);
+                    button.Y = Pos.AnchorEnd ();
                 }
                 }
 
 
                 break;
                 break;
@@ -283,7 +290,7 @@ public class Dialog : Window
                     Button button = _buttons [i];
                     Button button = _buttons [i];
                     shiftLeft += button.Frame.Width + 1;
                     shiftLeft += button.Frame.Width + 1;
                     button.X = Pos.AnchorEnd (shiftLeft);
                     button.X = Pos.AnchorEnd (shiftLeft);
-                    button.Y = Pos.AnchorEnd (1);
+                    button.Y = Pos.AnchorEnd ();
                 }
                 }
 
 
                 break;
                 break;

+ 14 - 63
Terminal.Gui/Views/MessageBox.cs

@@ -344,8 +344,8 @@ public static class MessageBox
             Buttons = buttonList.ToArray (),
             Buttons = buttonList.ToArray (),
             Title = title,
             Title = title,
             BorderStyle = DefaultBorderStyle,
             BorderStyle = DefaultBorderStyle,
-            Width = Dim.Percent (60),
-            Height = 5 // Border + one line of text + vspace + buttons
+            Width = Dim.Auto (DimAutoStyle.Content),
+            Height = Dim.Auto (DimAutoStyle.Content), 
         };
         };
 
 
         if (width != 0)
         if (width != 0)
@@ -372,17 +372,26 @@ public static class MessageBox
             Text = message,
             Text = message,
             TextAlignment = TextAlignment.Centered,
             TextAlignment = TextAlignment.Centered,
             X = Pos.Center (),
             X = Pos.Center (),
-            Y = 0
+            Y = 0,
+           // ColorScheme = Colors.ColorSchemes ["Error"]
         };
         };
 
 
+        messageLabel.TextFormatter.WordWrap = wrapMessage;
+        messageLabel.TextFormatter.MultiLine = !wrapMessage;
+
         if (wrapMessage)
         if (wrapMessage)
         {
         {
             messageLabel.Width = Dim.Fill ();
             messageLabel.Width = Dim.Fill ();
             messageLabel.Height = Dim.Fill (1);
             messageLabel.Height = Dim.Fill (1);
+            int GetWrapSize ()
+            {
+                // A bit of a hack to get the height of the wrapped text.
+                messageLabel.TextFormatter.Size = new (d.ContentSize.Width, 1000);
+                return messageLabel.TextFormatter.FormatAndGetSize ().Height;
+            }
+            d.Height = Dim.Auto (DimAutoStyle.Content, minimumContentDim: Dim.Func (GetWrapSize) + 1);
         }
         }
 
 
-        messageLabel.TextFormatter.WordWrap = wrapMessage;
-        messageLabel.TextFormatter.MultiLine = !wrapMessage;
         d.Add (messageLabel);
         d.Add (messageLabel);
 
 
         // Setup actions
         // Setup actions
@@ -405,69 +414,11 @@ public static class MessageBox
             }
             }
         }
         }
 
 
-        d.Loaded += Dialog_Loaded;
-
         // Run the modal; do not shutdown the mainloop driver when done
         // Run the modal; do not shutdown the mainloop driver when done
         Application.Run (d);
         Application.Run (d);
         d.Dispose ();
         d.Dispose ();
 
 
         return Clicked;
         return Clicked;
 
 
-        void Dialog_Loaded (object s, EventArgs e)
-        {
-            if (width != 0 || height != 0)
-            {
-                return;
-            }
-
-            // TODO: replace with Dim.Fit when implemented
-            Rectangle maxBounds = d.SuperView?.Viewport ?? Application.Top.Viewport;
-
-            Thickness adornmentsThickness = d.GetAdornmentsThickness ();
-
-            if (wrapMessage)
-            {
-                messageLabel.TextFormatter.Size = new (
-                                                       maxBounds.Size.Width
-                                                       - adornmentsThickness.Horizontal,
-                                                       maxBounds.Size.Height
-                                                       - adornmentsThickness.Vertical);
-            }
-
-            string msg = messageLabel.TextFormatter.Format ();
-            Size messageSize = messageLabel.TextFormatter.FormatAndGetSize ();
-
-            // Ensure the width fits the text + buttons
-            int newWidth = Math.Max (
-                                     width,
-                                     Math.Max (
-                                               messageSize.Width + adornmentsThickness.Horizontal,
-                                               d.GetButtonsWidth () + d.Buttons.Length + adornmentsThickness.Horizontal));
-
-            if (newWidth > d.Frame.Width)
-            {
-                d.Width = newWidth;
-            }
-
-            // Ensure height fits the text + vspace + buttons
-            if (messageSize.Height == 0)
-            {
-                d.Height = Math.Max (height, 3 + adornmentsThickness.Vertical);
-            }
-            else
-            {
-                string lastLine = messageLabel.TextFormatter.GetLines () [^1];
-
-                // INTENT: Instead of the check against \n or \r\n, how about just Environment.NewLine?
-                d.Height = Math.Max (
-                                     height,
-                                     messageSize.Height
-                                     + (lastLine.EndsWith ("\r\n") || lastLine.EndsWith ('\n') ? 1 : 2)
-                                     + adornmentsThickness.Vertical);
-            }
-
-            d.SetRelativeLayout (d.SuperView?.ContentSize ?? Application.Top.ContentSize);
-            d.LayoutSubviews ();
-        }
     }
     }
 }
 }

+ 1 - 1
UICatalog/Scenarios/DimAutoDemo.cs

@@ -153,7 +153,7 @@ public class DimAutoDemo : Scenario
         {
         {
             Text = "_Reset Button (AnchorEnd)",
             Text = "_Reset Button (AnchorEnd)",
             X = Pos.AnchorEnd (),
             X = Pos.AnchorEnd (),
-            Y = Pos.AnchorEnd ()
+            Y = Pos.AnchorEnd (1)
         };
         };
 
 
         resetButton.Accept += (s, e) => { movingButton.Y = Pos.Bottom (hlabel); };
         resetButton.Accept += (s, e) => { movingButton.Y = Pos.Bottom (hlabel); };

+ 2 - 2
UICatalog/Scenarios/MessageBoxes.cs

@@ -114,7 +114,7 @@ public class MessageBoxes : Scenario
 
 
         var messageEdit = new TextView
         var messageEdit = new TextView
         {
         {
-            Text = "Message",
+            Text = "Message line 1.\nMessage line two. This is a really long line to force wordwrap. It needs to be long for it to work.",
             X = Pos.Right (label) + 1,
             X = Pos.Right (label) + 1,
             Y = Pos.Top (label),
             Y = Pos.Top (label),
             Width = Dim.Fill (),
             Width = Dim.Fill (),
@@ -186,7 +186,7 @@ public class MessageBoxes : Scenario
 
 
         var ckbWrapMessage = new CheckBox
         var ckbWrapMessage = new CheckBox
         {
         {
-            X = Pos.Right (label) + 1, Y = Pos.Bottom (styleRadioGroup), Text = "_Wrap Message", Checked = true
+            X = Pos.Right (label) + 1, Y = Pos.Bottom (styleRadioGroup), Text = "_Wrap Message", Checked = false
         };
         };
         frame.Add (ckbWrapMessage);
         frame.Add (ckbWrapMessage);