Browse Source

Fixes #2002. Added feature to fill the remaining width with spaces. (#2003)

* Added feature to fill the remaining width with spaces.

* Removing unnecessary parameter.

* Fixes a typo.

* Unit test rewritten to explain better main feature of this PR.

Co-authored-by: Tig Kindel <[email protected]>
BDisp 2 years ago
parent
commit
28718e9c3c
2 changed files with 50 additions and 6 deletions
  1. 8 6
      Terminal.Gui/Core/TextFormatter.cs
  2. 42 0
      UnitTests/TextFormatterTests.cs

+ 8 - 6
Terminal.Gui/Core/TextFormatter.cs

@@ -356,7 +356,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Gets or sets whether the <see cref="TextFormatter"/> needs to format the text when <see cref="Draw(Rect, Attribute, Attribute, Rect)"/> is called.
+		/// Gets or sets whether the <see cref="TextFormatter"/> needs to format the text when <see cref="Draw(Rect, Attribute, Attribute, Rect, bool)"/> is called.
 		/// If it is <c>false</c> when Draw is called, the Draw call will be faster.
 		/// </summary>
 		/// <remarks>
@@ -1159,7 +1159,8 @@ namespace Terminal.Gui {
 		/// <param name="normalColor">The color to use for all text except the hotkey</param>
 		/// <param name="hotColor">The color to use to draw the hotkey</param>
 		/// <param name="containerBounds">Specifies the screen-relative location and maximum container size.</param>
-		public void Draw (Rect bounds, Attribute normalColor, Attribute hotColor, Rect containerBounds = default)
+		/// <param name="fillRemaining">Determines if the bounds width will be used (default) or only the text width will be used.</param>
+		public void Draw (Rect bounds, Attribute normalColor, Attribute hotColor, Rect containerBounds = default, bool fillRemaining = true)
 		{
 			// With this check, we protect against subclasses with overrides of Text (like Button)
 			if (ustring.IsNullOrEmpty (text)) {
@@ -1262,7 +1263,7 @@ namespace Terminal.Gui {
 				var size = isVertical ? bounds.Height : bounds.Width;
 				var current = start;
 				var savedClip = Application.Driver?.Clip;
-				if (Application.Driver != null && containerBounds != default) {
+				if (Application.Driver != null) {
 					Application.Driver.Clip = containerBounds == default
 						? bounds
 						: new Rect (Math.Max (containerBounds.X, bounds.X),
@@ -1272,10 +1273,10 @@ namespace Terminal.Gui {
 				}
 
 				for (var idx = (isVertical ? start - y : start - x); current < start + size; idx++) {
-					if (idx < 0) {
+					if (!fillRemaining && idx < 0) {
 						current++;
 						continue;
-					} else if (idx > runes.Length - 1) {
+					} else if (!fillRemaining && idx > runes.Length - 1) {
 						break;
 					}
 					var rune = (Rune)' ';
@@ -1307,7 +1308,8 @@ namespace Terminal.Gui {
 					} else {
 						current += runeWidth;
 					}
-					if (!isVertical && idx + 1 < runes.Length && current + Rune.ColumnWidth (runes [idx + 1]) > start + size) {
+					var nextRuneWidth = idx + 1 > -1 && idx + 1 < runes.Length ? Rune.ColumnWidth (runes [idx + 1]) : 0;
+					if (!isVertical && idx + 1 < runes.Length && current + nextRuneWidth > start + size) {
 						break;
 					}
 				}

+ 42 - 0
UnitTests/TextFormatterTests.cs

@@ -3365,6 +3365,48 @@ e
 			Assert.Equal (new Rect (0, 0, 13, height + 2), pos);
 		}
 
+		[Fact, AutoInitShutdown]
+		public void Draw_Fill_Remaining ()
+		{
+			var view = new View ("This view needs to be cleared before rewritten.");
+
+			var tf1 = new TextFormatter ();
+			tf1.Text = "This TextFormatter (tf1) without fill will not be cleared on rewritten.";
+			var tf1Size = tf1.Size;
+
+			var tf2 = new TextFormatter ();
+			tf2.Text = "This TextFormatter (tf2) with fill will be cleared on rewritten.";
+			var tf2Size = tf2.Size;
+
+			Application.Top.Add (view);
+			Application.Begin (Application.Top);
+
+			tf1.Draw (new Rect (new Point (0, 1), tf1Size), view.GetNormalColor (), view.ColorScheme.HotNormal, default, false);
+
+			tf2.Draw (new Rect (new Point (0, 2), tf2Size), view.GetNormalColor (), view.ColorScheme.HotNormal);
+
+			GraphViewTests.AssertDriverContentsWithFrameAre (@"
+This view needs to be cleared before rewritten.                        
+This TextFormatter (tf1) without fill will not be cleared on rewritten.
+This TextFormatter (tf2) with fill will be cleared on rewritten.       
+", output);
+
+			view.Text = "This view is rewritten.";
+			view.Redraw (view.Bounds);
+
+			tf1.Text = "This TextFormatter (tf1) is rewritten.";
+			tf1.Draw (new Rect (new Point (0, 1), tf1Size), view.GetNormalColor (), view.ColorScheme.HotNormal, default, false);
+
+			tf2.Text = "This TextFormatter (tf2) is rewritten.";
+			tf2.Draw (new Rect (new Point (0, 2), tf2Size), view.GetNormalColor (), view.ColorScheme.HotNormal);
+
+			GraphViewTests.AssertDriverContentsWithFrameAre (@"
+This view is rewritten.                                                
+This TextFormatter (tf1) is rewritten.will not be cleared on rewritten.
+This TextFormatter (tf2) is rewritten.                                 
+", output);
+		}
+
 		[Fact]
 		public void GetTextWidth_Simple_And_Wide_Runes ()
 		{