Browse Source

ref #198

pull/213/head
Nikita Tsukanov 11 years ago
parent
commit
79f8f76351
  1. 23
      src/Gtk/Perspex.Gtk/WindowImpl.cs
  2. 2
      src/Perspex.Controls/DropDown.cs
  3. 22
      src/Perspex.Controls/TextBox.cs
  4. 2
      src/Perspex.HtmlRenderer/HtmlContainer.cs
  5. 2
      src/Perspex.Input/AccessKeyHandler.cs
  6. 2
      src/Perspex.Input/IInputElement.cs
  7. 4
      src/Perspex.Input/IKeyboardDevice.cs
  8. 6
      src/Perspex.Input/InputElement.cs
  9. 2
      src/Perspex.Input/KeyEventArgs.cs
  10. 2
      src/Perspex.Input/KeyboardNavigationHandler.cs
  11. 29
      src/Perspex.Input/MouseDevice.cs
  12. 1
      src/Perspex.Input/Perspex.Input.csproj
  13. 20
      src/Perspex.Input/PointerEventArgs.cs
  14. 10
      src/Perspex.Input/PointerPressEventArgs.cs
  15. 4
      src/Perspex.Input/Raw/RawKeyEventArgs.cs
  16. 8
      src/Perspex.Input/Raw/RawMouseEventArgs.cs
  17. 4
      src/Perspex.Input/Raw/RawMouseWheelEventArgs.cs
  18. 12
      src/Windows/Perspex.Win32/Input/WindowsKeyboardDevice.cs
  19. 20
      src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs
  20. 29
      src/Windows/Perspex.Win32/WindowImpl.cs
  21. 2
      tests/Perspex.Controls.UnitTests/TopLevelTests.cs

23
src/Gtk/Perspex.Gtk/WindowImpl.cs

@ -134,26 +134,33 @@ namespace Perspex.Gtk
Activate();
}
private static ModifierKeys GetModifierKeys(ModifierType state)
private static InputModifiers GetModifierKeys(ModifierType state)
{
var rv = ModifierKeys.None;
var rv = InputModifiers.None;
if (state.HasFlag(ModifierType.ControlMask))
rv |= ModifierKeys.Control;
rv |= InputModifiers.Control;
if (state.HasFlag(ModifierType.ShiftMask))
rv |= ModifierKeys.Shift;
rv |= InputModifiers.Shift;
if (state.HasFlag(ModifierType.Mod1Mask))
rv |= ModifierKeys.Control;
rv |= InputModifiers.Control;
if(state.HasFlag(ModifierType.Button1Mask))
rv |= InputModifiers.LeftMouseButton;
if (state.HasFlag(ModifierType.Button2Mask))
rv |= InputModifiers.RightMouseButton;
return rv;
}
protected override bool OnButtonPressEvent(EventButton evnt)
{
var e = new RawMouseEventArgs(
GtkMouseDevice.Instance,
evnt.Time,
_owner,
RawMouseEventType.LeftButtonDown,
evnt.Button == 0
? RawMouseEventType.LeftButtonDown
: RawMouseEventType.RightButtonDown,
new Point(evnt.X, evnt.Y), GetModifierKeys(evnt.State));
Input(e);
return true;
@ -165,7 +172,9 @@ namespace Perspex.Gtk
GtkMouseDevice.Instance,
evnt.Time,
_owner,
RawMouseEventType.LeftButtonUp,
evnt.Button == 0
? RawMouseEventType.LeftButtonUp
: RawMouseEventType.RightButtonUp,
new Point(evnt.X, evnt.Y), GetModifierKeys(evnt.State));
Input(e);
return true;

2
src/Perspex.Controls/DropDown.cs

