Browse Source

Fixes #743. Added View argument to the Enter and Leave events.

BDisp 5 years ago
parent
commit
caa43eb371

+ 6 - 4
Terminal.Gui/Core/Responder.cs

@@ -24,11 +24,12 @@ namespace Terminal.Gui {
 		/// <value><c>true</c> if can focus; otherwise, <c>false</c>.</value>
 		/// <value><c>true</c> if can focus; otherwise, <c>false</c>.</value>
 		public virtual bool CanFocus { get; set; }
 		public virtual bool CanFocus { get; set; }
 
 
+		internal bool hasFocus;
 		/// <summary>
 		/// <summary>
 		/// Gets or sets a value indicating whether this <see cref="Responder"/> has focus.
 		/// Gets or sets a value indicating whether this <see cref="Responder"/> has focus.
 		/// </summary>
 		/// </summary>
 		/// <value><c>true</c> if has focus; otherwise, <c>false</c>.</value>
 		/// <value><c>true</c> if has focus; otherwise, <c>false</c>.</value>
-		public virtual bool HasFocus { get; internal set; }
+		public virtual bool HasFocus { get { return hasFocus; } }
 
 
 		// Key handling
 		// Key handling
 		/// <summary>
 		/// <summary>
@@ -133,7 +134,6 @@ namespace Terminal.Gui {
 			return false;
 			return false;
 		}
 		}
 
 
-
 		/// <summary>
 		/// <summary>
 		/// Method invoked when a mouse event is generated
 		/// Method invoked when a mouse event is generated
 		/// </summary>
 		/// </summary>
