Browse Source

Merge pull request #920 from BDisp/initialized

Fixes #919 Initialized and CanFocus.
Charlie Kindel 4 years ago
parent
commit
09bd48369d
2 changed files with 41 additions and 16 deletions
  1. 19 2
      Terminal.Gui/Core/View.cs
  2. 22 14
      UnitTests/ViewTests.cs

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

@@ -283,12 +283,15 @@ namespace Terminal.Gui {
 		public override bool CanFocus {
 			get => base.CanFocus;
 			set {
+				if (!addingView && IsInitialized && SuperView?.CanFocus == false && value) {
+					throw new InvalidOperationException ("Cannot set CanFocus to true if the SuperView CanFocus is false!");
+				}
 				if (base.CanFocus != value) {
 					base.CanFocus = value;
 					if (!value && tabIndex > -1) {
 						TabIndex = -1;
 					}
-					if (value && SuperView != null && !SuperView.CanFocus) {
+					if (value && SuperView?.CanFocus == false && addingView) {
 						SuperView.CanFocus = value;
 					}
 					if (value && tabIndex == -1) {
@@ -305,8 +308,12 @@ namespace Terminal.Gui {
 								view.CanFocus = value;
 								view.tabIndex = -1;
 							} else {
+								if (addingView) {
+									view.addingView = true;
+								}
 								view.CanFocus = view.oldCanFocus;
 								view.tabIndex = view.oldTabIndex;
+								view.addingView = false;
 							}
 						}
 					}
@@ -693,6 +700,8 @@ namespace Terminal.Gui {
 				container.ChildNeedsDisplay ();
 		}
 
+		internal bool addingView = false;
+
 		/// <summary>
 		///   Adds a subview (child) to this view.
 		/// </summary>
@@ -713,14 +722,22 @@ namespace Terminal.Gui {
 			tabIndexes.Add (view);
 			view.container = this;
 			if (view.CanFocus) {
+				addingView = true;
+				if (SuperView?.CanFocus == false) {
+					SuperView.addingView = true;
+					SuperView.CanFocus = true;
+					SuperView.addingView = false;
+				}
 				CanFocus = true;
 				view.tabIndex = tabIndexes.IndexOf (view);
+				addingView = false;
 			}
 			SetNeedsLayout ();
 			SetNeedsDisplay ();
 			OnAdded (view);
 			if (IsInitialized) {
 				view.BeginInit ();
+				view.EndInit ();
 			}
 		}
 
@@ -1985,7 +2002,6 @@ namespace Terminal.Gui {
 			if (!IsInitialized) {
 				oldCanFocus = CanFocus;
 				oldTabIndex = tabIndex;
-				Initialized?.Invoke (this, EventArgs.Empty);
 			}
 			if (subviews?.Count > 0) {
 				foreach (var view in subviews) {
@@ -2009,6 +2025,7 @@ namespace Terminal.Gui {
 					}
 				}
 			}
+			Initialized?.Invoke (this, EventArgs.Empty);
 		}
 
 		/// <summary>

+ 22 - 14
UnitTests/ViewTests.cs

@@ -578,10 +578,10 @@ namespace Terminal.Gui {
 			t.Initialized += (s, e) => {
 				tc++;
 				Assert.Equal (1, tc);
-				Assert.Equal (0, wc);
-				Assert.Equal (0, v1c);
-				Assert.Equal (0, v2c);
-				Assert.Equal (0, sv1c);
+				Assert.Equal (1, wc);
+				Assert.Equal (1, v1c);
+				Assert.Equal (1, v2c);
+				Assert.Equal (1, sv1c);
 
 				Assert.True (t.CanFocus);
 				Assert.True (w.CanFocus);
@@ -611,8 +611,8 @@ namespace Terminal.Gui {
 				Assert.Equal (t.Frame.Width, sv1.Frame.Width);
 				Assert.Equal (t.Frame.Height, sv1.Frame.Height);
 				Assert.False (sv1.CanFocus);
-				sv1.CanFocus = true;
-				Assert.True (sv1.CanFocus);
+				Assert.Throws<InvalidOperationException> (() => sv1.CanFocus = true);
+				Assert.False (sv1.CanFocus);
 			};
 
 			v1.Add (sv1);
@@ -637,7 +637,10 @@ namespace Terminal.Gui {
 			Assert.True (w.CanFocus);
 			Assert.False (v1.CanFocus);
 			Assert.False (v2.CanFocus);
-			Assert.True (sv1.CanFocus);
+			Assert.False (sv1.CanFocus);
+
+			v1.CanFocus = true;
+			Assert.False (sv1.CanFocus); // False because sv1 was disposed and it isn't a subview of v1.
 		}
 
 		[Fact]
@@ -656,10 +659,10 @@ namespace Terminal.Gui {
 			t.Initialized += (s, e) => {
 				tc++;
 				Assert.Equal (1, tc);
-				Assert.Equal (0, wc);
-				Assert.Equal (0, v1c);
-				Assert.Equal (0, v2c);
-				Assert.Equal (0, sv1c);
+				Assert.Equal (1, wc);
+				Assert.Equal (1, v1c);
+				Assert.Equal (1, v2c);
+				Assert.Equal (0, sv1c); // Added after t in the Application.Iteration.
 
 				Assert.True (t.CanFocus);
 				Assert.True (w.CanFocus);
@@ -694,8 +697,8 @@ namespace Terminal.Gui {
 					Assert.NotEqual (t.Frame.Width, sv1.Frame.Width);
 					Assert.NotEqual (t.Frame.Height, sv1.Frame.Height);
 					Assert.False (sv1.CanFocus);
-					sv1.CanFocus = true;
-					Assert.True (sv1.CanFocus);
+					Assert.Throws<InvalidOperationException> (() => sv1.CanFocus = true);
+					Assert.False (sv1.CanFocus);
 				};
 
 				v1.Add (sv1);
@@ -813,7 +816,11 @@ namespace Terminal.Gui {
 				Assert.False (f.CanFocus);
 				Assert.False (v.CanFocus);
 
-				v.CanFocus = true;
+				Assert.Throws<InvalidOperationException> (() => v.CanFocus = true);
+				Assert.False (f.CanFocus);
+				Assert.False (v.CanFocus);
+
+				f.CanFocus = true;
 				Assert.True (f.CanFocus);
 				Assert.True (v.CanFocus);
 			};
@@ -1015,5 +1022,6 @@ namespace Terminal.Gui {
 			Application.Run ();
 			Application.Shutdown ();
 		}
+
 	}
 }