@ -86,7 +86,7 @@ namespace Perspex.Controls
if (!e.Handled)
{
if (e.Key == Key.F4 ||
(e.Key == Key.Down && ((e.Modifiers & ModifierKeys.Alt) != 0)))
(e.Key == Key.Down && ((e.Modifiers & InputModifiers.Alt) != 0)))
{
IsDropDownOpen = !IsDropDownOpen;
e.Handled = true;

22
src/Perspex.Controls/TextBox.cs

@ -175,21 +175,21 @@ namespace Perspex.Controls
switch (e.Key)
{
case Key.A:
if (modifiers == ModifierKeys.Control)
if (modifiers == InputModifiers.Control)
{
SelectAll();
}
break;
case Key.C:
if (modifiers == ModifierKeys.Control)
if (modifiers == InputModifiers.Control)
{
Copy();
}
break;
case Key.V:
if (modifiers == ModifierKeys.Control)
if (modifiers == InputModifiers.Control)
{
Paste();
}
@ -264,7 +264,7 @@ namespace Perspex.Controls
break;
}
if (movement && ((modifiers & ModifierKeys.Shift) != 0))
if (movement && ((modifiers & InputModifiers.Shift) != 0))
{
SelectionEnd = CaretIndex;
}
@ -335,12 +335,12 @@ namespace Perspex.Controls
return Math.Max(0, Math.Min(length, value));
}
private void MoveHorizontal(int count, ModifierKeys modifiers)
private void MoveHorizontal(int count, InputModifiers modifiers)
{
var text = Text ?? string.Empty;
var caretIndex = CaretIndex;
if ((modifiers & ModifierKeys.Control) != 0)
if ((modifiers & InputModifiers.Control) != 0)
{
if (count > 0)
{
@ -355,7 +355,7 @@ namespace Perspex.Controls
CaretIndex = caretIndex += count;
}
private void MoveVertical(int count, ModifierKeys modifiers)
private void MoveVertical(int count, InputModifiers modifiers)
{
var formattedText = _presenter.FormattedText;
var lines = formattedText.GetLines().ToList();
@ -373,12 +373,12 @@ namespace Perspex.Controls
}
}
private void MoveHome(ModifierKeys modifiers)
private void MoveHome(InputModifiers modifiers)
{
var text = Text ?? string.Empty;
var caretIndex = CaretIndex;
if ((modifiers & ModifierKeys.Control) != 0)
if ((modifiers & InputModifiers.Control) != 0)
{
caretIndex = 0;
}
@ -403,12 +403,12 @@ namespace Perspex.Controls
CaretIndex = caretIndex;
}
private void MoveEnd(ModifierKeys modifiers)
private void MoveEnd(InputModifiers modifiers)
{
var text = Text ?? string.Empty;
var caretIndex = CaretIndex;
if ((modifiers & ModifierKeys.Control) != 0)
if ((modifiers & InputModifiers.Control) != 0)
{
caretIndex = text.Length;
}

2
src/Perspex.HtmlRenderer/HtmlContainer.cs

@ -462,7 +462,7 @@ namespace TheArtOfDev.HtmlRenderer.Perspex
/// </summary>
private static RKeyEvent CreateKeyEevent(KeyEventArgs e)
{
var control = (e.Modifiers & ModifierKeys.Control) == ModifierKeys.Control;
var control = (e.Modifiers & InputModifiers.Control) == InputModifiers.Control;
return new RKeyEvent(control, e.Key == Key.A, e.Key == Key.C);
}

2
src/Perspex.Input/AccessKeyHandler.cs

@ -143,7 +143,7 @@ namespace Perspex.Input
CloseMenu();
e.Handled = true;
}
else if ((e.Modifiers & ModifierKeys.Alt) != 0 || menuIsOpen)
else if ((e.Modifiers & InputModifiers.Alt) != 0 || menuIsOpen)
{
// If any other key is pressed with the Alt key held down, or the main menu is open,
// find all controls who have registered that access key.

2
src/Perspex.Input/IInputElement.cs

@ -60,7 +60,7 @@ namespace Perspex.Input
/// <summary>
/// Occurs when the pointer is released over the control.
/// </summary>
event EventHandler<PointerEventArgs> PointerReleased;
event EventHandler<PointerReleasedEventArgs> PointerReleased;
/// <summary>
/// Occurs when the mouse wheen is scrolled over the control.

4
src/Perspex.Input/IKeyboardDevice.cs

@ -6,13 +6,15 @@ using System;
namespace Perspex.Input
{
[Flags]
public enum ModifierKeys
public enum InputModifiers
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8,
LeftMouseButton = 16,
RightMouseButton = 32
}
[Flags]

6
src/Perspex.Input/InputElement.cs

@ -123,8 +123,8 @@ namespace Perspex.Input
/// <summary>
/// Defines the <see cref="PointerReleased"/> event.
/// </summary>
public static readonly RoutedEvent<PointerEventArgs> PointerReleasedEvent =
RoutedEvent.Register<InputElement, PointerEventArgs>(
public static readonly RoutedEvent<PointerReleasedEventArgs> PointerReleasedEvent =
RoutedEvent.Register<InputElement, PointerReleasedEventArgs>(
"PointerReleased",
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
@ -240,7 +240,7 @@ namespace Perspex.Input
/// <summary>
/// Occurs when the pointer is released over the control.
/// </summary>
public event EventHandler<PointerEventArgs> PointerReleased
public event EventHandler<PointerReleasedEventArgs> PointerReleased
{
add { AddHandler(PointerReleasedEvent, value); }
remove { RemoveHandler(PointerReleasedEvent, value); }

2
src/Perspex.Input/KeyEventArgs.cs

@ -12,6 +12,6 @@ namespace Perspex.Input
public Key Key { get; set; }
public ModifierKeys Modifiers { get; set; }
public InputModifiers Modifiers { get; set; }
}
}

2
src/Perspex.Input/KeyboardNavigationHandler.cs

@ -98,7 +98,7 @@ namespace Perspex.Input
switch (e.Key)
{
case Key.Tab:
direction = (e.Modifiers & ModifierKeys.Shift) == 0 ?
direction = (e.Modifiers & InputModifiers.Shift) == 0 ?
FocusNavigationDirection.Next : FocusNavigationDirection.Previous;
break;
case Key.Up:

29
src/Perspex.Input/MouseDevice.cs

@ -77,16 +77,21 @@ namespace Perspex.Input
LeaveWindow(mouse, e.Root);
break;
case RawMouseEventType.LeftButtonDown:
MouseDown(mouse, e.Timestamp, e.Root, e.Position);
case RawMouseEventType.RightButtonDown:
MouseDown(mouse, e.Timestamp, e.Root, e.Position,
e.Type == RawMouseEventType.LeftButtonDown ? MouseButton.Left : MouseButton.Right,
e.InputModifiers);
break;
case RawMouseEventType.LeftButtonUp:
MouseUp(mouse, e.Root, e.Position);
case RawMouseEventType.RightButtonUp:
MouseUp(mouse, e.Root, e.Position,
e.Type == RawMouseEventType.LeftButtonUp ? MouseButton.Left : MouseButton.Right, e.InputModifiers);
break;
case RawMouseEventType.Move:
MouseMove(mouse, e.Root, e.Position);
MouseMove(mouse, e.Root, e.Position, e.InputModifiers);
break;
case RawMouseEventType.Wheel:
MouseWheel(mouse, e.Root, e.Position, ((RawMouseWheelEventArgs)e).Delta);
MouseWheel(mouse, e.Root, e.Position, ((RawMouseWheelEventArgs)e).Delta, e.InputModifiers);
break;
}
}
@ -96,7 +101,7 @@ namespace Perspex.Input
ClearPointerOver(this, root);
}
private void MouseDown(IMouseDevice device, uint timestamp, IInputElement root, Point p)
private void MouseDown(IMouseDevice device, uint timestamp, IInputElement root, Point p, MouseButton button, InputModifiers inputModifiers)
{
var hit = HitTest(root, p);
@ -125,6 +130,8 @@ namespace Perspex.Input
RoutedEvent = InputElement.PointerPressedEvent,
Source = source,
ClickCount = _clickCount,
MouseButton = button,
InputModifiers = inputModifiers
};
source.RaiseEvent(e);
@ -132,7 +139,7 @@ namespace Perspex.Input
}
}
private void MouseMove(IMouseDevice device, IInputRoot root, Point p)
private void MouseMove(IMouseDevice device, IInputRoot root, Point p, InputModifiers inputModifiers)
{
IInputElement source;
@ -152,10 +159,11 @@ namespace Perspex.Input
Device = this,
RoutedEvent = InputElement.PointerMovedEvent,
Source = source,
InputModifiers = inputModifiers
});
}
private void MouseUp(IMouseDevice device, IInputRoot root, Point p)
private void MouseUp(IMouseDevice device, IInputRoot root, Point p, MouseButton button, InputModifiers inputModifiers)
{
var hit = HitTest(root, p);
@ -165,17 +173,19 @@ namespace Perspex.Input
if (source != null)
{
source.RaiseEvent(new PointerEventArgs
source.RaiseEvent(new PointerReleasedEventArgs
{
Device = this,
RoutedEvent = InputElement.PointerReleasedEvent,
Source = source,
MouseButton = button,
InputModifiers = inputModifiers
});
}
}
}
private void MouseWheel(IMouseDevice device, IInputRoot root, Point p, Vector delta)
private void MouseWheel(IMouseDevice device, IInputRoot root, Point p, Vector delta, InputModifiers inputModifiers)
{
var hit = HitTest(root, p);
@ -191,6 +201,7 @@ namespace Perspex.Input
RoutedEvent = InputElement.PointerWheelChangedEvent,
Source = source,
Delta = delta,
InputModifiers = inputModifiers
});
}
}

