|
|
|
@ -94,11 +94,13 @@ namespace Avalonia.Input |
|
|
|
{ |
|
|
|
if (_pointer.Captured == null) |
|
|
|
{ |
|
|
|
SetPointerOver(this, 0 /* TODO: proper timestamp */, root, clientPoint, InputModifiers.None); |
|
|
|
SetPointerOver(this, 0 /* TODO: proper timestamp */, root, clientPoint, |
|
|
|
PointerPointProperties.None, KeyModifiers.None); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
SetPointerOver(this, 0 /* TODO: proper timestamp */, root, _pointer.Captured, InputModifiers.None); |
|
|
|
SetPointerOver(this, 0 /* TODO: proper timestamp */, root, _pointer.Captured, |
|
|
|
PointerPointProperties.None, KeyModifiers.None); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -123,69 +125,73 @@ namespace Avalonia.Input |
|
|
|
|
|
|
|
Position = e.Root.PointToScreen(e.Position); |
|
|
|
var props = CreateProperties(e); |
|
|
|
var keyModifiers = KeyModifiersUtils.ConvertToKey(e.InputModifiers); |
|
|
|
switch (e.Type) |
|
|
|
{ |
|
|
|
case RawPointerEventType.LeaveWindow: |
|
|
|
LeaveWindow(mouse, e.Timestamp, e.Root, e.InputModifiers); |
|
|
|
LeaveWindow(mouse, e.Timestamp, e.Root, props, keyModifiers); |
|
|
|
break; |
|
|
|
case RawPointerEventType.LeftButtonDown: |
|
|
|
case RawPointerEventType.RightButtonDown: |
|
|
|
case RawPointerEventType.MiddleButtonDown: |
|
|
|
if (ButtonCount(props) > 1) |
|
|
|
e.Handled = MouseMove(mouse, e.Timestamp, e.Root, e.Position, props, e.InputModifiers); |
|
|
|
e.Handled = MouseMove(mouse, e.Timestamp, e.Root, e.Position, props, keyModifiers); |
|
|
|
else |
|
|
|
e.Handled = MouseDown(mouse, e.Timestamp, e.Root, e.Position, |
|
|
|
props, e.InputModifiers); |
|
|
|
props, keyModifiers); |
|
|
|
break; |
|
|
|
case RawPointerEventType.LeftButtonUp: |
|
|
|
case RawPointerEventType.RightButtonUp: |
|
|
|
case RawPointerEventType.MiddleButtonUp: |
|
|
|
if (ButtonCount(props) != 0) |
|
|
|
e.Handled = MouseMove(mouse, e.Timestamp, e.Root, e.Position, props, e.InputModifiers); |
|
|
|
e.Handled = MouseMove(mouse, e.Timestamp, e.Root, e.Position, props, keyModifiers); |
|
|
|
else |
|
|
|
e.Handled = MouseUp(mouse, e.Timestamp, e.Root, e.Position, props, e.InputModifiers); |
|
|
|
e.Handled = MouseUp(mouse, e.Timestamp, e.Root, e.Position, props, keyModifiers); |
|
|
|
break; |
|
|
|
case RawPointerEventType.Move: |
|
|
|
e.Handled = MouseMove(mouse, e.Timestamp, e.Root, e.Position, props, e.InputModifiers); |
|
|
|
e.Handled = MouseMove(mouse, e.Timestamp, e.Root, e.Position, props, keyModifiers); |
|
|
|
break; |
|
|
|
case RawPointerEventType.Wheel: |
|
|
|
e.Handled = MouseWheel(mouse, e.Timestamp, e.Root, e.Position, props, ((RawMouseWheelEventArgs)e).Delta, e.InputModifiers); |
|
|
|
e.Handled = MouseWheel(mouse, e.Timestamp, e.Root, e.Position, props, ((RawMouseWheelEventArgs)e).Delta, keyModifiers); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void LeaveWindow(IMouseDevice device, ulong timestamp, IInputRoot root, InputModifiers inputModifiers) |
|
|
|
private void LeaveWindow(IMouseDevice device, ulong timestamp, IInputRoot root, PointerPointProperties properties, |
|
|
|
KeyModifiers inputModifiers) |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(device != null); |
|
|
|
Contract.Requires<ArgumentNullException>(root != null); |
|
|
|
|
|
|
|
ClearPointerOver(this, timestamp, root, inputModifiers); |
|
|
|
ClearPointerOver(this, timestamp, root, properties, inputModifiers); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
PointerPointProperties CreateProperties(RawPointerEventArgs args) |
|
|
|
{ |
|
|
|
var rv = new PointerPointProperties(args.InputModifiers); |
|
|
|
|
|
|
|
var kind = PointerUpdateKind.Other; |
|
|
|
|
|
|
|
if (args.Type == RawPointerEventType.LeftButtonDown) |
|
|
|
rv.IsLeftButtonPressed = true; |
|
|
|
kind = PointerUpdateKind.LeftButtonPressed; |
|
|
|
if (args.Type == RawPointerEventType.MiddleButtonDown) |
|
|
|
rv.IsMiddleButtonPressed = true; |
|
|
|
kind = PointerUpdateKind.MiddleButtonPressed; |
|
|
|
if (args.Type == RawPointerEventType.RightButtonDown) |
|
|
|
rv.IsRightButtonPressed = true; |
|
|
|
kind = PointerUpdateKind.RightButtonPressed; |
|
|
|
if (args.Type == RawPointerEventType.LeftButtonUp) |
|
|
|
rv.IsLeftButtonPressed = false; |
|
|
|
kind = PointerUpdateKind.LeftButtonReleased; |
|
|
|
if (args.Type == RawPointerEventType.MiddleButtonUp) |
|
|
|
rv.IsMiddleButtonPressed = false; |
|
|
|
kind = PointerUpdateKind.MiddleButtonReleased; |
|
|
|
if (args.Type == RawPointerEventType.RightButtonUp) |
|
|
|
rv.IsRightButtonPressed = false; |
|
|
|
return rv; |
|
|
|
kind = PointerUpdateKind.RightButtonReleased; |
|
|
|
|
|
|
|
return new PointerPointProperties(args.InputModifiers, kind); |
|
|
|
} |
|
|
|
|
|
|
|
private MouseButton _lastMouseDownButton; |
|
|
|
private bool MouseDown(IMouseDevice device, ulong timestamp, IInputElement root, Point p, |
|
|
|
PointerPointProperties properties, |
|
|
|
InputModifiers inputModifiers) |
|
|
|
KeyModifiers inputModifiers) |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(device != null); |
|
|
|
Contract.Requires<ArgumentNullException>(root != null); |
|
|
|
@ -221,7 +227,7 @@ namespace Avalonia.Input |
|
|
|
} |
|
|
|
|
|
|
|
private bool MouseMove(IMouseDevice device, ulong timestamp, IInputRoot root, Point p, PointerPointProperties properties, |
|
|
|
InputModifiers inputModifiers) |
|
|
|
KeyModifiers inputModifiers) |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(device != null); |
|
|
|
Contract.Requires<ArgumentNullException>(root != null); |
|
|
|
@ -230,11 +236,11 @@ namespace Avalonia.Input |
|
|
|
|
|
|
|
if (_pointer.Captured == null) |
|
|
|
{ |
|
|
|
source = SetPointerOver(this, timestamp, root, p, inputModifiers); |
|
|
|
source = SetPointerOver(this, timestamp, root, p, properties, inputModifiers); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
SetPointerOver(this, timestamp, root, _pointer.Captured, inputModifiers); |
|
|
|
SetPointerOver(this, timestamp, root, _pointer.Captured, properties, inputModifiers); |
|
|
|
source = _pointer.Captured; |
|
|
|
} |
|
|
|
|
|
|
|
@ -246,7 +252,7 @@ namespace Avalonia.Input |
|
|
|
} |
|
|
|
|
|
|
|
private bool MouseUp(IMouseDevice device, ulong timestamp, IInputRoot root, Point p, PointerPointProperties props, |
|
|
|
InputModifiers inputModifiers) |
|
|
|
KeyModifiers inputModifiers) |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(device != null); |
|
|
|
Contract.Requires<ArgumentNullException>(root != null); |
|
|
|
@ -256,8 +262,7 @@ namespace Avalonia.Input |
|
|
|
if (hit != null) |
|
|
|
{ |
|
|
|
var source = GetSource(hit); |
|
|
|
var e = new PointerReleasedEventArgs(source, _pointer, root, p, timestamp, props, inputModifiers, |
|
|
|
_lastMouseDownButton); |
|
|
|
var e = new PointerReleasedEventArgs(source, _pointer, root, p, timestamp, props, inputModifiers); |
|
|
|
|
|
|
|
source?.RaiseEvent(e); |
|
|
|
_pointer.Capture(null); |
|
|
|
@ -269,7 +274,7 @@ namespace Avalonia.Input |
|
|
|
|
|
|
|
private bool MouseWheel(IMouseDevice device, ulong timestamp, IInputRoot root, Point p, |
|
|
|
PointerPointProperties props, |
|
|
|
Vector delta, InputModifiers inputModifiers) |
|
|
|
Vector delta, KeyModifiers inputModifiers) |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(device != null); |
|
|
|
Contract.Requires<ArgumentNullException>(root != null); |
|
|
|
@ -304,19 +309,23 @@ namespace Avalonia.Input |
|
|
|
return _pointer.Captured ?? root.InputHitTest(p); |
|
|
|
} |
|
|
|
|
|
|
|
PointerEventArgs CreateSimpleEvent(RoutedEvent ev, ulong timestamp, IInteractive source, InputModifiers inputModifiers) |
|
|
|
PointerEventArgs CreateSimpleEvent(RoutedEvent ev, ulong timestamp, IInteractive source, |
|
|
|
PointerPointProperties properties, |
|
|
|
KeyModifiers inputModifiers) |
|
|
|
{ |
|
|
|
return new PointerEventArgs(ev, source, _pointer, null, default, |
|
|
|
timestamp, new PointerPointProperties(inputModifiers), inputModifiers); |
|
|
|
timestamp, properties, inputModifiers); |
|
|
|
} |
|
|
|
|
|
|
|
private void ClearPointerOver(IPointerDevice device, ulong timestamp, IInputRoot root, InputModifiers inputModifiers) |
|
|
|
private void ClearPointerOver(IPointerDevice device, ulong timestamp, IInputRoot root, |
|
|
|
PointerPointProperties properties, |
|
|
|
KeyModifiers inputModifiers) |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(device != null); |
|
|
|
Contract.Requires<ArgumentNullException>(root != null); |
|
|
|
|
|
|
|
var element = root.PointerOverElement; |
|
|
|
var e = CreateSimpleEvent(InputElement.PointerLeaveEvent, timestamp, element, inputModifiers); |
|
|
|
var e = CreateSimpleEvent(InputElement.PointerLeaveEvent, timestamp, element, properties, inputModifiers); |
|
|
|
|
|
|
|
if (element!=null && !element.IsAttachedToVisualTree) |
|
|
|
{ |
|
|
|
@ -353,7 +362,9 @@ namespace Avalonia.Input |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private IInputElement SetPointerOver(IPointerDevice device, ulong timestamp, IInputRoot root, Point p, InputModifiers inputModifiers) |
|
|
|
private IInputElement SetPointerOver(IPointerDevice device, ulong timestamp, IInputRoot root, Point p, |
|
|
|
PointerPointProperties properties, |
|
|
|
KeyModifiers inputModifiers) |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(device != null); |
|
|
|
Contract.Requires<ArgumentNullException>(root != null); |
|
|
|
@ -364,18 +375,20 @@ namespace Avalonia.Input |
|
|
|
{ |
|
|
|
if (element != null) |
|
|
|
{ |
|
|
|
SetPointerOver(device, timestamp, root, element, inputModifiers); |
|
|
|
SetPointerOver(device, timestamp, root, element, properties, inputModifiers); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
ClearPointerOver(device, timestamp, root, inputModifiers); |
|
|
|
ClearPointerOver(device, timestamp, root, properties, inputModifiers); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return element; |
|
|
|
} |
|
|
|
|
|
|
|
private void SetPointerOver(IPointerDevice device, ulong timestamp, IInputRoot root, IInputElement element, InputModifiers inputModifiers) |
|
|
|
private void SetPointerOver(IPointerDevice device, ulong timestamp, IInputRoot root, IInputElement element, |
|
|
|
PointerPointProperties properties, |
|
|
|
KeyModifiers inputModifiers) |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(device != null); |
|
|
|
Contract.Requires<ArgumentNullException>(root != null); |
|
|
|
@ -397,7 +410,7 @@ namespace Avalonia.Input |
|
|
|
|
|
|
|
el = root.PointerOverElement; |
|
|
|
|
|
|
|
var e = CreateSimpleEvent(InputElement.PointerLeaveEvent, timestamp, el, inputModifiers); |
|
|
|
var e = CreateSimpleEvent(InputElement.PointerLeaveEvent, timestamp, el, properties, inputModifiers); |
|
|
|
if (el!=null && branch!=null && !el.IsAttachedToVisualTree) |
|
|
|
{ |
|
|
|
ClearChildrenPointerOver(e,branch,false); |
|
|
|
|