Переглянути джерело

Fixes the draw clip bounds issue visible on ScrollView.

BDisp 3 роки тому
батько
коміт
e941169dad

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

@@ -1145,20 +1145,17 @@ namespace Terminal.Gui {
 				var start = isVertical ? bounds.Top : bounds.Left;
 				var size = isVertical ? bounds.Height : bounds.Width;
 				var current = start;
-				var startX = start < 0
-					? start
-					: isVertical ? start - y : start - x;
 				var savedClip = Application.Driver?.Clip;
 				if (Application.Driver != null && containerBounds != default) {
 					Application.Driver.Clip = containerBounds == default
 						? bounds
 						: new Rect (Math.Max (containerBounds.X, bounds.X),
 						Math.Max (containerBounds.Y, bounds.Y),
-						Math.Min (containerBounds.Width, containerBounds.Right - bounds.Left),
-						Math.Min (containerBounds.Height, containerBounds.Bottom - bounds.Top));
+						Math.Max (Math.Min (containerBounds.Width, containerBounds.Right - bounds.Left), 0),
+						Math.Max (Math.Min (containerBounds.Height, containerBounds.Bottom - bounds.Top), 0));
 				}
 
-				for (var idx = startX; current < start + size; idx++) {
+				for (var idx = (isVertical ? start - y : start - x); current < start + size; idx++) {
 					if (idx < 0) {
 						current++;
 						continue;

+ 7 - 2
Terminal.Gui/Core/View.cs

@@ -1417,15 +1417,20 @@ namespace Terminal.Gui {
 				Border.DrawContent (this);
 			}
 
-			if (!ustring.IsNullOrEmpty (Text) || (this is Label && !AutoSize)) {
+			if (!ustring.IsNullOrEmpty (TextFormatter.Text) || (this is Label && !AutoSize)) {
 				Clear ();
 				// Draw any Text
 				if (TextFormatter != null) {
 					TextFormatter.NeedsFormat = true;
 				}
+				var containerBounds = SuperView == null ? default : SuperView.ViewToScreen (SuperView.Bounds);
+				containerBounds.X = Math.Max (containerBounds.X, Driver.Clip.X);
+				containerBounds.Y = Math.Max (containerBounds.Y, Driver.Clip.Y);
+				containerBounds.Width = Math.Min (containerBounds.Width, Driver.Clip.Width);
+				containerBounds.Height = Math.Min (containerBounds.Height, Driver.Clip.Height);
 				TextFormatter?.Draw (ViewToScreen (Bounds), HasFocus ? ColorScheme.Focus : GetNormalColor (),
 					HasFocus ? ColorScheme.HotFocus : Enabled ? ColorScheme.HotNormal : ColorScheme.Disabled,
-					SuperView == null ? default : SuperView.ViewToScreen (SuperView.Bounds));
+					containerBounds);
 			}
 
 			// Invoke DrawContentEvent

+ 0 - 20
Terminal.Gui/Views/Button.cs

@@ -221,26 +221,6 @@ namespace Terminal.Gui {
 			SetNeedsDisplay ();
 		}
 
-		/// <inheritdoc/>
-		public override void Redraw (Rect bounds)
-		{
-			if (ColorScheme != null) {
-				Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
-			}
-
-			if (Border != null) {
-				Border.DrawContent (this);
-			}
-
-			if (!ustring.IsNullOrEmpty (TextFormatter.Text)) {
-				Clear ();
-				TextFormatter.NeedsFormat = true;
-				TextFormatter?.Draw (ViewToScreen (Bounds), HasFocus ? ColorScheme.Focus : GetNormalColor (),
-					HasFocus ? ColorScheme.HotFocus : Enabled ? ColorScheme.HotNormal : ColorScheme.Disabled,
-					SuperView == null ? default : SuperView.ViewToScreen (SuperView.Bounds));
-			}
-		}
-
 		///<inheritdoc/>
 		public override bool ProcessHotKey (KeyEvent kb)
 		{

+ 266 - 4
UnitTests/ViewTests.cs

@@ -1985,14 +1985,276 @@ Y
 			view.Frame = new Rect (0, 0, 8, 4);
 			((FakeDriver)Application.Driver).SetBufferSize (7, 3);
 
+		}
+
+		[Fact, AutoInitShutdown]
+		public void DrawTextFormatter_Respects_The_Clip_Bounds ()
+		{
+			var view = new View (new Rect (0, 0, 20, 20));
+			view.Add (new Label ("0123456789abcdefghij"));
+			view.Add (new Label (0, 1, "1\n2\n3\n4\n5\n6\n7\n8\n9\n0"));
+			view.Add (new Button (1, 1, "Press me!"));
+			var scrollView = new ScrollView (new Rect (1, 1, 15, 10)) {
+				ContentSize = new Size (40, 40),
+				ShowHorizontalScrollIndicator = true,
+				ShowVerticalScrollIndicator = true
+			};
+			scrollView.Add (view);
+			var win = new Window (new Rect (1, 1, 20, 14), "Test");
+			win.Add (scrollView);
+			Application.Top.Add (win);
+			Application.Begin (Application.Top);
+
+			var expected = @"
+ ┌ Test ────────────┐
+ │                  │
+ │ 0123456789abcd▲  │
+ │ 1[ Press me! ]┬  │
+ │ 2             │  │
+ │ 3             ┴  │
+ │ 4             ░  │
+ │ 5             ░  │
+ │ 6             ░  │
+ │ 7             ░  │
+ │ 8             ▼  │
+ │ ◄├───┤░░░░░░░►   │
+ │                  │
+ └──────────────────┘
+";
+
+			var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (1, 1, 21, 14), pos);
+
+			Assert.True (scrollView.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
+			Application.Top.Redraw (Application.Top.Bounds);
+
 			expected = @"
-┌──────
-│
-│
+ ┌ Test ────────────┐
+ │                  │
+ │ 123456789abcde▲  │
+ │ [ Press me! ] ┬  │
+ │               │  │
+ │               ┴  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ▼  │
+ │ ◄├───┤░░░░░░░►   │
+ │                  │
+ └──────────────────┘
+";
+
+			pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (1, 1, 21, 14), pos);
+
+			Assert.True (scrollView.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
+			Application.Top.Redraw (Application.Top.Bounds);
+
+			expected = @"
+ ┌ Test ────────────┐
+ │                  │
+ │ 23456789abcdef▲  │
+ │  Press me! ]  ┬  │
+ │               │  │
+ │               ┴  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ▼  │
+ │ ◄├────┤░░░░░░►   │
+ │                  │
+ └──────────────────┘
+";
+
+			pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (1, 1, 21, 14), pos);
+
+			Assert.True (scrollView.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
+			Application.Top.Redraw (Application.Top.Bounds);
+
+			expected = @"
+ ┌ Test ────────────┐
+ │                  │
+ │ 3456789abcdefg▲  │
+ │ Press me! ]   ┬  │
+ │               │  │
+ │               ┴  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ▼  │
+ │ ◄├────┤░░░░░░►   │
+ │                  │
+ └──────────────────┘
+";
+
+			pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (1, 1, 21, 14), pos);
+
+			Assert.True (scrollView.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
+			Application.Top.Redraw (Application.Top.Bounds);
+
+			expected = @"
+ ┌ Test ────────────┐
+ │                  │
+ │ 456789abcdefgh▲  │
+ │ ress me! ]    ┬  │
+ │               │  │
+ │               ┴  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ▼  │
+ │ ◄░├───┤░░░░░░►   │
+ │                  │
+ └──────────────────┘
+";
+
+			pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (1, 1, 21, 14), pos);
+
+			Assert.True (scrollView.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
+			Application.Top.Redraw (Application.Top.Bounds);
+
+			expected = @"
+ ┌ Test ────────────┐
+ │                  │
+ │ 56789abcdefghi▲  │
+ │ ess me! ]     ┬  │
+ │               │  │
+ │               ┴  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ▼  │
+ │ ◄░├────┤░░░░░►   │
+ │                  │
+ └──────────────────┘
+";
+
+			pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (1, 1, 21, 14), pos);
+
+			Assert.True (scrollView.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
+			Application.Top.Redraw (Application.Top.Bounds);
+
+			expected = @"
+ ┌ Test ────────────┐
+ │                  │
+ │ 6789abcdefghij▲  │
+ │ ss me! ]      ┬  │
+ │               │  │
+ │               ┴  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ▼  │
+ │ ◄░├────┤░░░░░►   │
+ │                  │
+ └──────────────────┘
+";
+
+			pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (1, 1, 21, 14), pos);
+
+			Assert.True (scrollView.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
+			Application.Top.Redraw (Application.Top.Bounds);
+
+			expected = @"
+ ┌ Test ────────────┐
+ │                  │
+ │ 789abcdefghij ▲  │
+ │ s me! ]       ┬  │
+ │               │  │
+ │               ┴  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ░  │
+ │               ▼  │
+ │ ◄░░├───┤░░░░░►   │
+ │                  │
+ └──────────────────┘
+";
+
+			pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (1, 1, 21, 14), pos);
+
+			Assert.True (scrollView.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Home, new KeyModifiers ())));
+			Assert.True (scrollView.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ())));
+			Application.Top.Redraw (Application.Top.Bounds);
+
+			expected = @"
+ ┌ Test ────────────┐
+ │                  │
+ │ 1[ Press me! ]▲  │
+ │ 2             ┬  │
+ │ 3             │  │
+ │ 4             ┴  │
+ │ 5             ░  │
+ │ 6             ░  │
+ │ 7             ░  │
+ │ 8             ░  │
+ │ 9             ▼  │
+ │ ◄├───┤░░░░░░░►   │
+ │                  │
+ └──────────────────┘
+";
+
+			pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (1, 1, 21, 14), pos);
+
+			Assert.True (scrollView.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ())));
+			Application.Top.Redraw (Application.Top.Bounds);
+
+			expected = @"
+ ┌ Test ────────────┐
+ │                  │
+ │ 2             ▲  │
+ │ 3             ┬  │
+ │ 4             │  │
+ │ 5             ┴  │
+ │ 6             ░  │
+ │ 7             ░  │
+ │ 8             ░  │
+ │ 9             ░  │
+ │ 0             ▼  │
+ │ ◄├───┤░░░░░░░►   │
+ │                  │
+ └──────────────────┘
+";
+
+			pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (1, 1, 21, 14), pos);
+
+			Assert.True (scrollView.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ())));
+			Application.Top.Redraw (Application.Top.Bounds);
+
+			expected = @"
+ ┌ Test ────────────┐
+ │                  │
+ │ 3             ▲  │
+ │ 4             ┬  │
+ │ 5             │  │
+ │ 6             ┴  │
+ │ 7             ░  │
+ │ 8             ░  │
+ │ 9             ░  │
+ │ 0             ░  │
+ │               ▼  │
+ │ ◄├───┤░░░░░░░►   │
+ │                  │
+ └──────────────────┘
 ";
 
 			pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
-			Assert.Equal (new Rect (0, 0, 7, 3), pos);
+			Assert.Equal (new Rect (1, 1, 21, 14), pos);
 		}
 	}
 }