From ddb5ed229aa78922c5db90f5f757e4d0b1c9986d Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 9 Oct 2015 00:43:52 +0200 Subject: [PATCH] Make keyboard range selection work. --- src/Perspex.Controls/ListBox.cs | 5 ++++- src/Perspex.Input/FocusManager.cs | 16 +++++++++++----- src/Perspex.Input/GotFocusEventArgs.cs | 5 +++++ src/Perspex.Input/IFocusManager.cs | 6 +++++- src/Perspex.Input/IKeyboardDevice.cs | 5 ++++- src/Perspex.Input/IKeyboardNavigationHandler.cs | 6 +++++- src/Perspex.Input/KeyboardDevice.cs | 6 +++++- src/Perspex.Input/KeyboardNavigationHandler.cs | 10 +++++++--- .../Perspex.Win32/Input/WindowsKeyboardDevice.cs | 2 +- 9 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/Perspex.Controls/ListBox.cs b/src/Perspex.Controls/ListBox.cs index 044de39828..773a5ceb6e 100644 --- a/src/Perspex.Controls/ListBox.cs +++ b/src/Perspex.Controls/ListBox.cs @@ -38,7 +38,10 @@ namespace Perspex.Controls if (e.NavigationMethod == NavigationMethod.Directional) { - UpdateSelectionFromEventSource(e.Source); + UpdateSelectionFromEventSource( + e.Source, + true, + (e.InputModifiers & InputModifiers.Shift) != 0); } } diff --git a/src/Perspex.Input/FocusManager.cs b/src/Perspex.Input/FocusManager.cs index 945e9ad782..67fef2588c 100644 --- a/src/Perspex.Input/FocusManager.cs +++ b/src/Perspex.Input/FocusManager.cs @@ -55,7 +55,11 @@ namespace Perspex.Input /// /// The control to focus. /// The method by which focus was changed. - public void Focus(IInputElement control, NavigationMethod method = NavigationMethod.Unspecified) + /// Any input modifiers active at the time of focus. + public void Focus( + IInputElement control, + NavigationMethod method = NavigationMethod.Unspecified, + InputModifiers modifiers = InputModifiers.None) { if (control != null) { @@ -65,7 +69,7 @@ namespace Perspex.Input if (scope != null) { Scope = scope; - SetFocusedElement(scope, control, method); + SetFocusedElement(scope, control, method, modifiers); } } else if (Current != null) @@ -90,6 +94,7 @@ namespace Perspex.Input /// The focus scope. /// The element to focus. May be null. /// The method by which focus was changed. + /// Any input modifiers active at the time of focus. /// /// If the specified scope is the current then the keyboard focus /// will change. @@ -97,7 +102,8 @@ namespace Perspex.Input public void SetFocusedElement( IFocusScope scope, IInputElement element, - NavigationMethod method = NavigationMethod.Unspecified) + NavigationMethod method = NavigationMethod.Unspecified, + InputModifiers modifiers = InputModifiers.None) { Contract.Requires(scope != null); @@ -105,7 +111,7 @@ namespace Perspex.Input if (Scope == scope) { - KeyboardDevice.Instance.SetFocusedElement(element, method); + KeyboardDevice.Instance.SetFocusedElement(element, method, modifiers); } } @@ -181,7 +187,7 @@ namespace Perspex.Input if (element != null) { - Focus(element, NavigationMethod.Pointer); + Focus(element, NavigationMethod.Pointer, ev.InputModifiers); } } } diff --git a/src/Perspex.Input/GotFocusEventArgs.cs b/src/Perspex.Input/GotFocusEventArgs.cs index 492ea75074..a29a9f966a 100644 --- a/src/Perspex.Input/GotFocusEventArgs.cs +++ b/src/Perspex.Input/GotFocusEventArgs.cs @@ -14,5 +14,10 @@ namespace Perspex.Input /// Gets or sets a value indicating how the change in focus occurred. /// public NavigationMethod NavigationMethod { get; set; } + + /// + /// Gets or sets any input modifiers active at the time of focus. + /// + public InputModifiers InputModifiers { get; set; } } } diff --git a/src/Perspex.Input/IFocusManager.cs b/src/Perspex.Input/IFocusManager.cs index c813c82338..7794faebdf 100644 --- a/src/Perspex.Input/IFocusManager.cs +++ b/src/Perspex.Input/IFocusManager.cs @@ -23,7 +23,11 @@ namespace Perspex.Input /// /// The control to focus. /// The method by which focus was changed. - void Focus(IInputElement control, NavigationMethod method = NavigationMethod.Unspecified); + /// Any input modifiers active at the time of focus. + void Focus( + IInputElement control, + NavigationMethod method = NavigationMethod.Unspecified, + InputModifiers modifiers = InputModifiers.None); /// /// Notifies the focus manager of a change in focus scope. diff --git a/src/Perspex.Input/IKeyboardDevice.cs b/src/Perspex.Input/IKeyboardDevice.cs index fdf35fba1f..e0ff4c5449 100644 --- a/src/Perspex.Input/IKeyboardDevice.cs +++ b/src/Perspex.Input/IKeyboardDevice.cs @@ -30,6 +30,9 @@ namespace Perspex.Input { IInputElement FocusedElement { get; } - void SetFocusedElement(IInputElement element, NavigationMethod method); + void SetFocusedElement( + IInputElement element, + NavigationMethod method, + InputModifiers modifiers); } } diff --git a/src/Perspex.Input/IKeyboardNavigationHandler.cs b/src/Perspex.Input/IKeyboardNavigationHandler.cs index fd79e941b6..074279d718 100644 --- a/src/Perspex.Input/IKeyboardNavigationHandler.cs +++ b/src/Perspex.Input/IKeyboardNavigationHandler.cs @@ -22,6 +22,10 @@ namespace Perspex.Input /// /// The current element. /// The direction to move. - void Move(IInputElement element, FocusNavigationDirection direction); + /// Any input modifiers active at the time of focus. + void Move( + IInputElement element, + FocusNavigationDirection direction, + InputModifiers modifiers = InputModifiers.None); } } \ No newline at end of file diff --git a/src/Perspex.Input/KeyboardDevice.cs b/src/Perspex.Input/KeyboardDevice.cs index 8c2154eb8c..3032a663bd 100644 --- a/src/Perspex.Input/KeyboardDevice.cs +++ b/src/Perspex.Input/KeyboardDevice.cs @@ -45,7 +45,10 @@ namespace Perspex.Input } } - public void SetFocusedElement(IInputElement element, NavigationMethod method) + public void SetFocusedElement( + IInputElement element, + NavigationMethod method, + InputModifiers modifiers) { if (element != FocusedElement) { @@ -68,6 +71,7 @@ namespace Perspex.Input { RoutedEvent = InputElement.GotFocusEvent, NavigationMethod = method, + InputModifiers = modifiers, }); } } diff --git a/src/Perspex.Input/KeyboardNavigationHandler.cs b/src/Perspex.Input/KeyboardNavigationHandler.cs index 9c4ac508fd..7ad5a6a9ab 100644 --- a/src/Perspex.Input/KeyboardNavigationHandler.cs +++ b/src/Perspex.Input/KeyboardNavigationHandler.cs @@ -67,7 +67,11 @@ namespace Perspex.Input /// /// The current element. /// The direction to move. - public void Move(IInputElement element, FocusNavigationDirection direction) + /// Any input modifiers active at the time of focus. + public void Move( + IInputElement element, + FocusNavigationDirection direction, + InputModifiers modifiers = InputModifiers.None) { Contract.Requires(element != null); @@ -78,7 +82,7 @@ namespace Perspex.Input var method = direction == FocusNavigationDirection.Next || direction == FocusNavigationDirection.Previous ? NavigationMethod.Tab : NavigationMethod.Directional; - FocusManager.Instance.Focus(next, method); + FocusManager.Instance.Focus(next, method, modifiers); } } @@ -117,7 +121,7 @@ namespace Perspex.Input if (direction.HasValue) { - Move(current, direction.Value); + Move(current, direction.Value, e.Modifiers); e.Handled = true; } } diff --git a/src/Windows/Perspex.Win32/Input/WindowsKeyboardDevice.cs b/src/Windows/Perspex.Win32/Input/WindowsKeyboardDevice.cs index c26bfbd517..10598c4e00 100644 --- a/src/Windows/Perspex.Win32/Input/WindowsKeyboardDevice.cs +++ b/src/Windows/Perspex.Win32/Input/WindowsKeyboardDevice.cs @@ -49,7 +49,7 @@ namespace Perspex.Win32.Input public void WindowActivated(Window window) { - SetFocusedElement(window, NavigationMethod.Unspecified); + SetFocusedElement(window, NavigationMethod.Unspecified, InputModifiers.None); } public string StringFromVirtualKey(uint virtualKey)