Browse Source

Implemented motion and scroll events

Nikita Tsukanov 8 years ago
parent
commit
f55a497298
2 changed files with 85 additions and 2 deletions
  1. 46 2
      src/Gtk/Avalonia.Gtk3/Interop/Native.cs
  2. 39 0
      src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs

+ 46 - 2
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;
+    }
 }

+ 39 - 0
src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs

@@ -24,6 +24,8 @@ namespace Avalonia.Gtk3
             Connect<Native.D.signal_onevent>("configure-event", OnConfigured);
             Connect<Native.D.signal_onevent>("button-press-event", OnButton);
             Connect<Native.D.signal_onevent>("button-release-event", OnButton);
+            Connect<Native.D.signal_onevent>("motion-notify-event", OnMotion);
+            Connect<Native.D.signal_onevent>("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<T>(string name, T handler) => _disposables.Add(Signal.Connect<T>(GtkWidget, name, handler));
 
         private bool OnDraw(IntPtr gtkwidget, IntPtr cairocontext, IntPtr userdata)