1
src/Perspex.Input/Perspex.Input.csproj

@ -98,7 +98,6 @@
<Compile Include="Navigation\DirectionalNavigation.cs" />
<Compile Include="Navigation\TabNavigation.cs" />
<Compile Include="Platform\IPlatformSettings.cs" />
<Compile Include="PointerPressEventArgs.cs" />
<Compile Include="PointerWheelEventArgs.cs" />
<Compile Include="Raw\RawMouseWheelEventArgs.cs" />
<Compile Include="Raw\RawSizeEventArgs.cs" />

20
src/Perspex.Input/PointerEventArgs.cs

@ -10,9 +10,29 @@ namespace Perspex.Input
{
public IPointerDevice Device { get; set; }
public InputModifiers InputModifiers { get; set; }
public Point GetPosition(IVisual relativeTo)
{
return Device.GetPosition(relativeTo);
}
}
public enum MouseButton
{
None,
Left,
Right
}
public class PointerPressEventArgs : PointerEventArgs
{
public int ClickCount { get; set; }
public MouseButton MouseButton { get; set; }
}
public class PointerReleasedEventArgs : PointerEventArgs
{
public MouseButton MouseButton { get; set; }
}
}

10
src/Perspex.Input/PointerPressEventArgs.cs

@ -1,10 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
namespace Perspex.Input
{
public class PointerPressEventArgs : PointerEventArgs
{
public int ClickCount { get; set; }
}
}

