2
0
Эх сурвалжийг харах

Merge pull request #2124 from BDisp/view-clear-fix

Fixes #2122. Weird visual artifacts on clearing.
Tig 2 жил өмнө
parent
commit
ec7f6ae7c1

+ 8 - 3
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -1500,11 +1500,16 @@ namespace Terminal.Gui {
 			crow = row;
 		}
 
+		int GetOutputBufferPosition ()
+		{
+			return crow * Cols + ccol;
+		}
+
 		public override void AddRune (Rune rune)
 		{
 			rune = MakePrintable (rune);
 			var runeWidth = Rune.ColumnWidth (rune);
-			var position = crow * Cols + ccol;
+			var position = GetOutputBufferPosition ();
 			var validClip = IsValidContent (ccol, crow, Clip);
 
 			if (validClip) {
@@ -1518,7 +1523,7 @@ namespace Terminal.Gui {
 				} else if (runeWidth < 2 && ccol <= Clip.Right - 1
 					&& Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
 
-					var prevPosition = crow * Cols + ccol + 1;
+					var prevPosition = GetOutputBufferPosition () + 1;
 					OutputBuffer [prevPosition].Char.UnicodeChar = (char)' ';
 					contents [crow, ccol + 1, 0] = (int)(uint)' ';
 
@@ -1539,7 +1544,7 @@ namespace Terminal.Gui {
 			ccol++;
 			if (runeWidth > 1) {
 				if (validClip && ccol < Clip.Right) {
-					position = crow * Cols + ccol;
+					position = GetOutputBufferPosition ();
 					OutputBuffer [position].Attributes = (ushort)currentAttribute;
 					OutputBuffer [position].Char.UnicodeChar = (char)0x00;
 					contents [crow, ccol, 0] = (int)(uint)0x00;

+ 17 - 11
Terminal.Gui/Core/TextFormatter.cs

@@ -1182,10 +1182,22 @@ namespace Terminal.Gui {
 			}
 
 			var isVertical = IsVerticalDirection (textDirection);
+			var savedClip = Application.Driver?.Clip;
+			var maxBounds = bounds;
+			if (Application.Driver != null) {
+				Application.Driver.Clip = maxBounds = containerBounds == default
+					? bounds
+					: new Rect (Math.Max (containerBounds.X, bounds.X),
+					Math.Max (containerBounds.Y, bounds.Y),
+					Math.Max (Math.Min (containerBounds.Width, containerBounds.Right - bounds.Left), 0),
+					Math.Max (Math.Min (containerBounds.Height, containerBounds.Bottom - bounds.Top), 0));
+			}
 
 			for (int line = 0; line < linesFormated.Count; line++) {
 				if ((isVertical && line > bounds.Width) || (!isVertical && line > bounds.Height))
 					continue;
+				if ((isVertical && line > maxBounds.Left + maxBounds.Width - bounds.X) || (!isVertical && line > maxBounds.Top + maxBounds.Height - bounds.Y))
+					break;
 
 				var runes = lines [line].ToRunes ();
 
@@ -1262,15 +1274,6 @@ namespace Terminal.Gui {
 				var start = isVertical ? bounds.Top : bounds.Left;
 				var size = isVertical ? bounds.Height : bounds.Width;
 				var current = start;
-				var savedClip = Application.Driver?.Clip;
-				if (Application.Driver != null) {
-					Application.Driver.Clip = containerBounds == default
-						? bounds
-						: new Rect (Math.Max (containerBounds.X, bounds.X),
-						Math.Max (containerBounds.Y, bounds.Y),
-						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 = (isVertical ? start - y : start - x); current < start + size; idx++) {
 					if (!fillRemaining && idx < 0) {
@@ -1279,6 +1282,9 @@ namespace Terminal.Gui {
 					} else if (!fillRemaining && idx > runes.Length - 1) {
 						break;
 					}
+					if ((!isVertical && idx > maxBounds.Left + maxBounds.Width - bounds.X) || (isVertical && idx > maxBounds.Top + maxBounds.Height - bounds.Y))
+						break;
+
 					var rune = (Rune)' ';
 					if (isVertical) {
 						Application.Driver?.Move (x, current);
@@ -1313,9 +1319,9 @@ namespace Terminal.Gui {
 						break;
 					}
 				}
-				if (Application.Driver != null)
-					Application.Driver.Clip = (Rect)savedClip;
 			}
+			if (Application.Driver != null)
+				Application.Driver.Clip = (Rect)savedClip;
 		}
 	}
 }

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

@@ -1495,14 +1495,17 @@ namespace Terminal.Gui {
 
 			if (Border != null) {
 				Border.DrawContent (this);
-			} else if ((GetType ().IsPublic || GetType ().IsNestedPublic) && !IsOverridden (this, "Redraw") &&
+			} else if (ustring.IsNullOrEmpty (TextFormatter.Text) &&
+				(GetType ().IsPublic || GetType ().IsNestedPublic) && !IsOverridden (this, "Redraw") &&
 				(!NeedDisplay.IsEmpty || ChildNeedsDisplay || LayoutNeeded)) {
 
-				Clear (ViewToScreen (bounds));
+				Clear ();
+				SetChildNeedsDisplay ();
 			}
 
 			if (!ustring.IsNullOrEmpty (TextFormatter.Text)) {
 				Clear ();
+				SetChildNeedsDisplay ();
 				// Draw any Text
 				if (TextFormatter != null) {
 					TextFormatter.NeedsFormat = true;

+ 0 - 6
Terminal.Gui/Core/Window.cs

@@ -303,12 +303,6 @@ namespace Terminal.Gui {
 			if (Border.DrawMarginFrame)
 				Driver.DrawWindowTitle (scrRect, Title, padding.Left, padding.Top, padding.Right, padding.Bottom);
 			Driver.SetAttribute (GetNormalColor ());
-
-			// Checks if there are any SuperView view which intersect with this window.
-			if (SuperView != null) {
-				SuperView.SetNeedsLayout ();
-				SuperView.SetNeedsDisplay ();
-			}
 		}
 
 		/// <inheritdoc/>

+ 29 - 16
UICatalog/Scenarios/Scrolling.cs

@@ -105,8 +105,8 @@ namespace UICatalog.Scenarios {
 		{
 			Win.X = 3;
 			Win.Y = 3;
-			Win.Width = Dim.Fill () - 3;
-			Win.Height = Dim.Fill () - 3;
+			Win.Width = Dim.Fill (3);
+			Win.Height = Dim.Fill (3);
 			var label = new Label ("ScrollView (new Rect (2, 2, 50, 20)) with a 200, 100 ContentSize...") {
 				X = 0,
 				Y = 0,
@@ -114,8 +114,12 @@ namespace UICatalog.Scenarios {
 			};
 			Win.Add (label);
 
-			// BUGBUG: ScrollView only supports Absolute Positioning (#72)
-			var scrollView = new ScrollView (new Rect (2, 2, 50, 20)) {
+			// FIXED: ScrollView only supports Absolute Positioning (#72)
+			var scrollView = new ScrollView {
+				X = 2,
+				Y = 2,
+				Width = 50,
+				Height = 20,
 				ColorScheme = Colors.TopLevel,
 				ContentSize = new Size (200, 100),
 				//ContentOffset = new Point (0, 0),
@@ -124,6 +128,7 @@ namespace UICatalog.Scenarios {
 			};
 
 			const string rule = "0123456789";
+
 			var horizontalRuler = new Label () {
 				X = 0,
 				Y = 0,
@@ -133,6 +138,7 @@ namespace UICatalog.Scenarios {
 				AutoSize = false
 			};
 			scrollView.Add (horizontalRuler);
+
 			const string vrule = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n";
 
 			var verticalRuler = new Label () {
@@ -148,7 +154,7 @@ namespace UICatalog.Scenarios {
 			void Top_Loaded ()
 			{
 				horizontalRuler.Text = rule.Repeat ((int)Math.Ceiling ((double)(horizontalRuler.Bounds.Width) / (double)rule.Length)) [0..(horizontalRuler.Bounds.Width)] +
-				"\n" + "|         ".Repeat ((int)Math.Ceiling ((double)(horizontalRuler.Bounds.Width) / (double)rule.Length)) [0..(horizontalRuler.Bounds.Width)];
+					"\n" + "|         ".Repeat ((int)Math.Ceiling ((double)(horizontalRuler.Bounds.Width) / (double)rule.Length)) [0..(horizontalRuler.Bounds.Width)];
 				verticalRuler.Text = vrule.Repeat ((int)Math.Ceiling ((double)(verticalRuler.Bounds.Height * 2) / (double)rule.Length)) [0..(verticalRuler.Bounds.Height * 2)];
 				Top.Loaded -= Top_Loaded;
 			}
@@ -164,7 +170,7 @@ namespace UICatalog.Scenarios {
 			var aLongButton = new Button ("A very long button. Should be wide enough to demo clipping!") {
 				X = 3,
 				Y = 4,
-				Width = Dim.Fill (6),
+				Width = Dim.Fill (3),
 			};
 			aLongButton.Clicked += () => MessageBox.Query (20, 7, "MessageBox", "Neat?", "Yes", "No");
 			scrollView.Add (aLongButton);
@@ -206,6 +212,8 @@ namespace UICatalog.Scenarios {
 			};
 			scrollView.Add (anchorButton);
 
+			Win.Add (scrollView);
+
 			var hCheckBox = new CheckBox ("Horizontal Scrollbar", scrollView.ShowHorizontalScrollIndicator) {
 				X = Pos.X (scrollView),
 				Y = Pos.Bottom (scrollView) + 1,
@@ -265,6 +273,7 @@ namespace UICatalog.Scenarios {
 			scrollView2.DrawContent += (r) => {
 				scrollView2.ContentSize = filler.GetContentSize ();
 			};
+			Win.Add (scrollView2);
 
 			// This is just to debug the visuals of the scrollview when small
 			var scrollView3 = new ScrollView (new Rect (55, 15, 3, 3)) {
@@ -273,20 +282,26 @@ namespace UICatalog.Scenarios {
 				ShowHorizontalScrollIndicator = true
 			};
 			scrollView3.Add (new Box10x (0, 0));
+			Win.Add (scrollView3);
 
 			int count = 0;
-			var mousePos = new Label ("Mouse: ");
-			mousePos.X = Pos.Right (scrollView) + 1;
-			mousePos.Y = Pos.AnchorEnd (1);
-			mousePos.Width = 50;
+			var mousePos = new Label ("Mouse: ") {
+				X = Pos.Right (scrollView) + 1,
+				Y = Pos.AnchorEnd (1),
+				Width = 50,
+			};
+			Win.Add (mousePos);
 			Application.RootMouseEvent += delegate (MouseEvent me) {
 				mousePos.Text = $"Mouse: ({me.X},{me.Y}) - {me.Flags} {count++}";
 			};
 
-			var progress = new ProgressBar ();
-			progress.X = Pos.Right (scrollView) + 1;
-			progress.Y = Pos.AnchorEnd (2);
-			progress.Width = 50;
+			var progress = new ProgressBar {
+				X = Pos.Right (scrollView) + 1,
+				Y = Pos.AnchorEnd (2),
+				Width = 50
+			};
+			Win.Add (progress);
+
 			bool pulsing = true;
 			bool timer (MainLoop caller)
 			{
@@ -301,8 +316,6 @@ namespace UICatalog.Scenarios {
 				Top.Unloaded -= Top_Unloaded;
 			}
 			Top.Unloaded += Top_Unloaded;
-
-			Win.Add (scrollView, scrollView2, scrollView3, mousePos, progress);
 		}
 	}
 }

+ 24 - 0
UnitTests/ViewTests.cs

@@ -4062,5 +4062,29 @@ This is a tes
 			Assert.False (view.IsKeyPress);
 			Assert.True (view.IsKeyUp);
 		}
+
+		[Fact, AutoInitShutdown]
+		public void IsOverridden_False_IfNotOverriden ()
+		{
+			var view = new DerivedView () { Text = "DerivedView does not override MouseEvent", Width = 10, Height = 10 };
+
+			Assert.False (View.IsOverridden (view, "MouseEvent"));
+
+			var view2 = new Button () { Text = "Button does not overrides OnKeyDown", Width = 10, Height = 10 };
+
+			Assert.False (View.IsOverridden (view2, "OnKeyDown"));
+		}
+
+		[Fact, AutoInitShutdown]
+		public void IsOverridden_True_IfOverriden ()
+		{
+			var view = new Button () { Text = "Button overrides MouseEvent", Width = 10, Height = 10 };
+
+			Assert.True (View.IsOverridden (view, "MouseEvent"));
+
+			var view2 = new DerivedView () { Text = "DerivedView overrides OnKeyDown", Width = 10, Height = 10 };
+
+			Assert.True (View.IsOverridden (view2, "OnKeyDown"));
+		}
 	}
 }