Merge branch 'enter-leave-events' into listview-reseting

This commit is contained in:
BDisp
2020-07-05 14:26:06 +01:00
7 changed files with 50 additions and 41 deletions

View File

@@ -28,7 +28,7 @@ namespace Terminal.Gui {
/// 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>
@@ -133,7 +133,6 @@ namespace Terminal.Gui {
return false;
}
/// <summary>
/// Method invoked when a mouse event is generated
/// </summary>
@@ -167,8 +166,9 @@ namespace Terminal.Gui {
/// <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;
}
@@ -176,8 +176,9 @@ namespace Terminal.Gui {
/// <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;
}

View File

@@ -895,26 +895,31 @@ namespace Terminal.Gui {
}
}
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 (focused);
focused.hasFocus = false;
focused = null;
}
}
@@ -925,35 +930,40 @@ namespace Terminal.Gui {
/// <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;
@@ -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;

View File

@@ -184,7 +184,7 @@ namespace Terminal.Gui {
}
///<inheritdoc/>
public override bool OnEnter ()
public override bool OnEnter (View view)
{
if (!search.HasFocus)
this.SetFocus (search);

View File

@@ -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;
}

View File

@@ -93,14 +93,14 @@ namespace Terminal.Gui {
}
///<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/>

View File

@@ -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 ()));
}
}
}

View File

@@ -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
}