Browse Source

Make keyboard range selection work.

Steven Kirk 10 years ago
parent
commit
ddb5ed229a

+ 4 - 1
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);
             }
         }
 

+ 11 - 5
src/Perspex.Input/FocusManager.cs

@@ -55,7 +55,11 @@ namespace Perspex.Input
         /// </summary>
         /// <param name="control">The control to focus.</param>
         /// <param name="method">The method by which focus was changed.</param>
-        public void Focus(IInputElement control, NavigationMethod method = NavigationMethod.Unspecified)
+        /// <param name="modifiers">Any input modifiers active at the time of focus.</param>
+        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
         /// <param name="scope">The focus scope.</param>
         /// <param name="element">The element to focus. May be null.</param>
         /// <param name="method">The method by which focus was changed.</param>
+        /// <param name="modifiers">Any input modifiers active at the time of focus.</param>
         /// <remarks>
         /// If the specified scope is the current <see cref="Scope"/> 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<ArgumentNullException>(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);
                 }
             }
         }

+ 5 - 0
src/Perspex.Input/GotFocusEventArgs.cs

@@ -14,5 +14,10 @@ namespace Perspex.Input
         /// Gets or sets a value indicating how the change in focus occurred.
         /// </summary>
         public NavigationMethod NavigationMethod { get; set; }
+
+        /// <summary>
+        /// Gets or sets any input modifiers active at the time of focus.
+        /// </summary>
+        public InputModifiers InputModifiers { get; set; }
     }
 }

+ 5 - 1
src/Perspex.Input/IFocusManager.cs

@@ -23,7 +23,11 @@ namespace Perspex.Input
         /// </summary>
         /// <param name="control">The control to focus.</param>
         /// <param name="method">The method by which focus was changed.</param>
-        void Focus(IInputElement control, NavigationMethod method = NavigationMethod.Unspecified);
+        /// <param name="modifiers">Any input modifiers active at the time of focus.</param>
+        void Focus(
+            IInputElement control, 
+            NavigationMethod method = NavigationMethod.Unspecified,
+            InputModifiers modifiers = InputModifiers.None);
 
         /// <summary>
         /// Notifies the focus manager of a change in focus scope.

+ 4 - 1
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);
     }
 }

+ 5 - 1
src/Perspex.Input/IKeyboardNavigationHandler.cs

@@ -22,6 +22,10 @@ namespace Perspex.Input
         /// </summary>
         /// <param name="element">The current element.</param>
         /// <param name="direction">The direction to move.</param>
-        void Move(IInputElement element, FocusNavigationDirection direction);
+        /// <param name="modifiers">Any input modifiers active at the time of focus.</param>
+        void Move(
+            IInputElement element, 
+            FocusNavigationDirection direction,
+            InputModifiers modifiers = InputModifiers.None);
     }
 }

+ 5 - 1
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,
                     });
                 }
             }

+ 7 - 3
src/Perspex.Input/KeyboardNavigationHandler.cs

@@ -67,7 +67,11 @@ namespace Perspex.Input
         /// </summary>
         /// <param name="element">The current element.</param>
         /// <param name="direction">The direction to move.</param>
-        public void Move(IInputElement element, FocusNavigationDirection direction)
+        /// <param name="modifiers">Any input modifiers active at the time of focus.</param>
+        public void Move(
+            IInputElement element, 
+            FocusNavigationDirection direction,
+            InputModifiers modifiers = InputModifiers.None)
         {
             Contract.Requires<ArgumentNullException>(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;
                 }
             }

+ 1 - 1
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)