@@ -167,8 +167,9 @@ namespace Terminal.Gui {
 		/// <summary>
 		/// <summary>
 		/// Method invoked when a view gets focus.
 		/// Method invoked when a view gets focus.
 		/// </summary>
 		/// </summary>
+		/// <param name="view">The view that is losing focus.</param>
 		/// <returns><c>true</c>, if the event was handled, <c>false</c> otherwise.</returns>
 		/// <returns><c>true</c>, if the event was handled, <c>false</c> otherwise.</returns>
-		public virtual bool OnEnter ()
+		public virtual bool OnEnter (View view)
 		{
 		{
 			return false;
 			return false;
 		}
 		}
@@ -176,8 +177,9 @@ namespace Terminal.Gui {
 		/// <summary>
 		/// <summary>
 		/// Method invoked when a view loses focus.
 		/// Method invoked when a view loses focus.
 		/// </summary>
 		/// </summary>
+		/// <param name="view">The view that is getting focus.</param>
 		/// <returns><c>true</c>, if the event was handled, <c>false</c> otherwise.</returns>
 		/// <returns><c>true</c>, if the event was handled, <c>false</c> otherwise.</returns>
-		public virtual bool OnLeave ()
+		public virtual bool OnLeave (View view)
 		{
 		{
 			return false;
 			return false;
 		}
 		}

+ 37 - 28
Terminal.Gui/Core/View.cs

@@ -898,23 +898,27 @@ namespace Terminal.Gui {
 		/// <inheritdoc/>
 		/// <inheritdoc/>
 		public override bool HasFocus {
 		public override bool HasFocus {
 			get {
 			get {
-				return base.HasFocus;
+				return hasFocus;
 			}
 			}
-			internal set {
-				if (base.HasFocus != value)
-					if (value)
-						OnEnter ();
-					else
-						OnLeave ();
-				SetNeedsDisplay ();
-				base.HasFocus = value;
+		}
 
 
-				// Remove focus down the chain of subviews if focus is removed
-				if (!value && focused != null) {
-					focused.OnLeave ();
-					focused.HasFocus = false;
-					focused = null;
-				}
+		void SetHasFocus (bool value, View view)
+		{
+			if (hasFocus != value) {
+				hasFocus = value;
+			}
+			if (value) {
+				OnEnter (view);
+			} else {
+				OnLeave (view);
+			}
+			SetNeedsDisplay ();
+
+			// Remove focus down the chain of subviews if focus is removed
+			if (!value && focused != null) {
+				focused.OnLeave (focused);
+				focused.hasFocus = false;
+				focused = null;
 			}
 			}
 		}
 		}
 
 
@@ -925,35 +929,40 @@ namespace Terminal.Gui {
 			/// <summary>
 			/// <summary>
 			/// Constructs.
 			/// Constructs.
 			/// </summary>
 			/// </summary>
-			public FocusEventArgs () { }
+			/// <param name="view">The view that gets or loses focus.</param>
+			public FocusEventArgs (View view) { View = view; }
 			/// <summary>
 			/// <summary>
 			/// Indicates if the current focus event has already been processed and the driver should stop notifying any other event subscriber.
 			/// Indicates if the current focus event has already been processed and the driver should stop notifying any other event subscriber.
 			/// Its important to set this value to true specially when updating any View's layout from inside the subscriber method.
 			/// Its important to set this value to true specially when updating any View's layout from inside the subscriber method.
 			/// </summary>
 			/// </summary>
 			public bool Handled { get; set; }
 			public bool Handled { get; set; }
+			/// <summary>
+			/// Indicates the current view that gets or loses focus.
+			/// </summary>
+			public View View { get; set; }
 		}
 		}
 
 
 		/// <inheritdoc/>
 		/// <inheritdoc/>
-		public override bool OnEnter ()
+		public override bool OnEnter (View view)
 		{
 		{
-			FocusEventArgs args = new FocusEventArgs ();
+			FocusEventArgs args = new FocusEventArgs (view);
 			Enter?.Invoke (args);
 			Enter?.Invoke (args);
 			if (args.Handled)
 			if (args.Handled)
 				return true;
 				return true;
-			if (base.OnEnter ())
+			if (base.OnEnter (view))
 				return true;
 				return true;
 
 
 			return false;
 			return false;
 		}
 		}
 
 
 		/// <inheritdoc/>
 		/// <inheritdoc/>
-		public override bool OnLeave ()
+		public override bool OnLeave (View view)
 		{
 		{
-			FocusEventArgs args = new FocusEventArgs ();
+			FocusEventArgs args = new FocusEventArgs (view);
 			Leave?.Invoke (args);
 			Leave?.Invoke (args);
 			if (args.Handled)
 			if (args.Handled)
 				return true;
 				return true;
-			if (base.OnLeave ())
+			if (base.OnLeave (view))
 				return true;
 				return true;
 
 
 			return false;
 			return false;
@@ -1123,10 +1132,10 @@ namespace Terminal.Gui {
 				throw new ArgumentException ("the specified view is not part of the hierarchy of this view");
 				throw new ArgumentException ("the specified view is not part of the hierarchy of this view");
 
 
 			if (focused != null)
 			if (focused != null)
-				focused.HasFocus = false;
+				focused.SetHasFocus (false, view);
 
 
 			focused = view;
 			focused = view;
-			focused.HasFocus = true;
+			focused.SetHasFocus (true, view);
 			focused.EnsureFocus ();
 			focused.EnsureFocus ();
 
 
 			// Send focus upwards
 			// Send focus upwards
@@ -1320,7 +1329,7 @@ namespace Terminal.Gui {
 					continue;
 					continue;
 				}
 				}
 				if (w.CanFocus && focused_idx != -1) {
 				if (w.CanFocus && focused_idx != -1) {
-					focused.HasFocus = false;
+					focused.SetHasFocus (false, w);
 
 
 					if (w != null && w.CanFocus)
 					if (w != null && w.CanFocus)
 						w.FocusLast ();
 						w.FocusLast ();
@@ -1330,7 +1339,7 @@ namespace Terminal.Gui {
 				}
 				}
 			}
 			}
 			if (focused != null) {
 			if (focused != null) {
-				focused.HasFocus = false;
+				focused.SetHasFocus (false, focused);
 				focused = null;
 				focused = null;
 			}
 			}
 			return false;
 			return false;
@@ -1362,7 +1371,7 @@ namespace Terminal.Gui {
 					continue;
 					continue;
 				}
 				}
 				if (w.CanFocus && focused_idx != -1) {
 				if (w.CanFocus && focused_idx != -1) {
-					focused.HasFocus = false;
+					focused.SetHasFocus (false, w);
 
 
 					if (w != null && w.CanFocus)
 					if (w != null && w.CanFocus)
 						w.FocusFirst ();
 						w.FocusFirst ();
@@ -1372,7 +1381,7 @@ namespace Terminal.Gui {
 				}
 				}
 			}
 			}
 			if (focused != null) {
 			if (focused != null) {
-				focused.HasFocus = false;
+				focused.SetHasFocus (false, focused);
 				focused = null;
 				focused = null;
 			}
 			}
 			return false;
 			return false;

+ 1 - 1
Terminal.Gui/Views/Menu.cs

@@ -535,7 +535,7 @@ namespace Terminal.Gui {
 				if (item == null || !item.IsEnabled ()) disabled = true;
 				if (item == null || !item.IsEnabled ()) disabled = true;
 				if (item != null && !disabled)
 				if (item != null && !disabled)
 					current = me.Y - 1;
 					current = me.Y - 1;
-				HasFocus = true;
+				hasFocus = true;
 				SetNeedsDisplay ();
 				SetNeedsDisplay ();
 				CheckSubMenu ();
 				CheckSubMenu ();
 				return true;
 				return true;

+ 2 - 2
Terminal.Gui/Views/TextField.cs

@@ -93,14 +93,14 @@ namespace Terminal.Gui {
 		}
 		}
 
 
 		///<inheritdoc/>
 		///<inheritdoc/>
-		public override bool OnLeave ()
+		public override bool OnLeave (View view)
 		{
 		{
 			if (Application.mouseGrabView != null && Application.mouseGrabView == this)
 			if (Application.mouseGrabView != null && Application.mouseGrabView == this)
 				Application.UngrabMouse ();
 				Application.UngrabMouse ();
 			if (SelectedLength != 0 && !(Application.mouseGrabView is MenuBar))
 			if (SelectedLength != 0 && !(Application.mouseGrabView is MenuBar))
 				ClearAllSelection ();
 				ClearAllSelection ();
 
 
-			return base.OnLeave ();
+			return base.OnLeave (view);
 		}
 		}
 
 
 		///<inheritdoc/>
 		///<inheritdoc/>

+ 2 - 2
UnitTests/ResponderTests.cs

@@ -32,8 +32,8 @@ namespace Terminal.Gui {
 			Assert.False (r.MouseEvent (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.MouseEvent (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseEnter (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseEnter (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseLeave (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseLeave (new MouseEvent () { Flags = MouseFlags.AllEvents }));
-			Assert.False (r.OnEnter ());
-			Assert.False (r.OnLeave ());
+			Assert.False (r.OnEnter (new View ()));
+			Assert.False (r.OnLeave (new View ()));
 		}
 		}
 	}
 	}
 }
 }

+ 2 - 2
UnitTests/ViewTests.cs

@@ -102,8 +102,8 @@ namespace Terminal.Gui {
 			Assert.False (r.MouseEvent (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.MouseEvent (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseEnter (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseEnter (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseLeave (new MouseEvent () { Flags = MouseFlags.AllEvents }));
 			Assert.False (r.OnMouseLeave (new MouseEvent () { Flags = MouseFlags.AllEvents }));
-			Assert.False (r.OnEnter ());
-			Assert.False (r.OnLeave ());
+			Assert.False (r.OnEnter (new View ()));
+			Assert.False (r.OnLeave (new View ()));
 
 
 			// TODO: Add more
 			// TODO: Add more
 		}
 		}