Skip to content

Commit

Permalink
feat(pointers): [Skia] Add support for key modifiers and improve supp…
Browse files Browse the repository at this point in the history
…ort of horizontal scrolling (including shift+wheel)
  • Loading branch information
dr1rrb committed Aug 3, 2020
1 parent d79c9fd commit 5b9bc79
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 135 deletions.
194 changes: 111 additions & 83 deletions src/Uno.UI.Runtime.Skia.Gtk/GTK/GtkUIElementPointersSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Windows.ApplicationModel;
using Windows.Devices.Input;
using Windows.Foundation;
using Windows.System;
using Windows.UI.Composition;
using Windows.UI.Core;
using Windows.UI.Input;
Expand All @@ -35,56 +36,24 @@ public GtkUIElementPointersSupport(object owner)
| EventMask.ButtonPressMask
| EventMask.SmoothScrollMask
));
GtkHost.Window.MotionNotifyEvent += OnMotionEvent;
GtkHost.Window.ButtonPressEvent += Window_ButtonPressEvent;
GtkHost.Window.ButtonReleaseEvent += Window_ButtonReleaseEvent;
GtkHost.Window.EnterNotifyEvent += Window_EnterEvent;
GtkHost.Window.LeaveNotifyEvent += Window_LeaveEvent;
GtkHost.Window.ScrollEvent += Window_ScrollEvent;
GtkHost.Window.MotionNotifyEvent += OnWindowMotionEvent;
GtkHost.Window.ButtonPressEvent += OnWindowButtonPressEvent;
GtkHost.Window.ButtonReleaseEvent += OnWindowButtonReleaseEvent;
GtkHost.Window.EnterNotifyEvent += OnWindowEnterEvent;
GtkHost.Window.LeaveNotifyEvent += OnWindowLeaveEvent;
GtkHost.Window.ScrollEvent += OnWindowScrollEvent;
}

private static uint GetNextFrameId() => (uint)Interlocked.Increment(ref _currentFrameId);

private void Window_ScrollEvent(object o, ScrollEventArgs args)
private void OnWindowEnterEvent(object o, EnterNotifyEventArgs args)
{
try
{
if (args.Event.Direction == ScrollDirection.Smooth)
{
_ownerEvents.RaisePointerWheelChanged(
new PointerEventArgs(
new Windows.UI.Input.PointerPoint(
frameId: GetNextFrameId(),
timestamp: args.Event.Time,
device: PointerDevice.For(PointerDeviceType.Mouse),
pointerId: 0,
rawPosition: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
position: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
isInContact: false,
properties: BuildProperties(args.Event)
)
)
);
}
}
catch (Exception e)
{
this.Log().Error("Failed to raise PointerExited", e);
}
}
var properties = BuildProperties(args.Event);
var modifiers = GetKeyModifiers();

private PointerPointProperties BuildProperties(EventScroll scrollEvent)
=> new PointerPointProperties
{
MouseWheelDelta = scrollEvent.DeltaX != 0 ? (int)scrollEvent.DeltaX : (int)scrollEvent.DeltaY,
IsHorizontalMouseWheel = scrollEvent.DeltaX != 0,
};

private void Window_LeaveEvent(object o, LeaveNotifyEventArgs args)
{
try
{
_ownerEvents.RaisePointerExited(
_ownerEvents.RaisePointerEntered(
new PointerEventArgs(
new Windows.UI.Input.PointerPoint(
frameId: GetNextFrameId(),
Expand All @@ -93,23 +62,27 @@ private void Window_LeaveEvent(object o, LeaveNotifyEventArgs args)
pointerId: 0,
rawPosition: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
position: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
isInContact: false,
properties: BuildProperties(args.Event)
)
isInContact: properties.HasPressedButton,
properties: properties
),
modifiers
)
);
}
catch(Exception e)
catch (Exception e)
{
this.Log().Error("Failed to raise PointerExited", e);
this.Log().Error("Failed to raise PointerEntered", e);
}
}

private void Window_EnterEvent(object o, EnterNotifyEventArgs args)
private void OnWindowLeaveEvent(object o, LeaveNotifyEventArgs args)
{
try
{
_ownerEvents.RaisePointerEntered(
var properties = BuildProperties(args.Event);
var modifiers = GetKeyModifiers();

_ownerEvents.RaisePointerExited(
new PointerEventArgs(
new Windows.UI.Input.PointerPoint(
frameId: GetNextFrameId(),
Expand All @@ -118,23 +91,27 @@ private void Window_EnterEvent(object o, EnterNotifyEventArgs args)
pointerId: 0,
rawPosition: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
position: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
isInContact: false,
properties: BuildProperties(args.Event)
)
isInContact: properties.HasPressedButton,
properties: properties
),
modifiers
)
);
}
catch (Exception e)
{
this.Log().Error("Failed to raise PointerEntered", e);
this.Log().Error("Failed to raise PointerExited", e);
}
}

