ソースを参照

Fixes #2403. Dialog not draw text well if is opened on a smaller width.

BDisp 2 年 前
コミット
e69aa25ddd

+ 31 - 22
Terminal.Gui/Windows/MessageBox.cs

@@ -38,7 +38,7 @@ namespace Terminal.Gui {
 		/// </remarks>
 		public static int Query (int width, int height, ustring title, ustring message, params ustring [] buttons)
 		{
-			return QueryFull (false, width, height, title, message, 0, null, buttons);
+			return QueryFull (false, width, height, title, message, 0, null, true, buttons);
 		}
 
 		/// <summary>
@@ -54,7 +54,7 @@ namespace Terminal.Gui {
 		/// </remarks>
 		public static int Query (ustring title, ustring message, params ustring [] buttons)
 		{
-			return QueryFull (false, 0, 0, title, message, 0, null, buttons);
+			return QueryFull (false, 0, 0, title, message, 0, null, true, buttons);
 		}
 
 		/// <summary>
@@ -71,7 +71,7 @@ namespace Terminal.Gui {
 		/// </remarks>
 		public static int ErrorQuery (int width, int height, ustring title, ustring message, params ustring [] buttons)
 		{
-			return QueryFull (true, width, height, title, message, 0, null, buttons);
+			return QueryFull (true, width, height, title, message, 0, null, true, buttons);
 		}
 
 		/// <summary>
@@ -87,7 +87,7 @@ namespace Terminal.Gui {
 		/// </remarks>
 		public static int ErrorQuery (ustring title, ustring message, params ustring [] buttons)
 		{
-			return QueryFull (true, 0, 0, title, message, 0, null, buttons);
+			return QueryFull (true, 0, 0, title, message, 0, null, true, buttons);
 		}
 
 		/// <summary>
@@ -105,7 +105,7 @@ namespace Terminal.Gui {
 		/// </remarks>
 		public static int Query (int width, int height, ustring title, ustring message, int defaultButton = 0, params ustring [] buttons)
 		{
-			return QueryFull (false, width, height, title, message, defaultButton, null, buttons);
+			return QueryFull (false, width, height, title, message, defaultButton, null, true, buttons);
 		}
 
 		/// <summary>
@@ -122,7 +122,7 @@ namespace Terminal.Gui {
 		/// </remarks>
 		public static int Query (ustring title, ustring message, int defaultButton = 0, params ustring [] buttons)
 		{
-			return QueryFull (false, 0, 0, title, message, defaultButton, null, buttons);
+			return QueryFull (false, 0, 0, title, message, defaultButton, null, true, buttons);
 		}
 
 		/// <summary>
@@ -139,9 +139,9 @@ namespace Terminal.Gui {
 		/// <remarks>
 		/// Use <see cref="Query(ustring, ustring, ustring[])"/> instead; it automatically sizes the MessageBox based on the contents.
 		/// </remarks>
-		public static int Query (int width, int height, ustring title, ustring message, int defaultButton = 0, Border border = null, params ustring [] buttons)
+		public static int Query (int width, int height, ustring title, ustring message, int defaultButton = 0, Border border = null, bool wrapMessagge = true, params ustring [] buttons)
 		{
-			return QueryFull (false, width, height, title, message, defaultButton, border, buttons);
+			return QueryFull (false, width, height, title, message, defaultButton, border, wrapMessagge, buttons);
 		}
 
 		/// <summary>
@@ -157,9 +157,9 @@ namespace Terminal.Gui {
 		/// The message box will be vertically and horizontally centered in the container and the size will be automatically determined
 		/// from the size of the message and buttons.
 		/// </remarks>
-		public static int Query (ustring title, ustring message, int defaultButton = 0, Border border = null, params ustring [] buttons)
+		public static int Query (ustring title, ustring message, int defaultButton = 0, Border border = null, bool wrapMessagge = true, params ustring [] buttons)
 		{
-			return QueryFull (false, 0, 0, title, message, defaultButton, border, buttons);
+			return QueryFull (false, 0, 0, title, message, defaultButton, border, wrapMessagge, buttons);
 		}
 
 
@@ -178,7 +178,7 @@ namespace Terminal.Gui {
 		/// </remarks>
 		public static int ErrorQuery (int width, int height, ustring title, ustring message, int defaultButton = 0, params ustring [] buttons)
 		{
-			return QueryFull (true, width, height, title, message, defaultButton, null, buttons);
+			return QueryFull (true, width, height, title, message, defaultButton, null, true, buttons);
 		}
 
 		/// <summary>
@@ -195,7 +195,7 @@ namespace Terminal.Gui {
 		/// </remarks>
 		public static int ErrorQuery (ustring title, ustring message, int defaultButton = 0, params ustring [] buttons)
 		{
-			return QueryFull (true, 0, 0, title, message, defaultButton, null, buttons);
+			return QueryFull (true, 0, 0, title, message, defaultButton, null, true, buttons);
 		}
 
 		/// <summary>
@@ -212,9 +212,9 @@ namespace Terminal.Gui {
 		/// <remarks>
 		/// Use <see cref="ErrorQuery(ustring, ustring, ustring[])"/> instead; it automatically sizes the MessageBox based on the contents.
 		/// </remarks>
-		public static int ErrorQuery (int width, int height, ustring title, ustring message, int defaultButton = 0, Border border = null, params ustring [] buttons)
+		public static int ErrorQuery (int width, int height, ustring title, ustring message, int defaultButton = 0, Border border = null, bool wrapMessagge = true, params ustring [] buttons)
 		{
-			return QueryFull (true, width, height, title, message, defaultButton, border, buttons);
+			return QueryFull (true, width, height, title, message, defaultButton, border, wrapMessagge, buttons);
 		}
 
 		/// <summary>
@@ -230,20 +230,20 @@ namespace Terminal.Gui {
 		/// The message box will be vertically and horizontally centered in the container and the size will be automatically determined
 		/// from the size of the title, message. and buttons.
 		/// </remarks>
-		public static int ErrorQuery (ustring title, ustring message, int defaultButton = 0, Border border = null, params ustring [] buttons)
+		public static int ErrorQuery (ustring title, ustring message, int defaultButton = 0, Border border = null, bool wrapMessagge = true, params ustring [] buttons)
 		{
-			return QueryFull (true, 0, 0, title, message, defaultButton, border, buttons);
+			return QueryFull (true, 0, 0, title, message, defaultButton, border, wrapMessagge, buttons);
 		}
 
 		static int QueryFull (bool useErrorColors, int width, int height, ustring title, ustring message,
-			int defaultButton = 0, Border border = null, params ustring [] buttons)
+			int defaultButton = 0, Border border = null, bool wrapMessagge = true, params ustring [] buttons)
 		{
 			int defaultWidth = 50;
 			if (defaultWidth > Application.Driver.Cols / 2) {
 				defaultWidth = (int)(Application.Driver.Cols * 0.60f);
 			}
 			int maxWidthLine = TextFormatter.MaxWidthLine (message);
-			if (maxWidthLine > Application.Driver.Cols) {
+			if (wrapMessagge && maxWidthLine > Application.Driver.Cols) {
 				maxWidthLine = Application.Driver.Cols;
 			}
 			if (width == 0) {
@@ -251,10 +251,14 @@ namespace Terminal.Gui {
 			} else {
 				maxWidthLine = width;
 			}
-			int textWidth = Math.Min (TextFormatter.MaxWidth (message, maxWidthLine), Application.Driver.Cols);
+			int textWidth = TextFormatter.MaxWidth (message, maxWidthLine);
 			int textHeight = TextFormatter.MaxLines (message, textWidth); // message.Count (ustring.Make ('\n')) + 1;
-			int msgboxHeight = Math.Min (Math.Max (1, textHeight) + 4, Application.Driver.Rows); // textHeight + (top + top padding + buttons + bottom)
+			int msgboxHeight = Math.Max (1, textHeight) + 4; // textHeight + (top + top padding + buttons + bottom)
 
+			if (wrapMessagge) {
+				textWidth = Math.Min (textWidth, Application.Driver.Cols);
+				msgboxHeight = Math.Min (msgboxHeight, Application.Driver.Rows);
+			}
 			// Create button array for Dialog
 			int count = 0;
 			List<Button> buttonList = new List<Button> ();
@@ -288,7 +292,7 @@ namespace Terminal.Gui {
 				d.ColorScheme = Colors.Error;
 			}
 
-			if (message != null) {
+			if (!ustring.IsNullOrEmpty (message)) {
 				var l = new Label (message) {
 					LayoutStyle = LayoutStyle.Computed,
 					TextAlignment = TextAlignment.Centered,
@@ -303,7 +307,12 @@ namespace Terminal.Gui {
 
 			if (width == 0 & height == 0) {
 				// Dynamically size Width
-				d.Width = Math.Min (Math.Max (maxWidthLine, Math.Max (title.ConsoleWidth, Math.Max (textWidth + 2, d.GetButtonsWidth () + d.buttons.Count + 2))), Application.Driver.Cols); // textWidth + (left + padding + padding + right)
+				var dWidth = Math.Max (maxWidthLine, Math.Max (title.ConsoleWidth, Math.Max (textWidth + 2, d.GetButtonsWidth () + d.buttons.Count + 2))); // textWidth + (left + padding + padding + right)
+				if (wrapMessagge) {
+					d.Width = Math.Min (dWidth, Application.Driver.Cols);
+				} else {
+					d.Width = dWidth;
+				}
 			}
 
 			// Setup actions

+ 8 - 3
UICatalog/Scenarios/MessageBoxes.cs

@@ -151,11 +151,16 @@ namespace UICatalog.Scenarios {
 				border.Effect3D = (bool)!e;
 			};
 			frame.Add (ckbEffect3D);
+			var ckbWrapMessage = new CheckBox ("Wrap Message", true) {
+				X = Pos.Right (label) + 1,
+				Y = Pos.Top (label) + 3
+			};
+			frame.Add (ckbWrapMessage);
 
 			void Top_Loaded ()
 			{
 				frame.Height = Dim.Height (widthEdit) + Dim.Height (heightEdit) + Dim.Height (titleEdit) + Dim.Height (messageEdit)
-				+ Dim.Height (numButtonsEdit) + Dim.Height (defaultButtonEdit) + Dim.Height (styleRadioGroup) + 2 + Dim.Height (ckbEffect3D);
+				+ Dim.Height (numButtonsEdit) + Dim.Height (defaultButtonEdit) + Dim.Height (styleRadioGroup) + 2 + Dim.Height (ckbEffect3D) + Dim.Height (ckbWrapMessage);
 				Application.Top.Loaded -= Top_Loaded;
 			}
 			Application.Top.Loaded += Top_Loaded;
@@ -196,9 +201,9 @@ namespace UICatalog.Scenarios {
 						btns.Add (NumberToWords.Convert (i));
 					}
 					if (styleRadioGroup.SelectedItem == 0) {
-						buttonPressedLabel.Text = $"{MessageBox.Query (width, height, titleEdit.Text.ToString (), messageEdit.Text.ToString (), defaultButton, border, btns.ToArray ())}";
+						buttonPressedLabel.Text = $"{MessageBox.Query (width, height, titleEdit.Text.ToString (), messageEdit.Text.ToString (), defaultButton, border, (bool)ckbWrapMessage.Checked, btns.ToArray ())}";
 					} else {
-						buttonPressedLabel.Text = $"{MessageBox.ErrorQuery (width, height, titleEdit.Text.ToString (), messageEdit.Text.ToString (), defaultButton, border, btns.ToArray ())}";
+						buttonPressedLabel.Text = $"{MessageBox.ErrorQuery (width, height, titleEdit.Text.ToString (), messageEdit.Text.ToString (), defaultButton, border, (bool)ckbWrapMessage.Checked, btns.ToArray ())}";
 					}
 				} catch (FormatException) {
 					buttonPressedLabel.Text = "Invalid Options";

+ 11 - 10
UICatalog/UICatalog.cs

@@ -54,7 +54,7 @@ namespace UICatalog {
 		//[SerializableConfigurationProperty (Scope = typeof (AppScope), OmitClassName = true), JsonPropertyName ("UICatalog.StatusBar")]
 		//public static bool ShowStatusBar { get; set; } = true;
 
-		[SerializableConfigurationProperty (Scope = typeof (AppScope), OmitClassName = true), JsonPropertyName("UICatalog.StatusBar")]
+		[SerializableConfigurationProperty (Scope = typeof (AppScope), OmitClassName = true), JsonPropertyName ("UICatalog.StatusBar")]
 		public static bool ShowStatusBar { get; set; } = true;
 
 		static readonly FileSystemWatcher _currentDirWatcher = new FileSystemWatcher ();
@@ -135,7 +135,8 @@ namespace UICatalog {
 			VerifyObjectsWereDisposed ();
 		}
 
-		private static void StopConfigFileWatcher() {
+		private static void StopConfigFileWatcher ()
+		{
 			_currentDirWatcher.EnableRaisingEvents = false;
 			_currentDirWatcher.Changed -= ConfigFileChanged;
 			_currentDirWatcher.Created -= ConfigFileChanged;
@@ -145,7 +146,7 @@ namespace UICatalog {
 			_homeDirWatcher.Created -= ConfigFileChanged;
 		}
 
-		private static void StartConfigFileWatcher()
+		private static void StartConfigFileWatcher ()
 		{
 			// Setup a file system watcher for `./.tui/`
 			_currentDirWatcher.NotifyFilter = NotifyFilters.LastWrite;
@@ -275,7 +276,7 @@ namespace UICatalog {
 						new MenuItem ("_gui.cs API Overview", "", () => OpenUrl ("https://gui-cs.github.io/Terminal.Gui/articles/overview.html"), null, null, Key.F1),
 						new MenuItem ("gui.cs _README", "", () => OpenUrl ("https://github.com/gui-cs/Terminal.Gui"), null, null, Key.F2),
 						new MenuItem ("_About...",
-							"About UI Catalog", () =>  MessageBox.Query ("About UI Catalog", _aboutMessage.ToString(), "_Ok"), null, null, Key.CtrlMask | Key.A),
+							"About UI Catalog", () =>  MessageBox.Query ("About UI Catalog", _aboutMessage.ToString(), 0, null, false, "_Ok"), null, null, Key.CtrlMask | Key.A),
 					}),
 				});
 
@@ -286,7 +287,7 @@ namespace UICatalog {
 				OS = new StatusItem (Key.CharMask, "OS:", null);
 
 				StatusBar = new StatusBar () {
-					Visible = UICatalogApp.ShowStatusBar					
+					Visible = UICatalogApp.ShowStatusBar
 				};
 
 				StatusBar.Items = new StatusItem [] {
@@ -320,7 +321,7 @@ namespace UICatalog {
 				ContentPane.Border.BorderStyle = BorderStyle.Single;
 				ContentPane.SetSplitterPos (0, 25);
 				ContentPane.ShortcutAction = () => ContentPane.SetFocus ();
-					
+
 				CategoryListView = new ListView (_categories) {
 					X = 0,
 					Y = 0,
@@ -368,7 +369,7 @@ namespace UICatalog {
 
 				ConfigurationManager.Applied += ConfigAppliedHandler;
 			}
- 
+
 			void LoadedHandler ()
 			{
 				ConfigChanged ();
@@ -403,7 +404,7 @@ namespace UICatalog {
 				ConfigurationManager.Applied -= ConfigAppliedHandler;
 				Unloaded -= UnloadedHandler;
 			}
-			
+
 			void ConfigAppliedHandler (ConfigurationManagerEventArgs a)
 			{
 				ConfigChanged ();
@@ -631,7 +632,7 @@ namespace UICatalog {
 				if (_topLevelColorScheme == null || !Colors.ColorSchemes.ContainsKey (_topLevelColorScheme)) {
 					_topLevelColorScheme = "Base";
 				}
-				
+
 				_themeMenuItems = ((UICatalogTopLevel)Application.Top).CreateThemeMenuItems ();
 				_themeMenuBarItem.Children = _themeMenuItems;
 
@@ -717,7 +718,7 @@ namespace UICatalog {
 			// after a scenario was selected to run. This proves the main UI Catalog
 			// 'app' closed cleanly.
 			foreach (var inst in Responder.Instances) {
-				
+
 				Debug.Assert (inst.WasDisposed);
 			}
 			Responder.Instances.Clear ();

+ 66 - 6
UnitTests/TopLevels/MessageBoxTests.cs

@@ -157,7 +157,7 @@ namespace Terminal.Gui.TopLevelTests {
 		}
 
 		[Fact, AutoInitShutdown]
-		public void MessageBox_With_A_Label_Without_Spaces ()
+		public void MessageBox_With_A_Label_Without_Spaces_WrapMessagge_True ()
 		{
 			var iterations = -1;
 			Application.Begin (Application.Top);
@@ -196,8 +196,7 @@ namespace Terminal.Gui.TopLevelTests {
 │ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│
 │ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│
 │                                   [◦ ok ◦]                                   │
-└──────────────────────────────────────────────────────────────────────────────┘
-", output);
+└──────────────────────────────────────────────────────────────────────────────┘", output);
 
 					Application.RequestStop ();
 				}
@@ -207,7 +206,7 @@ namespace Terminal.Gui.TopLevelTests {
 		}
 
 		[Fact, AutoInitShutdown]
-		public void MessageBox_With_A_Label_With_Spaces ()
+		public void MessageBox_With_A_Label_With_Spaces_WrapMessagge_True ()
 		{
 			var iterations = -1;
 			Application.Begin (Application.Top);
@@ -250,8 +249,69 @@ namespace Terminal.Gui.TopLevelTests {
 │ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │
 │ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │
 │                                   [◦ ok ◦]                                   │
-└──────────────────────────────────────────────────────────────────────────────┘
-", output);
+└──────────────────────────────────────────────────────────────────────────────┘", output);
+
+					Application.RequestStop ();
+				}
+			};
+
+			Application.Run ();
+		}
+
+		[Fact, AutoInitShutdown]
+		public void MessageBox_With_A_Label_Without_Spaces_WrapMessagge_False ()
+		{
+			var iterations = -1;
+			Application.Begin (Application.Top);
+
+			Application.Iteration += () => {
+				iterations++;
+
+				if (iterations == 0) {
+					MessageBox.Query ("mywindow", new string ('f', 2000), 0, null, false, "ok");
+
+					Application.RequestStop ();
+				} else if (iterations == 1) {
+					Application.Refresh ();
+					TestHelpers.AssertDriverContentsWithFrameAre (@"
+────────────────────────────────────────────────────────────────────────────────
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+                                                                                
+                                    [◦ ok ◦]                                    
+────────────────────────────────────────────────────────────────────────────────", output);
+
+					Application.RequestStop ();
+				}
+			};
+
+			Application.Run ();
+		}
+
+		[Fact, AutoInitShutdown]
+		public void MessageBox_With_A_Label_With_Spaces_WrapMessagge_False ()
+		{
+			var iterations = -1;
+			Application.Begin (Application.Top);
+
+			Application.Iteration += () => {
+				iterations++;
+
+				if (iterations == 0) {
+					var sb = new StringBuilder ();
+					for (int i = 0; i < 1000; i++)
+						sb.Append ("ff ");
+
+					MessageBox.Query ("mywindow", sb.ToString (), 0, null, false, "ok");
+
+					Application.RequestStop ();
+				} else if (iterations == 1) {
+					Application.Refresh ();
+					TestHelpers.AssertDriverContentsWithFrameAre (@"
+────────────────────────────────────────────────────────────────────────────────
+ ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff f
+                                                                                
+                                    [◦ ok ◦]                                    
+────────────────────────────────────────────────────────────────────────────────", output);
 
 					Application.RequestStop ();
 				}