// ----------------------------------------------------------------------- // // Copyright 2015 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex.Input { using System; using Perspex.Input.Navigation; /// /// Handles keyboard navigation for a window. /// public class KeyboardNavigationHandler : IKeyboardNavigationHandler { /// /// The window to which the handler belongs. /// private IInputRoot owner; /// /// Sets the owner of the keyboard navigation handler. /// /// The owner. /// /// This method can only be called once, typically by the owner itself on creation. /// public void SetOwner(IInputRoot owner) { Contract.Requires(owner != null); if (this.owner != null) { throw new InvalidOperationException("AccessKeyHandler owner has already been set."); } this.owner = owner; this.owner.AddHandler(InputElement.KeyDownEvent, this.OnKeyDown); } /// /// Gets the next control in the specified navigation direction. /// /// The element. /// The navigation direction. /// /// The next element in the specified direction, or null if /// was the last in therequested direction. /// public static IInputElement GetNext( IInputElement element, FocusNavigationDirection direction) { Contract.Requires(element != null); if (direction == FocusNavigationDirection.Next || direction == FocusNavigationDirection.Previous) { return TabNavigation.GetNextInTabOrder(element, direction); } else { return DirectionalNavigation.GetNext(element, direction); } } /// /// Moves the focus in the specified direction. /// /// The current element. /// The direction to move. public void Move(IInputElement element, FocusNavigationDirection direction) { Contract.Requires(element != null); var next = GetNext(element, direction); if (next != null) { FocusManager.Instance.Focus(next, true); } } /// /// Handles the Tab key being pressed in the window. /// /// The event sender. /// The event args. protected virtual void OnKeyDown(object sender, KeyEventArgs e) { var current = FocusManager.Instance.Current; if (current != null) { FocusNavigationDirection? direction = null; switch (e.Key) { case Key.Tab: direction = (KeyboardDevice.Instance.Modifiers & ModifierKeys.Shift) == 0 ? FocusNavigationDirection.Next : FocusNavigationDirection.Previous; break; case Key.Up: direction = FocusNavigationDirection.Up; break; case Key.Down: direction = FocusNavigationDirection.Down; break; case Key.Left: direction = FocusNavigationDirection.Left; break; case Key.Right: direction = FocusNavigationDirection.Right; break; } if (direction.HasValue) { this.Move(current, direction.Value); e.Handled = true; } } } } }