From f55a49729831db65472e26f31fbea0944ba0ae49 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Thu, 26 Jan 2017 04:01:38 +0300 Subject: [PATCH] Implemented motion and scroll events --- src/Gtk/Avalonia.Gtk3/Interop/Native.cs | 48 +++++++++++++++++++++++-- src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs | 39 ++++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs index 3ee8871b40..d9cf9fff05 100644 --- a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs +++ b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs @@ -5,8 +5,10 @@ using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using gint8 = System.Byte; +using gint16 = System.Int16; using gint32 = System.Int32; using gint = System.Int32; +using guint16 = System.UInt16; using guint32 = System.UInt32; using guint = System.UInt32; using gdouble = System.Double; @@ -195,7 +197,7 @@ namespace Avalonia.Gtk3.Interop GrabBroken = 35, } - public enum GdkModifierType + enum GdkModifierType { ShiftMask = 1, LockMask = 2, @@ -218,6 +220,15 @@ namespace Avalonia.Gtk3.Interop None = 0, } + enum GdkScrollDirection + { + Up, + Down, + Left, + Right, + Smooth + } + [StructLayout(LayoutKind.Sequential)] unsafe struct GdkEventButton { @@ -232,5 +243,38 @@ namespace Avalonia.Gtk3.Interop public guint button; public IntPtr device; public gdouble x_root, y_root; - }; + } + + [StructLayout(LayoutKind.Sequential)] + unsafe struct GdkEventMotion + { + public GdkEventType type; + public IntPtr window; + public gint8 send_event; + public guint32 time; + public gdouble x; + public gdouble y; + public gdouble* axes; + public GdkModifierType state; + public gint16 is_hint; + public IntPtr device; + public gdouble x_root, y_root; + } + + [StructLayout(LayoutKind.Sequential)] + unsafe struct GdkEventScroll + { + public GdkEventType type; + public IntPtr window; + public gint8 send_event; + public guint32 time; + public gdouble x; + public gdouble y; + public GdkModifierType state; + public GdkScrollDirection direction; + public IntPtr device; + public gdouble x_root, y_root; + public gdouble delta_x; + public gdouble delta_y; + } } diff --git a/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs b/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs index c16415828f..fc0893bdb8 100644 --- a/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs +++ b/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs @@ -24,6 +24,8 @@ namespace Avalonia.Gtk3 Connect("configure-event", OnConfigured); Connect("button-press-event", OnButton); Connect("button-release-event", OnButton); + Connect("motion-notify-event", OnMotion); + Connect("scroll-event", OnScroll); } private Size _lastSize; @@ -85,6 +87,43 @@ namespace Avalonia.Gtk3 return false; } + private unsafe bool OnMotion(IntPtr w, IntPtr ev, IntPtr userdata) + { + var evnt = (GdkEventMotion*)ev; + var position = new Point(evnt->x, evnt->y); + + + var e = new RawMouseEventArgs( + Gtk3Platform.Mouse, + evnt->time, + _inputRoot, + RawMouseEventType.Move, + position, GetModifierKeys(evnt->state)); + Input(e); + return false; + } + private unsafe bool OnScroll(IntPtr w, IntPtr ev, IntPtr userdata) + { + var evnt = (GdkEventScroll*)ev; + var delta = new Vector(); + var step = (double) 1; + if (evnt->direction == GdkScrollDirection.Down) + delta = new Vector(0, -step); + else if (evnt->direction == GdkScrollDirection.Up) + delta = new Vector(0, step); + else if (evnt->direction == GdkScrollDirection.Right) + delta = new Vector(-step, 0); + else if (evnt->direction == GdkScrollDirection.Left) + delta = new Vector(step, 0); + else if (evnt->direction == GdkScrollDirection.Smooth) + delta = new Vector(evnt->delta_x, evnt->delta_y); + + var e = new RawMouseWheelEventArgs(Gtk3Platform.Mouse, evnt->time, _inputRoot, + new Point(evnt->x, evnt->y), delta, GetModifierKeys(evnt->state)); + Input(e); + return false; + } + void Connect(string name, T handler) => _disposables.Add(Signal.Connect(GtkWidget, name, handler)); private bool OnDraw(IntPtr gtkwidget, IntPtr cairocontext, IntPtr userdata)