Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 5 commits into from Jul 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 5 additions & 4 deletions Terminal.Gui/Core/Responder.cs
Expand Up @@ -28,7 +28,7 @@ public class Responder {
/// Gets or sets a value indicating whether this <see cref="Responder"/> has focus.
/// </summary>
/// <value><c>true</c> if has focus; otherwise, <c>false</c>.</value>
public virtual bool HasFocus { get; internal set; }
public virtual bool HasFocus { get; }

// Key handling
/// <summary>
Expand Down Expand Up @@ -133,7 +133,6 @@ public virtual bool OnKeyUp (KeyEvent keyEvent)
return false;
}


/// <summary>
/// Method invoked when a mouse event is generated
/// </summary>
Expand Down Expand Up @@ -167,17 +166,19 @@ public virtual bool OnMouseLeave (MouseEvent mouseEvent)
/// <summary>
/// Method invoked when a view gets focus.
/// </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>
public virtual bool OnEnter ()
public virtual bool OnEnter (View view)
{
return false;
}

/// <summary>
/// Method invoked when a view loses focus.
/// </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>
public virtual bool OnLeave ()
public virtual bool OnLeave (View view)
{
return false;
}
Expand Down
67 changes: 39 additions & 28 deletions Terminal.Gui/Core/View.cs
Expand Up @@ -895,26 +895,31 @@ public virtual void PositionCursor ()
}
}

bool hasFocus;
/// <inheritdoc/>
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 (view);
focused.SetHasFocus (false, view);
focused = null;
}
}

Expand All @@ -925,35 +930,40 @@ public class FocusEventArgs : EventArgs {
/// <summary>
/// Constructs.
/// </summary>
public FocusEventArgs () { }
/// <param name="view">The view that gets or loses focus.</param>
public FocusEventArgs (View view) { View = view; }
/// <summary>
/// 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.
/// </summary>
public bool Handled { get; set; }
/// <summary>
/// Indicates the current view that gets or loses focus.
/// </summary>
public View View { get; set; }
}

/// <inheritdoc/>
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;
}

/// <inheritdoc/>
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;
Expand Down Expand Up @@ -1123,10 +1133,11 @@ public void SetFocus (View view)
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);

var f = focused;
focused = view;
focused.HasFocus = true;
focused.SetHasFocus (true, f);
focused.EnsureFocus ();

// Send focus upwards
Expand Down Expand Up @@ -1320,7 +1331,7 @@ public bool FocusPrev ()
continue;
}
if (w.CanFocus && focused_idx != -1) {
focused.HasFocus = false;
focused.SetHasFocus (false, w);

if (w != null && w.CanFocus)
w.FocusLast ();
Expand All @@ -1330,7 +1341,7 @@ public bool FocusPrev ()
}
}
if (focused != null) {
focused.HasFocus = false;
focused.SetHasFocus (false, this);
focused = null;
}
return false;
Expand Down Expand Up @@ -1362,7 +1373,7 @@ public bool FocusNext ()
continue;
}
if (w.CanFocus && focused_idx != -1) {
focused.HasFocus = false;
focused.SetHasFocus (false, w);

if (w != null && w.CanFocus)
w.FocusFirst ();
Expand All @@ -1372,7 +1383,7 @@ public bool FocusNext ()
}
}
if (focused != null) {
focused.HasFocus = false;
focused.SetHasFocus (false, this);
focused = null;
}
return false;
Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/Views/ComboBox.cs
Expand Up @@ -184,7 +184,7 @@ private void Search_MouseClick (MouseEventArgs e)
}

///<inheritdoc/>
public override bool OnEnter ()
public override bool OnEnter (View view)
{
if (!search.HasFocus)
this.SetFocus (search);
Expand Down
2 changes: 0 additions & 2 deletions Terminal.Gui/Views/Menu.cs
Expand Up @@ -535,8 +535,6 @@ public override bool MouseEvent (MouseEvent me)
if (item == null || !item.IsEnabled ()) disabled = true;
if (item != null && !disabled)
current = me.Y - 1;
HasFocus = true;
SetNeedsDisplay ();
CheckSubMenu ();
return true;
}
Expand Down
4 changes: 2 additions & 2 deletions Terminal.Gui/Views/TextField.cs
Expand Up @@ -93,14 +93,14 @@ void Initialize (ustring text, int w)
}

///<inheritdoc/>
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);
}

///<inheritdoc/>
Expand Down
4 changes: 2 additions & 2 deletions UnitTests/ResponderTests.cs
Expand Up @@ -32,8 +32,8 @@ public void New_Methods_Return_False ()
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 ()));
}
}
}
4 changes: 2 additions & 2 deletions UnitTests/ViewTests.cs
Expand Up @@ -102,8 +102,8 @@ public void New_Methods_Return_False ()
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
}
Expand Down