浏览代码

Merge pull request #1057 from BDisp/window-superview-redraw-fix

Fixes #1056. Window doesn't redraw his SuperView properly.
Charlie Kindel 4 年之前
父节点
当前提交
00fdc92899

+ 17 - 2
Terminal.Gui/Core/Toplevel.cs

@@ -363,14 +363,24 @@ namespace Terminal.Gui {
 		internal void EnsureVisibleBounds (Toplevel top, int x, int y, out int nx, out int ny)
 		{
 			nx = Math.Max (x, 0);
-			nx = nx + top.Frame.Width > Driver.Cols ? Math.Max (Driver.Cols - top.Frame.Width, 0) : nx;
+			int l;
+			if (SuperView == null || SuperView is Toplevel) {
+				l = Driver.Cols;
+			} else {
+				l = SuperView.Frame.Width;
+			}
+			nx = nx + top.Frame.Width > l ? Math.Max (l - top.Frame.Width, 0) : nx;
+			SetWidth (top.Frame.Width, out int rWidth);
+			if (rWidth < 0 && nx >= top.Frame.X) {
+				nx = Math.Max (top.Frame.Right - 2, 0);
+			}
+			//System.Diagnostics.Debug.WriteLine ($"nx:{nx}, rWidth:{rWidth}");
 			bool m, s;
 			if (SuperView == null || SuperView.GetType () != typeof (Toplevel)) {
 				m = Application.Top.MenuBar != null;
 			} else {
 				m = ((Toplevel)SuperView).MenuBar != null;
 			}
-			int l;
 			if (SuperView == null || SuperView is Toplevel) {
 				l = m ? 1 : 0;
 			} else {
@@ -389,6 +399,11 @@ namespace Terminal.Gui {
 			}
 			ny = Math.Min (ny, l);
 			ny = ny + top.Frame.Height > l ? Math.Max (l - top.Frame.Height, m ? 1 : 0) : ny;
+			SetHeight (top.Frame.Height, out int rHeight);
+			if (rHeight < 0 && ny >= top.Frame.Y) {
+				ny = Math.Max (top.Frame.Bottom - 2, 0);
+			}
+			//System.Diagnostics.Debug.WriteLine ($"ny:{ny}, rHeight:{rHeight}");
 		}
 
 		internal void PositionToplevels ()

+ 63 - 3
Terminal.Gui/Core/View.cs

@@ -1125,10 +1125,10 @@ namespace Terminal.Gui {
 				return;
 			}
 
-			if (focused != null) {
+			if (focused?.Frame.Width > 0 && focused.Frame.Height > 0) {
 				focused.PositionCursor ();
 			} else {
-				if (CanFocus && HasFocus && Visible) {
+				if (CanFocus && HasFocus && Visible && Frame.Width > 0 && Frame.Height > 0) {
 					Move (textFormatter.HotKeyPos == -1 ? 0 : textFormatter.CursorPosition, 0);
 				} else {
 					Move (frame.X, frame.Y);
@@ -1344,7 +1344,7 @@ namespace Terminal.Gui {
 
 							// Draw the subview
 							// Use the view's bounds (view-relative; Location will always be (0,0)
-							if (view.Visible) {
+							if (view.Visible && view.Frame.Width > 0 && view.Frame.Height > 0) {
 								view.Redraw (view.Bounds);
 							}
 						}
@@ -2144,5 +2144,65 @@ namespace Terminal.Gui {
 
 			return true;
 		}
+
+		/// <summary>
+		/// Calculate the width based on the <see cref="Width"/> settings.
+		/// </summary>
+		/// <param name="desiredWidth">The desired width.</param>
+		/// <param name="resultWidth">The real result width.</param>
+		/// <returns>True if the width can be directly assigned, false otherwise.</returns>
+		public bool SetWidth (int desiredWidth, out int resultWidth)
+		{
+			int w = desiredWidth;
+			bool canSetWidth;
+			if (Width is Dim.DimCombine || Width is Dim.DimView || Width is Dim.DimFill) {
+				// It's a Dim.DimCombine and so can't be assigned. Let it have it's width anchored.
+				w = Width.Anchor (w);
+				canSetWidth = false;
+			} else if (Width is Dim.DimFactor factor) {
+				// Tries to get the SuperView width otherwise the view width.
+				var sw = SuperView != null ? SuperView.Frame.Width : w;
+				if (factor.IsFromRemaining ()) {
+					sw -= Frame.X;
+				}
+				w = Width.Anchor (sw);
+				canSetWidth = false;
+			} else {
+				canSetWidth = true;
+			}
+			resultWidth = w;
+
+			return canSetWidth;
+		}
+
+		/// <summary>
+		/// Calculate the height based on the <see cref="Height"/> settings.
+		/// </summary>
+		/// <param name="desiredHeight">The desired height.</param>
+		/// <param name="resultHeight">The real result height.</param>
+		/// <returns>True if the height can be directly assigned, false otherwise.</returns>
+		public bool SetHeight (int desiredHeight, out int resultHeight)
+		{
+			int h = desiredHeight;
+			bool canSetHeight;
+			if (Height is Dim.DimCombine || Height is Dim.DimView || Height is Dim.DimFill) {
+				// It's a Dim.DimCombine and so can't be assigned. Let it have it's height anchored.
+				h = Height.Anchor (h);
+				canSetHeight = false;
+			} else if (Height is Dim.DimFactor factor) {
+				// Tries to get the SuperView height otherwise the view height.
+				var sh = SuperView != null ? SuperView.Frame.Height : h;
+				if (factor.IsFromRemaining ()) {
+					sh -= Frame.Y;
+				}
+				h = Height.Anchor (sh);
+				canSetHeight = false;
+			} else {
+				canSetHeight = true;
+			}
+			resultHeight = h;
+
+			return canSetHeight;
+		}
 	}
 }

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

@@ -196,12 +196,8 @@ namespace Terminal.Gui {
 
 			// Checks if there are any SuperView view which intersect with this window.
 			if (SuperView != null) {
-				foreach (var view in SuperView.Subviews) {
-					if (view != this && view.Frame.IntersectsWith (Bounds)) {
-						view.SetNeedsLayout ();
-						view.SetNeedsDisplay (view.Bounds);
-					}
-				}
+				SuperView.SetNeedsLayout ();
+				SuperView.SetNeedsDisplay ();
 			}
 		}
 
@@ -231,7 +227,7 @@ namespace Terminal.Gui {
 					Application.GrabMouse (this);
 				}
 
-				//Demo.ml2.Text = $"Starting at {dragPosition}";
+				//System.Diagnostics.Debug.WriteLine ($"Starting at {dragPosition}");
 				return true;
 			} else if (mouseEvent.Flags == (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) ||
 				mouseEvent.Flags == MouseFlags.Button3Pressed) {
@@ -249,10 +245,11 @@ namespace Terminal.Gui {
 						mouseEvent.Y + (SuperView == null ? mouseEvent.OfY : Frame.Y), out nx, out ny);
 
 					dragPosition = new Point (nx, ny);
+					LayoutSubviews ();
 					Frame = new Rect (nx, ny, Frame.Width, Frame.Height);
 					X = nx;
 					Y = ny;
-					//Demo.ml2.Text = $"{dx},{dy}";
+					//System.Diagnostics.Debug.WriteLine ($"nx:{nx},ny:{ny}");
 
 					// FIXED: optimize, only SetNeedsDisplay on the before/after regions.
 					SetNeedsDisplay ();
@@ -266,7 +263,7 @@ namespace Terminal.Gui {
 				dragPosition = null;
 			}
 
-			//Demo.ml.Text = me.ToString ();
+			//System.Diagnostics.Debug.WriteLine (mouseEvent.ToString ());
 			return false;
 		}
 

+ 3 - 12
Terminal.Gui/Views/Button.cs

@@ -146,19 +146,10 @@ namespace Terminal.Gui {
 				base.Text = ustring.Make (_leftBracket) + " " + text + " " + ustring.Make (_rightBracket);
 
 			int w = base.Text.RuneCount - (base.Text.Contains (HotKeySpecifier) ? 1 : 0);
-			if (Width is Dim.DimCombine || Width is Dim.DimView || Width is Dim.DimFill) {
-				// It's a Dim.DimCombine and so can't be assigned. Let it have it's width anchored.
-				w = Width.Anchor (w);
-			} else if (Width is Dim.DimFactor) {
-				// Tries to get the SuperView width otherwise the button width.
-				var sw = SuperView != null ? SuperView.Frame.Width : w;
-				if (((Dim.DimFactor)Width).IsFromRemaining ()) {
-					sw -= Frame.X;
-				}
-				w = Width.Anchor (sw);
-			} else {
-				Width = w;
+			if (SetWidth (w, out int rWidth)) {
+				Width = rWidth;
 			}
+			w = rWidth;
 			var layout = LayoutStyle;
 			bool layoutChanged = false;
 			if (!(Height is Dim.DimAbsolute)) {

+ 3 - 0
Terminal.Gui/Views/Menu.cs

@@ -927,6 +927,9 @@ namespace Terminal.Gui {
 		///<inheritdoc/>
 		public override void PositionCursor ()
 		{
+			if (selected == -1 && HasFocus && Menus.Length > 0) {
+				selected = 0;
+			}
 			int pos = 0;
 			for (int i = 0; i < Menus.Length; i++) {
 				if (i == selected) {

+ 5 - 5
UICatalog/Scenarios/Clipping.cs

@@ -32,7 +32,7 @@ namespace UICatalog {
 			//Win.Y = 2;
 			//Win.Width = Dim.Fill () - 4;
 			//Win.Height = Dim.Fill () - 2;
-			var label = new Label ("ScrollView (new Rect (5, 5, 100, 60)) with a 200, 100 ContentSize...") {
+			var label = new Label ("ScrollView (new Rect (3, 3, 50, 20)) with a 200, 100 ContentSize...") {
 				X = 0, Y = 0,
 				//ColorScheme = Colors.Dialog
 			};
@@ -40,10 +40,10 @@ namespace UICatalog {
 
 			var scrollView = new ScrollView (new Rect (3, 3, 50, 20));
 			scrollView.ColorScheme = Colors.Menu;
-			scrollView.ContentSize = new Size (100, 60);
+			scrollView.ContentSize = new Size (200, 100);
 			//ContentOffset = new Point (0, 0),
-			scrollView.ShowVerticalScrollIndicator = true;
-			scrollView.ShowHorizontalScrollIndicator = true;
+			//scrollView.ShowVerticalScrollIndicator = true;
+			//scrollView.ShowHorizontalScrollIndicator = true;
 
 			var embedded1 = new Window ("1") {
 				X = 3,
@@ -78,7 +78,7 @@ namespace UICatalog {
 			embedded2.Add (embedded3);
 
 			scrollView.Add (embedded1);
-					
+
 			Top.Add (scrollView);
 		}
 	}

+ 7 - 1
UICatalog/Scenarios/Threading.cs

@@ -92,7 +92,13 @@ namespace UICatalog {
 			_btnQuit.Clicked += Application.RequestStop;
 
 			Win.Add (_itemsList, _btnActionCancel, _logJob, text, _btnAction, _btnLambda, _btnHandler, _btnSync, _btnMethod, _btnClearData, _btnQuit);
-			_btnActionCancel.SetFocus ();
+
+			void Top_Loaded ()
+			{
+				_btnActionCancel.SetFocus ();
+				Top.Loaded -= Top_Loaded;
+			}
+			Top.Loaded += Top_Loaded;
 		}
 
 		private async void LoadData ()