4
src/Perspex.Input/Raw/RawKeyEventArgs.cs

@ -15,7 +15,7 @@ namespace Perspex.Input.Raw
IKeyboardDevice device,
uint timestamp,
RawKeyEventType type,
Key key, ModifierKeys modifiers)
Key key, InputModifiers modifiers)
: base(device, timestamp)
{
Key = key;
@ -25,7 +25,7 @@ namespace Perspex.Input.Raw
public Key Key { get; set; }
public ModifierKeys Modifiers { get; set; }
public InputModifiers Modifiers { get; set; }
public RawKeyEventType Type { get; set; }
}

8
src/Perspex.Input/Raw/RawMouseEventArgs.cs

@ -10,6 +10,8 @@ namespace Perspex.Input.Raw
LeaveWindow,
LeftButtonDown,
LeftButtonUp,
RightButtonDown,
RightButtonUp,
Move,
Wheel,
}
@ -21,7 +23,7 @@ namespace Perspex.Input.Raw
uint timestamp,
IInputRoot root,
RawMouseEventType type,
Point position, ModifierKeys modifierKeys)
Point position, InputModifiers inputModifiers)
: base(device, timestamp)
{
Contract.Requires<ArgumentNullException>(device != null);
@ -30,7 +32,7 @@ namespace Perspex.Input.Raw
Root = root;
Position = position;
Type = type;
ModifierKeys = modifierKeys;
InputModifiers = inputModifiers;
}
public IInputRoot Root { get; private set; }
@ -39,6 +41,6 @@ namespace Perspex.Input.Raw
public RawMouseEventType Type { get; private set; }
public ModifierKeys ModifierKeys { get; private set; }
public InputModifiers InputModifiers { get; private set; }
}
}

4
src/Perspex.Input/Raw/RawMouseWheelEventArgs.cs

@ -13,8 +13,8 @@ namespace Perspex.Input.Raw
uint timestamp,
IInputRoot root,
Point position,
Vector delta, ModifierKeys modifierKeys)
: base(device, timestamp, root, RawMouseEventType.Wheel, position, modifierKeys)
Vector delta, InputModifiers inputModifiers)
: base(device, timestamp, root, RawMouseEventType.Wheel, position, inputModifiers)
{
Delta = delta;
}

12
src/Windows/Perspex.Win32/Input/WindowsKeyboardDevice.cs