private void Window_ButtonReleaseEvent(object o, ButtonReleaseEventArgs args)
private void OnWindowButtonPressEvent(object o, ButtonPressEventArgs args)
{
try
{
_ownerEvents.RaisePointerReleased(
var properties = BuildProperties(args.Event);
var modifiers = GetKeyModifiers();

_ownerEvents.RaisePointerPressed(
new PointerEventArgs(
new Windows.UI.Input.PointerPoint(
frameId: GetNextFrameId(),
Expand All @@ -143,23 +120,27 @@ private void Window_ButtonReleaseEvent(object o, ButtonReleaseEventArgs args)
pointerId: 0,
rawPosition: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
position: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
isInContact: false,
properties: BuildProperties(args.Event)
)
isInContact: true,
properties: properties
),
modifiers
)
);
}
catch (Exception e)
{
this.Log().Error("Failed to raise PointerReleased", e);
this.Log().Error("Failed to raise PointerPressed", e);
}
}

private void Window_ButtonPressEvent(object o, ButtonPressEventArgs args)
private void OnWindowButtonReleaseEvent(object o, ButtonReleaseEventArgs args)
{
try
{
_ownerEvents.RaisePointerPressed(
var properties = BuildProperties(args.Event);
var modifiers = GetKeyModifiers();

_ownerEvents.RaisePointerReleased(
new PointerEventArgs(
new Windows.UI.Input.PointerPoint(
frameId: GetNextFrameId(),
Expand All @@ -168,39 +149,29 @@ private void Window_ButtonPressEvent(object o, ButtonPressEventArgs args)
pointerId: 0,
rawPosition: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
position: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
isInContact: false,
properties: BuildProperties(args.Event)
)
isInContact: properties.HasPressedButton,
properties: properties
),
modifiers
)
);
}
catch (Exception e)
{
this.Log().Error("Failed to raise PointerPressed", e);
this.Log().Error("Failed to raise PointerReleased", e);
}
}

private PointerPointProperties BuildProperties(EventButton eventButton)
=> new PointerPointProperties
{
IsLeftButtonPressed = eventButton.Button == 1,
IsRightButtonPressed = eventButton.Button == 3,
};

private PointerPointProperties BuildProperties(EventCrossing eventCrossing)
=> new PointerPointProperties
{
IsLeftButtonPressed = (eventCrossing.State & ModifierType.Button1Mask) != 0,
IsRightButtonPressed = (eventCrossing.State & ModifierType.Button4Mask) != 0,
};

private void OnMotionEvent(object o, MotionNotifyEventArgs args)
private void OnWindowMotionEvent(object o, MotionNotifyEventArgs args) // a.k.a. move
{
try
{
switch (args.Event.Type)
{
case Gdk.EventType.MotionNotify:
var properties = BuildProperties(args.Event);
var modifiers = GetKeyModifiers();

_ownerEvents.RaisePointerMoved(
new PointerEventArgs(
new Windows.UI.Input.PointerPoint(
Expand All @@ -210,9 +181,10 @@ private void OnMotionEvent(object o, MotionNotifyEventArgs args)
pointerId: 0,
rawPosition: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
position: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
isInContact: false,
properties: BuildProperties(args.Event)
)
isInContact: properties.HasPressedButton,
properties: properties
),
modifiers
)
);
break;
Expand All @@ -228,11 +200,67 @@ private void OnMotionEvent(object o, MotionNotifyEventArgs args)
}
}

private void OnWindowScrollEvent(object o, ScrollEventArgs args)
{
try
{
if (args.Event.Direction == ScrollDirection.Smooth)
{
var properties = BuildProperties(args.Event);
var modifiers = GetKeyModifiers();

_ownerEvents.RaisePointerWheelChanged(
new PointerEventArgs(
new Windows.UI.Input.PointerPoint(
frameId: GetNextFrameId(),
timestamp: args.Event.Time,
device: PointerDevice.For(PointerDeviceType.Mouse),
pointerId: 0,
rawPosition: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
position: new Windows.Foundation.Point(args.Event.X, args.Event.Y),
isInContact: properties.HasPressedButton,
properties: properties
),
modifiers
)
);
}
}
catch (Exception e)
{
this.Log().Error("Failed to raise PointerExited", e);
}
}

private PointerPointProperties BuildProperties(EventMotion eventMotion)
=> new Windows.UI.Input.PointerPointProperties()
{
IsLeftButtonPressed = (eventMotion.State & Gdk.ModifierType.Button1Mask) != 0,
IsRightButtonPressed = (eventMotion.State & Gdk.ModifierType.Button2Mask) != 0
};

private PointerPointProperties BuildProperties(EventButton eventButton)
=> new PointerPointProperties
{
IsLeftButtonPressed = eventButton.Button == 1,
IsRightButtonPressed = eventButton.Button == 3,
};

private PointerPointProperties BuildProperties(EventCrossing eventCrossing)
=> new PointerPointProperties
{
IsLeftButtonPressed = (eventCrossing.State & ModifierType.Button1Mask) != 0,
IsRightButtonPressed = (eventCrossing.State & ModifierType.Button4Mask) != 0,
};

private PointerPointProperties BuildProperties(EventScroll scrollEvent)
=> new PointerPointProperties
{
MouseWheelDelta = scrollEvent.DeltaX != 0 ? (int)scrollEvent.DeltaX : (int)scrollEvent.DeltaY,
IsHorizontalMouseWheel = scrollEvent.DeltaX != 0,
};

private VirtualKeyModifiers GetKeyModifiers()
=> VirtualKeyModifiers.None;
}
}
Loading

0 comments on commit 5b9bc79

Please sign in to comment.