diff --git a/Terminal.Gui/Core/Responder.cs b/Terminal.Gui/Core/Responder.cs
index c6fd75c74..52fce4b21 100644
--- a/Terminal.Gui/Core/Responder.cs
+++ b/Terminal.Gui/Core/Responder.cs
@@ -28,7 +28,7 @@ namespace Terminal.Gui {
/// Gets or sets a value indicating whether this has focus.
///
/// true if has focus; otherwise, false.
- public virtual bool HasFocus { get; internal set; }
+ public virtual bool HasFocus { get; }
// Key handling
///
@@ -133,7 +133,6 @@ namespace Terminal.Gui {
return false;
}
-
///
/// Method invoked when a mouse event is generated
///
@@ -167,8 +166,9 @@ namespace Terminal.Gui {
///
/// Method invoked when a view gets focus.
///
+ /// The view that is losing focus.
/// true, if the event was handled, false otherwise.
- public virtual bool OnEnter ()
+ public virtual bool OnEnter (View view)
{
return false;
}
@@ -176,8 +176,9 @@ namespace Terminal.Gui {
///
/// Method invoked when a view loses focus.
///
+ /// The view that is getting focus.
/// true, if the event was handled, false otherwise.
- public virtual bool OnLeave ()
+ public virtual bool OnLeave (View view)
{
return false;
}
diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs
index 77f402f50..47481724e 100644
--- a/Terminal.Gui/Core/View.cs
+++ b/Terminal.Gui/Core/View.cs
@@ -895,26 +895,31 @@ namespace Terminal.Gui {
}
}
+ bool hasFocus;
///
public override bool HasFocus {
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 +930,40 @@ namespace Terminal.Gui {
///
/// Constructs.
///
- public FocusEventArgs () { }
+ /// The view that gets or loses focus.
+ public FocusEventArgs (View view) { View = view; }
///
/// 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.
///
public bool Handled { get; set; }
+ ///
+ /// Indicates the current view that gets or loses focus.
+ ///
+ public View View { get; set; }
}
///
- public override bool OnEnter ()
+ public override bool OnEnter (View view)
{
- FocusEventArgs args = new FocusEventArgs ();
+ FocusEventArgs args = new FocusEventArgs (view);
Enter?.Invoke (args);
if (args.Handled)
return true;
- if (base.OnEnter ())
+ if (base.OnEnter (view))
return true;
return false;
}
///
- public override bool OnLeave ()
+ public override bool OnLeave (View view)
{
- FocusEventArgs args = new FocusEventArgs ();
+ FocusEventArgs args = new FocusEventArgs (view);
Leave?.Invoke (args);
if (args.Handled)
return true;
- if (base.OnLeave ())
+ if (base.OnLeave (view))
return true;
return false;
@@ -1123,10 +1133,10 @@ namespace Terminal.Gui {
throw new ArgumentException ("the specified view is not part of the hierarchy of this view");
if (focused != null)
- focused.HasFocus = false;
+ focused.SetHasFocus (false, view);
focused = view;
- focused.HasFocus = true;
+ focused.SetHasFocus (true, view);
focused.EnsureFocus ();
// Send focus upwards
@@ -1320,7 +1330,7 @@ namespace Terminal.Gui {
continue;
}
if (w.CanFocus && focused_idx != -1) {
- focused.HasFocus = false;
+ focused.SetHasFocus (false, w);
if (w != null && w.CanFocus)
w.FocusLast ();
@@ -1330,7 +1340,7 @@ namespace Terminal.Gui {
}
}
if (focused != null) {
- focused.HasFocus = false;
+ focused.SetHasFocus (false, focused);
focused = null;
}
return false;
@@ -1362,7 +1372,7 @@ namespace Terminal.Gui {
continue;
}
if (w.CanFocus && focused_idx != -1) {
- focused.HasFocus = false;
+ focused.SetHasFocus (false, w);
if (w != null && w.CanFocus)
w.FocusFirst ();
@@ -1372,7 +1382,7 @@ namespace Terminal.Gui {
}
}
if (focused != null) {
- focused.HasFocus = false;
+ focused.SetHasFocus (false, this);
focused = null;
}
return false;
diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs
index aff1f2c6f..2c3e4d5df 100644
--- a/Terminal.Gui/Views/ComboBox.cs
+++ b/Terminal.Gui/Views/ComboBox.cs
@@ -184,7 +184,7 @@ namespace Terminal.Gui {
}
///
- public override bool OnEnter ()
+ public override bool OnEnter (View view)
{
if (!search.HasFocus)
this.SetFocus (search);
diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs
index 554424f5e..40d53fa22 100644
--- a/Terminal.Gui/Views/Menu.cs
+++ b/Terminal.Gui/Views/Menu.cs
@@ -535,8 +535,6 @@ namespace Terminal.Gui {
if (item == null || !item.IsEnabled ()) disabled = true;
if (item != null && !disabled)
current = me.Y - 1;
- HasFocus = true;
- SetNeedsDisplay ();
CheckSubMenu ();
return true;
}
diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs
index 2fa43f832..1624b6e34 100644
--- a/Terminal.Gui/Views/TextField.cs
+++ b/Terminal.Gui/Views/TextField.cs
@@ -93,14 +93,14 @@ namespace Terminal.Gui {
}
///
- public override bool OnLeave ()
+ public override bool OnLeave (View view)
{
if (Application.mouseGrabView != null && Application.mouseGrabView == this)
Application.UngrabMouse ();
if (SelectedLength != 0 && !(Application.mouseGrabView is MenuBar))
ClearAllSelection ();
- return base.OnLeave ();
+ return base.OnLeave (view);
}
///
diff --git a/UnitTests/ResponderTests.cs b/UnitTests/ResponderTests.cs
index 1e662a608..43e9cf186 100644
--- a/UnitTests/ResponderTests.cs
+++ b/UnitTests/ResponderTests.cs
@@ -32,8 +32,8 @@ namespace Terminal.Gui {
Assert.False (r.MouseEvent (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.OnEnter ());
- Assert.False (r.OnLeave ());
+ Assert.False (r.OnEnter (new View ()));
+ Assert.False (r.OnLeave (new View ()));
}
}
}
diff --git a/UnitTests/ViewTests.cs b/UnitTests/ViewTests.cs
index 43473921b..4904ff684 100644
--- a/UnitTests/ViewTests.cs
+++ b/UnitTests/ViewTests.cs
@@ -102,8 +102,8 @@ namespace Terminal.Gui {
Assert.False (r.MouseEvent (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.OnEnter ());
- Assert.False (r.OnLeave ());
+ Assert.False (r.OnEnter (new View ()));
+ Assert.False (r.OnLeave (new View ()));
// TODO: Add more
}