@ -16,31 +16,31 @@ namespace Perspex.Win32.Input
public static new WindowsKeyboardDevice Instance => s_instance;
public ModifierKeys Modifiers
public InputModifiers Modifiers
{
get
{
UpdateKeyStates();
ModifierKeys result = 0;
InputModifiers result = 0;
if (IsDown(Key.LeftAlt) || IsDown(Key.RightAlt))
{
result |= ModifierKeys.Alt;
result |= InputModifiers.Alt;
}
if (IsDown(Key.LeftCtrl) || IsDown(Key.RightCtrl))
{
result |= ModifierKeys.Control;
result |= InputModifiers.Control;
}
if (IsDown(Key.LeftShift) || IsDown(Key.RightShift))
{
result |= ModifierKeys.Shift;
result |= InputModifiers.Shift;
}
if (IsDown(Key.LWin) || IsDown(Key.RWin))
{
result |= ModifierKeys.Windows;
result |= InputModifiers.Windows;
}
return result;

20
src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs

@ -5,6 +5,8 @@ using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Text;
using Perspex.Input;
// ReSharper disable InconsistentNaming
#pragma warning disable 169
@ -191,6 +193,24 @@ namespace Perspex.Win32.Interop
SM_SYSTEMDOCKED = 0x2004,
}
[Flags]
public enum ModifierKeys
{
MK_CONTROL = 0x0008,
MK_LBUTTON = 0x0001,
MK_MBUTTON = 0x0010,
MK_RBUTTON = 0x0002,
MK_SHIFT = 0x0004,
MK_XBUTTON1 = 0x0020,
MK_XBUTTON2 = 0x0040
}
public enum WindowActivate
{
WA_INACTIVE,

29
src/Windows/Perspex.Win32/WindowImpl.cs

@ -307,21 +307,27 @@ namespace Perspex.Win32
break;
case UnmanagedMethods.WindowsMessage.WM_LBUTTONDOWN:
case UnmanagedMethods.WindowsMessage.WM_RBUTTONDOWN:
e = new RawMouseEventArgs(
WindowsMouseDevice.Instance,
timestamp,
_owner,
RawMouseEventType.LeftButtonDown,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16), WindowsKeyboardDevice.Instance.Modifiers);
msg == (int) UnmanagedMethods.WindowsMessage.WM_LBUTTONDOWN
? RawMouseEventType.LeftButtonDown
: RawMouseEventType.RightButtonDown,
new Point((uint) lParam & 0xffff, (uint) lParam >> 16), GetMouseModifiers(wParam));
break;
case UnmanagedMethods.WindowsMessage.WM_LBUTTONUP:
case UnmanagedMethods.WindowsMessage.WM_RBUTTONUP:
e = new RawMouseEventArgs(
WindowsMouseDevice.Instance,
timestamp,
_owner,
RawMouseEventType.LeftButtonUp,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16), WindowsKeyboardDevice.Instance.Modifiers);
msg == (int) UnmanagedMethods.WindowsMessage.WM_LBUTTONUP
? RawMouseEventType.LeftButtonUp
: RawMouseEventType.RightButtonUp,
new Point((uint) lParam & 0xffff, (uint) lParam >> 16), GetMouseModifiers(wParam));
break;
case UnmanagedMethods.WindowsMessage.WM_MOUSEMOVE:
@ -343,7 +349,7 @@ namespace Perspex.Win32
timestamp,
_owner,
RawMouseEventType.Move,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16), WindowsKeyboardDevice.Instance.Modifiers);
new Point((uint)lParam & 0xffff, (uint)lParam >> 16), GetMouseModifiers(wParam));
break;
case UnmanagedMethods.WindowsMessage.WM_MOUSEWHEEL:
@ -352,7 +358,7 @@ namespace Perspex.Win32
timestamp,
_owner,
ScreenToClient((uint)lParam & 0xffff, (uint)lParam >> 16),
new Vector(0, ((int)wParam >> 16) / wheelDelta), WindowsKeyboardDevice.Instance.Modifiers);
new Vector(0, ((int)wParam >> 16) / wheelDelta), GetMouseModifiers(wParam));
break;
case UnmanagedMethods.WindowsMessage.WM_MOUSELEAVE:
@ -400,6 +406,17 @@ namespace Perspex.Win32
return UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam);
}
static InputModifiers GetMouseModifiers(IntPtr wParam)
{
var keys = (UnmanagedMethods.ModifierKeys)wParam.ToInt32();
var modifiers = WindowsKeyboardDevice.Instance.Modifiers;
if (keys.HasFlag(UnmanagedMethods.ModifierKeys.MK_LBUTTON))
modifiers |= InputModifiers.LeftMouseButton;
if(keys.HasFlag(UnmanagedMethods.ModifierKeys.MK_RBUTTON))
modifiers |= InputModifiers.RightMouseButton;
return modifiers;
}
private void CreateWindow()
{
// Ensure that the delegate doesn't get garbage collected by storing it as a field.

2
tests/Perspex.Controls.UnitTests/TopLevelTests.cs

@ -296,7 +296,7 @@ namespace Perspex.Controls.UnitTests
new Mock<IKeyboardDevice>().Object,
0,
RawKeyEventType.KeyDown,
Key.A, ModifierKeys.None);
Key.A, InputModifiers.None);
impl.Object.Input(input);
var inputManagerMock = Mock.Get(InputManager.Instance);

Loading…
Cancel
Save