Browse Source

Restore focus when menu item clicked.

pull/58/head
Steven Kirk 11 years ago
parent
commit
9ae44342e5
  1. 12
      Perspex.Controls/Menu.cs
  2. 11
      Perspex.Controls/PopupRoot.cs
  3. 41
      Perspex.Input/FocusManager.cs
  4. 2
      Perspex.Input/MouseDevice.cs
  5. 1
      Perspex.SceneGraph/Perspex.SceneGraph.csproj
  6. 22
      Perspex.SceneGraph/VisualTree/IHostedVisualTreeRoot.cs

12
Perspex.Controls/Menu.cs

@ -132,16 +132,6 @@ namespace Perspex.Controls
this.subscription.Dispose();
}
/// <summary>
/// Called when the <see cref="Menu"/> loses focus.
/// </summary>
/// <param name="e">The event args.</param>
protected override void OnLostFocus(RoutedEventArgs e)
{
base.OnLostFocus(e);
//this.Close();
}
/// <summary>
/// Called when a key is pressed within the menu.
/// </summary>
@ -205,6 +195,8 @@ namespace Perspex.Controls
private void OnMenuClick(RoutedEventArgs e)
{
this.Close();
FocusManager.Instance.Focus(null);
e.Handled = true;
}
/// <summary>

11
Perspex.Controls/PopupRoot.cs

@ -11,11 +11,12 @@ namespace Perspex.Controls
using Perspex.Media;
using Perspex.Platform;
using Splat;
using Perspex.VisualTree;
/// <summary>
/// The root window of a <see cref="Popup"/>.
/// </summary>
public class PopupRoot : TopLevel, IInteractive
public class PopupRoot : TopLevel, IInteractive, IHostedVisualTreeRoot
{
/// <summary>
/// Initializes static members of the <see cref="PopupRoot"/> class.
@ -64,6 +65,14 @@ namespace Perspex.Controls
get { return this.Parent; }
}
/// <summary>
/// Gets the control that is hosting the popup root.
/// </summary>
IVisual IHostedVisualTreeRoot.Host
{
get { return this.Parent; }
}
/// <summary>
/// Sets the position of the popup in screen coordinates.
/// </summary>

41
Perspex.Input/FocusManager.cs

@ -59,19 +59,29 @@ namespace Perspex.Input
{
if (control != null)
{
var scope = control.GetSelfAndVisualAncestors()
.OfType<IFocusScope>()
.FirstOrDefault() ?? this.Scope;
var scope = GetFocusScopeAncestors(control)
.FirstOrDefault();
if (scope != null)
{
this.Scope = scope;
this.SetFocusedElement(scope, control, keyboardNavigated);
System.Diagnostics.Debug.WriteLine("Focused " + control.GetType().Name);
}
}
else
else if (this.Current != null)
{
this.SetFocusedElement(this.Scope, null);
// If control is null, set focus to the topmost focus scope.
foreach (var scope in GetFocusScopeAncestors(this.Current).Reverse().ToList())
{
IInputElement element;
if (this.focusScopes.TryGetValue(scope, out element))
{
this.Focus(element, keyboardNavigated);
break;
}
}
}
}
@ -124,5 +134,26 @@ namespace Perspex.Input
this.Scope = scope;
this.Focus(e);
}
/// <summary>
/// Gets the focus scope ancestors of the specified control, traversing popups.
/// </summary>
/// <param name="control">The control.</param>
/// <returns>The focus scopes.</returns>
private static IEnumerable<IFocusScope> GetFocusScopeAncestors(IInputElement control)
{
while (control != null)
{
var scope = control as IFocusScope;
if (scope != null)
{
yield return scope;
}
control = control.GetVisualParent<IInputElement>() ??
((control as IHostedVisualTreeRoot)?.Host as IInputElement);
}
}
}
}

2
Perspex.Input/MouseDevice.cs

@ -143,7 +143,7 @@ namespace Perspex.Input
IInputElement focusable = this.GetFocusable(hit);
if (focusable != null && focusable.Focusable)
if (focusable != null && focusable.Focusable && focusable.IsEffectivelyVisible)
{
focusable.Focus();
}

1
Perspex.SceneGraph/Perspex.SceneGraph.csproj

@ -101,6 +101,7 @@
<Compile Include="Thickness.cs" />
<Compile Include="Vector.cs" />
<Compile Include="Visual.cs" />
<Compile Include="VisualTree\IHostedVisualTreeRoot.cs" />
<Compile Include="VisualTree\IVisualTreeHost.cs" />
<Compile Include="VisualTree\TransformedBounds.cs" />
<Compile Include="VisualTree\BoundsTracker.cs" />

22
Perspex.SceneGraph/VisualTree/IHostedVisualTreeRoot.cs

@ -0,0 +1,22 @@
// -----------------------------------------------------------------------
// <copyright file="IVisualTreeHost.cs" company="Steven Kirk">
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.VisualTree
{
/// <summary>
/// Interface for controls that are at the root of a hosted visual tree, such as popups.
/// </summary>
public interface IHostedVisualTreeRoot
{
/// <summary>
/// Gets the visual tree host.
/// </summary>
/// <value>
/// The visual tree host.
/// </value>
IVisual Host { get; }
}
}
Loading…
Cancel
Save