Browse Source

Move click focus handling to FocusManager.

pull/58/head
Steven Kirk 11 years ago
parent
commit
0959817b35
  1. 46
      Perspex.Input/FocusManager.cs
  2. 23
      Perspex.Input/MouseDevice.cs
  3. 1
      TestApplication/App.cs

46
Perspex.Input/FocusManager.cs

@ -11,6 +11,8 @@ namespace Perspex.Input
using System.Linq; using System.Linq;
using Perspex.VisualTree; using Perspex.VisualTree;
using Splat; using Splat;
using Perspex.Interactivity;
/// <summary> /// <summary>
/// Manages focus for the application. /// Manages focus for the application.
@ -23,6 +25,17 @@ namespace Perspex.Input
private Dictionary<IFocusScope, IInputElement> focusScopes = private Dictionary<IFocusScope, IInputElement> focusScopes =
new Dictionary<IFocusScope, IInputElement>(); new Dictionary<IFocusScope, IInputElement>();
/// <summary>
/// Initializes a new instance of the <see cref="FocusManager"/> class.
/// </summary>
public FocusManager()
{
InputElement.PointerPressedEvent.AddClassHandler(
typeof(IInputElement),
new EventHandler<RoutedEventArgs>(this.OnPreviewPointerPressed),
RoutingStrategies.Tunnel);
}
/// <summary> /// <summary>
/// Gets the instance of the <see cref="IFocusManager"/>. /// Gets the instance of the <see cref="IFocusManager"/>.
/// </summary> /// </summary>
@ -135,6 +148,13 @@ namespace Perspex.Input
this.Focus(e); this.Focus(e);
} }
/// <summary>
/// Checks if the specified element can be focused.
/// </summary>
/// <param name="e">The element.</param>
/// <returns>True if the element can be focused.</returns>
private static bool CanFocus(IInputElement e) => e.Focusable && e.IsEnabledCore && e.IsVisible;
/// <summary> /// <summary>
/// Gets the focus scope ancestors of the specified control, traversing popups. /// Gets the focus scope ancestors of the specified control, traversing popups.
/// </summary> /// </summary>
@ -155,5 +175,31 @@ namespace Perspex.Input
((control as IHostedVisualTreeRoot)?.Host as IInputElement); ((control as IHostedVisualTreeRoot)?.Host as IInputElement);
} }
} }
/// <summary>
/// Global handler for pointer pressed events.
/// </summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event args.</param>
private void OnPreviewPointerPressed(object sender, RoutedEventArgs e)
{
if (sender == e.Source)
{
var ev = (PointerPressEventArgs)e;
var element = (ev.Device.Captured as IInputElement) ?? (e.Source as IInputElement);
if (element == null || !CanFocus(element))
{
element = element.GetSelfAndVisualAncestors()
.OfType<IInputElement>()
.FirstOrDefault(x => CanFocus(x));
}
if (element != null)
{
this.Focus(element);
}
}
}
} }
} }

23
Perspex.Input/MouseDevice.cs

@ -140,13 +140,6 @@ namespace Perspex.Input
source.RaiseEvent(e); source.RaiseEvent(e);
} }
IInputElement focusable = this.GetFocusable(hit);
if (focusable != null && focusable.Focusable && focusable.IsEffectivelyVisible)
{
focusable.Focus();
}
} }
} }
@ -227,22 +220,6 @@ namespace Perspex.Input
} }
} }
private IInputElement GetFocusable(IVisual hit)
{
var inputFocus = this.Captured as IInputElement;
if (inputFocus != null && inputFocus.Focusable)
{
return inputFocus;
}
else
{
return hit.GetSelfAndVisualAncestors()
.OfType<IInputElement>()
.FirstOrDefault(x => x.Focusable);
}
}
private IInteractive GetSource(IVisual hit) private IInteractive GetSource(IVisual hit)
{ {
return this.Captured ?? return this.Captured ??

1
TestApplication/App.cs

@ -20,7 +20,6 @@
public App() public App()
: base(new DefaultTheme()) : base(new DefaultTheme())
{ {
this.RegisterServices();
#if PERSPEX_CAIRO #if PERSPEX_CAIRO
CairoPlatform.Initialize(); CairoPlatform.Initialize();
#else #else

Loading…
Cancel
Save