diff --git a/Terminal.Gui/View/Layout/ViewLayout.cs b/Terminal.Gui/View/Layout/ViewLayout.cs index 0a6c7a7fd..10bbac7fc 100644 --- a/Terminal.Gui/View/Layout/ViewLayout.cs +++ b/Terminal.Gui/View/Layout/ViewLayout.cs @@ -87,6 +87,8 @@ public partial class View return null; } + // BUGBUG: This method interferes with Dialog/MessageBox default min/max size. + /// /// Gets a new location of the that is within the Viewport of the 's /// (e.g. for dragging a Window). The `out` parameters are the new X and Y coordinates. diff --git a/Terminal.Gui/Views/MessageBox.cs b/Terminal.Gui/Views/MessageBox.cs index a9d0b542a..03339a957 100644 --- a/Terminal.Gui/Views/MessageBox.cs +++ b/Terminal.Gui/Views/MessageBox.cs @@ -36,18 +36,18 @@ public static class MessageBox public static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single; /// - /// Defines the default minimum MessageBox width, as a percentage of the container width. Can be configured via + /// Defines the default minimum MessageBox width, as a percentage of the screen width. Can be configured via /// . /// [SerializableConfigurationProperty (Scope = typeof (ThemeScope))] - public static int DefaultMinimumWidth { get; set; } = 60; + public static int DefaultMinimumWidth { get; set; } = 0; /// - /// Defines the default minimum Dialog height, as a percentage of the container width. Can be configured via + /// Defines the default minimum Dialog height, as a percentage of the screen width. Can be configured via /// . /// [SerializableConfigurationProperty (Scope = typeof (ThemeScope))] - public static int DefaultMinimumHeight { get; set; } = 5; + public static int DefaultMinimumHeight { get; set; } = 0; /// /// The index of the selected button, or -1 if the user pressed to close the MessageBox. This is useful for web /// based console where there is no SynchronizationContext or TaskScheduler. @@ -369,10 +369,17 @@ public static class MessageBox ButtonAlignment = Alignment.Center, ButtonAlignmentModes = AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, BorderStyle = MessageBox.DefaultBorderStyle, - Width = Dim.Auto (DimAutoStyle.Auto, /*minimumContentDim: Dim.Percent (DefaultMinimumWidth), */ maximumContentDim: Dim.Percent (90)), - Height = Dim.Auto (DimAutoStyle.Auto, /*minimumContentDim: Dim.Percent (DefaultMinimumHeight),*/ maximumContentDim: Dim.Percent (90)), }; + d.Width = Dim.Auto (DimAutoStyle.Auto, + minimumContentDim: Dim.Func (() => (int)((Application.Screen.Width - d.GetAdornmentsThickness ().Horizontal) * (DefaultMinimumWidth / 100f) )), + maximumContentDim: Dim.Func (() => (int)((Application.Screen.Width - d.GetAdornmentsThickness ().Horizontal) * 0.9f))); + + d.Height = Dim.Auto (DimAutoStyle.Auto, + minimumContentDim: Dim.Func (() => (int)((Application.Screen.Height - d.GetAdornmentsThickness ().Vertical) * (DefaultMinimumHeight / 100f))), + maximumContentDim: Dim.Func (() => (int)((Application.Screen.Height - d.GetAdornmentsThickness ().Vertical) * 0.9f))); + + if (width != 0) { d.Width = width; diff --git a/UICatalog/Scenarios/Dialogs.cs b/UICatalog/Scenarios/Dialogs.cs index 26764b8a8..096cc1ec4 100644 --- a/UICatalog/Scenarios/Dialogs.cs +++ b/UICatalog/Scenarios/Dialogs.cs @@ -83,7 +83,7 @@ public class Dialogs : Scenario { X = Pos.Right (widthEdit) + 2, Y = Pos.Top (widthEdit), - Text = $"If width is 0, the dimension will be {Dialog.DefaultMinimumWidth}%." + Text = $"If width is 0, the dimension will be greater than {Dialog.DefaultMinimumWidth}%." } ); @@ -92,7 +92,7 @@ public class Dialogs : Scenario { X = Pos.Right (heightEdit) + 2, Y = Pos.Top (heightEdit), - Text = $"If height is 0, the dimension will be {Dialog.DefaultMinimumWidth}%." + Text = $"If height is 0, the dimension will be greater {Dialog.DefaultMinimumHeight}%." } ); diff --git a/UICatalog/Scenarios/MessageBoxes.cs b/UICatalog/Scenarios/MessageBoxes.cs index b1e16a97b..e2e8f941f 100644 --- a/UICatalog/Scenarios/MessageBoxes.cs +++ b/UICatalog/Scenarios/MessageBoxes.cs @@ -15,7 +15,7 @@ public class MessageBoxes : Scenario Window app = new () { - Title = GetQuitKeyAndName () + Title = GetQuitKeyAndName (), }; var frame = new FrameView @@ -69,7 +69,7 @@ public class MessageBoxes : Scenario { X = Pos.Right (widthEdit) + 2, Y = Pos.Top (widthEdit), - Text = $"If width is 0, the dimension will be {MessageBox.DefaultMinimumWidth}%." + Text = $"If width is 0, the dimension will be greater than {MessageBox.DefaultMinimumWidth}%." } ); @@ -78,7 +78,7 @@ public class MessageBoxes : Scenario { X = Pos.Right (heightEdit) + 2, Y = Pos.Top (heightEdit), - Text = $"If height is 0, the dimension will be {MessageBox.DefaultMinimumWidth}%." + Text = $"If height is 0, the dimension will be greater than {MessageBox.DefaultMinimumHeight}%." } ); diff --git a/UnitTests/Dialogs/MessageBoxTests.cs b/UnitTests/Dialogs/MessageBoxTests.cs index f32f7074a..8638fae69 100644 --- a/UnitTests/Dialogs/MessageBoxTests.cs +++ b/UnitTests/Dialogs/MessageBoxTests.cs @@ -1,4 +1,5 @@ using System.Text; +using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities; using Xunit.Abstractions; namespace Terminal.Gui.DialogTests; @@ -120,199 +121,48 @@ public class MessageBoxTests Assert.Equal (1, result); } - [Fact (Skip = "Pos.Align WIP")] + [Theory] + [InlineData (@"", false, false, 6, 6, 2, 2)] + [InlineData (@"", false, true, 3, 6, 9, 3)] + [InlineData (@"01234\n-----\n01234", false, false, 1, 6, 13, 3)] + [InlineData (@"01234\n-----\n01234", true, false, 1, 5, 13, 4)] + [InlineData (@"0123456789", false, false, 1, 6, 12, 3)] + [InlineData (@"0123456789", false, true, 1, 5, 12, 4)] + [InlineData (@"01234567890123456789", false, true, 1, 5, 13, 4)] + [InlineData (@"01234567890123456789", true, true, 1, 5, 13, 5)] + [InlineData (@"01234567890123456789\n01234567890123456789", false, true, 1, 5, 13, 4)] + [InlineData (@"01234567890123456789\n01234567890123456789", true, true, 1, 4, 13, 7)] [AutoInitShutdown] - public void Location_Default () + public void Location_And_Size_Correct (string message, bool wrapMessage, bool hasButton, int expectedX, int expectedY, int expectedW, int expectedH) { int iterations = -1; - ((FakeDriver)Application.Driver).SetBufferSize (100, 100); + + ((FakeDriver)Application.Driver).SetBufferSize (15, 15); // 15 x 15 gives us enough room for a button with one char (9x1) + + Rectangle mbFrame = Rectangle.Empty; Application.Iteration += (s, a) => - { - iterations++; + { + iterations++; - if (iterations == 0) - { - MessageBox.Query (string.Empty, string.Empty, null); - - Application.RequestStop (); - } - else if (iterations == 1) - { - Application.Refresh (); - - Assert.IsType (Application.Current); - - // Default location is centered, so - // X = (100 / 2) - (60 / 2) = 20 - // Y = (100 / 2) - (5 / 2) = 47 - Assert.Equal (new Point (20, 47), (Point)Application.Current.Frame.Location); - - Application.RequestStop (); - } - }; + if (iterations == 0) + { + MessageBox.Query (string.Empty, message, 0, wrapMessage, hasButton ? ["0"] : []); + Application.RequestStop (); + } + else if (iterations == 1) + { + mbFrame = Application.Current.Frame; + Application.RequestStop (); + } + }; Application.Run ().Dispose (); + + Assert.Equal (new (expectedX, expectedY, expectedW, expectedH), mbFrame); } - - [Theory (Skip = "Pos.Align WIP")] - [AutoInitShutdown] - [InlineData (" ", true, 1)] - [InlineData (" ", false, 1)] - [InlineData ("", true, 1)] - [InlineData ("", false, 1)] - [InlineData ("\n", true, 1)] - [InlineData ("\n", false, 1)] - [InlineData (" \n", true, 1)] - [InlineData (" \n", false, 2)] - public void Message_Empty_Or_A_NewLline_WrapMessagge_True_Or_False ( - string message, - bool wrapMessage, - int linesLength - ) - { - int iterations = -1; - - Application.Iteration += (s, a) => - { - iterations++; - - if (iterations == 0) - { - MessageBox.Query (string.Empty, message, 0, wrapMessage, "ok"); - - Application.RequestStop (); - } - else if (iterations == 1) - { - Application.Refresh (); - - if (linesLength == 1) - { - TestHelpers.AssertDriverContentsWithFrameAre ( - @$" - ┌──────────────────────────────────────────────┐ - │ │ - │ │ - │ { - CM.Glyphs.LeftBracket - }{ - CM.Glyphs.LeftDefaultIndicator - } ok { - CM.Glyphs.RightDefaultIndicator - }{ - CM.Glyphs.RightBracket - } │ - └──────────────────────────────────────────────┘", - _output - ); - } - else - { - TestHelpers.AssertDriverContentsWithFrameAre ( - @$" - ┌──────────────────────────────────────────────┐ - │ │ - │ │ - │ │ - │ { - CM.Glyphs.LeftBracket - }{ - CM.Glyphs.LeftDefaultIndicator - } ok { - CM.Glyphs.RightDefaultIndicator - }{ - CM.Glyphs.RightBracket - } │ - └──────────────────────────────────────────────┘", - _output - ); - } - - Application.RequestStop (); - } - }; - - Application.Run ().Dispose (); - } - - [Fact (Skip = "Pos.Align WIP")] - [AutoInitShutdown] - public void Message_Long_Without_Spaces_WrapMessage_True () - { - int iterations = -1; - var top = new Toplevel (); - top.BorderStyle = LineStyle.None; - ((FakeDriver)Application.Driver).SetBufferSize (20, 10); - - var btn = - $"{ - CM.Glyphs.LeftBracket - }{ - CM.Glyphs.LeftDefaultIndicator - } btn { - CM.Glyphs.RightDefaultIndicator - }{ - CM.Glyphs.RightBracket - }"; - - Application.Iteration += (s, a) => - { - iterations++; - - if (iterations == 0) - { - // 50 characters should make the height of the wrapped text 7 - MessageBox.Query (string.Empty, new string ('f', 50), 0, true, "btn"); - - Application.RequestStop (); - } - else if (iterations == 1) - { - Application.Refresh (); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @$" -┌──────────────────┐ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ ffffffffffffff │ -│ │ -│ {btn} │ -└──────────────────┘", - _output - ); - Application.RequestStop (); - - // Really long text - MessageBox.Query (string.Empty, new string ('f', 500), 0, true, "btn"); - } - else if (iterations == 2) - { - Application.Refresh (); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @$" -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ {btn} │", - _output - ); - Application.RequestStop (); - } - }; - - Application.Run (top); - } - - [Fact (Skip = "Pos.Align WIP")] + + [Fact] [AutoInitShutdown] public void Message_With_Spaces_WrapMessage_False () { @@ -322,15 +172,7 @@ public class MessageBoxTests ((FakeDriver)Application.Driver).SetBufferSize (20, 10); var btn = - $"{ - CM.Glyphs.LeftBracket - }{ - CM.Glyphs.LeftDefaultIndicator - } btn { - CM.Glyphs.RightDefaultIndicator - }{ - CM.Glyphs.RightBracket - }"; + $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}"; Application.Iteration += (s, a) => { @@ -353,15 +195,12 @@ public class MessageBoxTests { Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre ( - @" -──────────────────── -ff ff ff ff ff ff ff - - ⟦► btn ◄⟧ -──────────────────── -", - _output + TestHelpers.AssertDriverContentsWithFrameAre (@" + ╔════════════════╗ + ║ ff ff ff ff ff ║ + ║ ⟦► btn ◄⟧║ + ╚════════════════╝", + _output ); Application.RequestStop (); @@ -374,12 +213,10 @@ ff ff ff ff ff ff ff TestHelpers.AssertDriverContentsWithFrameAre ( @" -──────────────────── -ffffffffffffffffffff - - ⟦► btn ◄⟧ -──────────────────── -", + ╔════════════════╗ + ║ffffffffffffffff║ + ║ ⟦► btn ◄⟧║ + ╚════════════════╝", _output ); Application.RequestStop (); @@ -389,25 +226,17 @@ ffffffffffffffffffff Application.Run (top); } - [Fact (Skip = "Pos.Align WIP")] + [Fact] [AutoInitShutdown] public void Message_With_Spaces_WrapMessage_True () { int iterations = -1; - var top = new Toplevel(); + var top = new Toplevel (); top.BorderStyle = LineStyle.None; ((FakeDriver)Application.Driver).SetBufferSize (20, 10); var btn = - $"{ - CM.Glyphs.LeftBracket - }{ - CM.Glyphs.LeftDefaultIndicator - } btn { - CM.Glyphs.RightDefaultIndicator - }{ - CM.Glyphs.RightBracket - }"; + $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}"; Application.Iteration += (s, a) => { @@ -430,14 +259,14 @@ ffffffffffffffffffff { Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@$" -┌─────────────────┐ -│ff ff ff ff ff ff│ -│ff ff ff ff ff ff│ -│ ff ff ff ff ff │ -│ │ -│ {btn} │ -└─────────────────┘", + TestHelpers.AssertDriverContentsWithFrameAre (@" + ╔══════════════╗ + ║ff ff ff ff ff║ + ║ff ff ff ff ff║ + ║ff ff ff ff ff║ + ║ ff ff ║ + ║ ⟦► btn ◄⟧║ + ╚══════════════╝", _output ); Application.RequestStop (); @@ -450,16 +279,15 @@ ffffffffffffffffffff Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@$" -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ffffffffffffffffff│ -│ {btn} │", + ╔════════════════╗ + ║ffffffffffffffff║ + ║ffffffffffffffff║ + ║ffffffffffffffff║ + ║ffffffffffffffff║ + ║ffffffffffffffff║ + ║ffffffffffffffff║ + ║fffffff⟦► btn ◄⟧║ + ╚════════════════╝", _output ); Application.RequestStop (); @@ -469,261 +297,7 @@ ffffffffffffffffffff Application.Run (top); top.Dispose (); } - - [Fact (Skip = "Pos.Align WIP")] - [AutoInitShutdown] - public void Message_Without_Spaces_WrapMessage_False () - { - int iterations = -1; - var top = new Toplevel(); - top.BorderStyle = LineStyle.None; - ((FakeDriver)Application.Driver).SetBufferSize (20, 10); - - var btn = - $"{ - CM.Glyphs.LeftBracket - }{ - CM.Glyphs.LeftDefaultIndicator - } btn { - CM.Glyphs.RightDefaultIndicator - }{ - CM.Glyphs.RightBracket - }"; - - Application.Iteration += (s, a) => - { - iterations++; - - if (iterations == 0) - { - MessageBox.Query (string.Empty, new string ('f', 50), 0, false, "btn"); - - Application.RequestStop (); - } - else if (iterations == 1) - { - Application.Refresh (); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @" -──────────────────── -ffffffffffffffffffff - - ⟦► btn ◄⟧ -──────────────────── -", - _output - ); - - Application.RequestStop (); - - // Really long text - MessageBox.Query (string.Empty, new string ('f', 500), 0, false, "btn"); - } - else if (iterations == 2) - { - Application.Refresh (); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @" -──────────────────── -ffffffffffffffffffff - - ⟦► btn ◄⟧ -──────────────────── -", - _output - ); - - Application.RequestStop (); - } - }; - - Application.Run (top); - } - - [Fact (Skip = "Pos.Align WIP")] - [AutoInitShutdown] - public void Size_Default () - { - int iterations = -1; - ((FakeDriver)Application.Driver).SetBufferSize (100, 100); - - Application.Iteration += (s, a) => - { - iterations++; - - if (iterations == 0) - { - MessageBox.Query (string.Empty, string.Empty, null); - - Application.RequestStop (); - } - else if (iterations == 1) - { - Application.Refresh (); - - Assert.IsType (Application.Current); - - // Default size is Percent(60) - Assert.Equal (new ((int)(100 * .60), 5), Application.Current.Frame.Size); - - Application.RequestStop (); - } - }; - - Application.Run ().Dispose (); - } - - [Fact (Skip = "Pos.Align WIP")] - [AutoInitShutdown] - public void Size_JustBigEnough_Fixed_Size () - { - int iterations = -1; - - var btn = - $"{ - CM.Glyphs.LeftBracket - }{ - CM.Glyphs.LeftDefaultIndicator - } Ok { - CM.Glyphs.RightDefaultIndicator - }{ - CM.Glyphs.RightBracket - }"; - - Application.Iteration += (s, a) => - { - iterations++; - - if (iterations == 0) - { - MessageBox.Query (11, 5, string.Empty, "Message", "_Ok"); - - Application.RequestStop (); - } - else if (iterations == 1) - { - Application.Refresh (); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @$" - ┌─────────┐ - │ Message │ - │ │ - │{ - btn - } │ - └─────────┘ -", - _output - ); - - Application.RequestStop (); - } - }; - - Application.Run ().Dispose (); - } - - [Fact (Skip = "Pos.Align WIP")] - [AutoInitShutdown] - public void Size_No_With_Button () - { - var top = new Toplevel (); - top.BorderStyle = LineStyle.None; - int iterations = -1; - - var aboutMessage = new StringBuilder (); - aboutMessage.AppendLine (@"0123456789012345678901234567890123456789"); - aboutMessage.AppendLine (@"https://github.com/gui-cs/Terminal.Gui"); - var message = aboutMessage.ToString (); - - var btn = - $"{ - CM.Glyphs.LeftBracket - }{ - CM.Glyphs.LeftDefaultIndicator - } Ok { - CM.Glyphs.RightDefaultIndicator - }{ - CM.Glyphs.RightBracket - }"; - - ((FakeDriver)Application.Driver).SetBufferSize (40 + 4, 8); - - Application.Iteration += (s, a) => - { - iterations++; - - if (iterations == 0) - { - MessageBox.Query (string.Empty, message, "_Ok"); - - Application.RequestStop (); - } - else if (iterations == 1) - { - Application.Refresh (); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @$" - ┌────────────────────────────────────────┐ - │0123456789012345678901234567890123456789│ - │ https://github.com/gui-cs/Terminal.Gui │ - │ │ - │ {btn} │ - └────────────────────────────────────────┘ -", - _output - ); - - Application.RequestStop (); - } - }; - - Application.Run (top); - top.Dispose (); - } - - [Fact (Skip = "Pos.Align WIP")] - [AutoInitShutdown] - public void Size_None_No_Buttons () - { - int iterations = -1; - - Application.Iteration += (s, a) => - { - iterations++; - - if (iterations == 0) - { - MessageBox.Query ("Title", "Message"); - - Application.RequestStop (); - } - else if (iterations == 1) - { - Application.Refresh (); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @" - ┌┤Title├───────────────────────────────────────┐ - │ Message │ - │ │ - │ │ - └──────────────────────────────────────────────┘ -", - _output - ); - - Application.RequestStop (); - } - }; - - Application.Run ().Dispose (); - } - + [Theory] [InlineData (0, 0, "1")] [InlineData (1, 1, "1")] @@ -832,45 +406,45 @@ ffffffffffffffffffff } // TODO: Reimplement once messagebox ues Dim.Auto -// [Fact] -// [AutoInitShutdown] -// public void Size_Tiny_Fixed_Size () -// { -// int iterations = -1; + // [Fact] + // [AutoInitShutdown] + // public void Size_Tiny_Fixed_Size () + // { + // int iterations = -1; -// Application.Iteration += (s, a) => -// { -// iterations++; + // Application.Iteration += (s, a) => + // { + // iterations++; -// if (iterations == 0) -// { -// MessageBox.Query (7, 5, string.Empty, "Message", "_Ok"); + // if (iterations == 0) + // { + // MessageBox.Query (7, 5, string.Empty, "Message", "_Ok"); -// Application.RequestStop (); -// } -// else if (iterations == 1) -// { -// Application.Refresh (); + // Application.RequestStop (); + // } + // else if (iterations == 1) + // { + // Application.Refresh (); -// Assert.Equal (new (7, 5), Application.Current.Frame.Size); + // Assert.Equal (new (7, 5), Application.Current.Frame.Size); -// TestHelpers.AssertDriverContentsWithFrameAre ( -// @$" -// ┌─────┐ -// │Messa│ -// │ ge │ -// │ Ok { -// CM.Glyphs.RightDefaultIndicator -// }│ -// └─────┘ -//", -// _output -// ); + // TestHelpers.AssertDriverContentsWithFrameAre ( + // @$" + // ┌─────┐ + // │Messa│ + // │ ge │ + // │ Ok { + // CM.Glyphs.RightDefaultIndicator + // }│ + // └─────┘ + //", + // _output + // ); -// Application.RequestStop (); -// } -// }; + // Application.RequestStop (); + // } + // }; -// Application.Run ().Dispose (); -// } + // Application.Run ().Dispose (); + // } }