Browse Source

Implemented click support

pull/875/head
Nikita Tsukanov 9 years ago
parent
commit
04359041d7
  1. 6
      src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj
  2. 96
      src/Gtk/Avalonia.Gtk3/Interop/Native.cs
  3. 97
      src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs
  4. 11
      src/Gtk/Avalonia.Gtk3/WindowImpl.cs

6
src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj

@ -25,6 +25,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -33,6 +34,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
@ -65,6 +67,10 @@
<Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
<Name>Avalonia.Input</Name>
</ProjectReference>
<ProjectReference Include="..\..\Avalonia.Interactivity\Avalonia.Interactivity.csproj">
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project>
<Name>Avalonia.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\..\Avalonia.Visuals\Avalonia.Visuals.csproj">
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Avalonia.SceneGraph</Name>

96
src/Gtk/Avalonia.Gtk3/Interop/Native.cs

@ -4,6 +4,12 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using gint8 = System.Byte;
using gint32 = System.Int32;
using gint = System.Int32;
using guint32 = System.UInt32;
using guint = System.UInt32;
using gdouble = System.Double;
namespace Avalonia.Gtk3.Interop
{
@ -48,6 +54,9 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate int gdk_screen_get_width(IntPtr screen);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate int gdk_window_get_origin(IntPtr gdkWindow, out int x, out int y);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
@ -64,6 +73,10 @@ namespace Avalonia.Gtk3.Interop
public delegate void gtk_window_get_size(IntPtr gtkWindow, out int width, out int height);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_resize(IntPtr gtkWindow, int width, int height);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_get_position(IntPtr gtkWindow, out int x, out int y);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_move(IntPtr gtkWindow, int x, int y);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_widget_queue_draw_area(IntPtr gtkWindow, int x, int y, int width, int height);
@ -102,6 +115,8 @@ namespace Avalonia.Gtk3.Interop
public static D.gtk_widget_realize GtkWidgetRealize;
public static D.gtk_window_get_size GtkWindowGetSize;
public static D.gtk_window_resize GtkWindowResize;
public static D.gtk_window_get_position GtkWindowGetPosition;
public static D.gtk_window_move GtkWindowMove;
public static D.g_signal_connect_object GSignalConnectObject;
public static D.g_signal_handler_disconnect GSignalHandlerDisconnect;
public static D.g_timeout_add GTimeoutAdd;
@ -111,6 +126,7 @@ namespace Avalonia.Gtk3.Interop
public static D.gtk_widget_queue_draw_area GtkWidgetQueueDrawArea;
public static D.gdk_screen_get_height GdkScreenGetHeight;
public static D.gdk_screen_get_width GdkScreenGetWidth;
public static D.gdk_window_get_origin GdkWindowGetOrigin;
}
@ -137,4 +153,84 @@ namespace Avalonia.Gtk3.Interop
};
}
}
enum GdkEventType
{
Nothing = -1,
Delete = 0,
Destroy = 1,
Expose = 2,
MotionNotify = 3,
ButtonPress = 4,
TwoButtonPress = 5,
ThreeButtonPress = 6,
ButtonRelease = 7,
KeyPress = 8,
KeyRelease = 9,
EnterNotify = 10,
LeaveNotify = 11,
FocusChange = 12,
Configure = 13,
Map = 14,
Unmap = 15,
PropertyNotify = 16,
SelectionClear = 17,
SelectionRequest = 18,
SelectionNotify = 19,
ProximityIn = 20,
ProximityOut = 21,
DragEnter = 22,
DragLeave = 23,
DragMotion = 24,
DragStatus = 25,
DropStart = 26,
DropFinished = 27,
ClientEvent = 28,
VisibilityNotify = 29,
NoExpose = 30,
Scroll = 31,
WindowState = 32,
Setting = 33,
OwnerChange = 34,
GrabBroken = 35,
}
public enum GdkModifierType
{
ShiftMask = 1,
LockMask = 2,
ControlMask = 4,
Mod1Mask = 8,
Mod2Mask = 16,
Mod3Mask = 32,
Mod4Mask = 64,
Mod5Mask = 128,
Button1Mask = 256,
Button2Mask = 512,
Button3Mask = 1024,
Button4Mask = 2048,
Button5Mask = 4096,
SuperMask = 67108864,
HyperMask = 134217728,
MetaMask = 268435456,
ReleaseMask = 1073741824,
ModifierMask = ReleaseMask | Button5Mask | Button4Mask | Button3Mask | Button2Mask | Button1Mask | Mod5Mask | Mod4Mask | Mod3Mask | Mod2Mask | Mod1Mask | ControlMask | LockMask | ShiftMask,
None = 0,
}
[StructLayout(LayoutKind.Sequential)]
unsafe struct GdkEventButton
{
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 guint button;
public IntPtr device;
public gdouble x_root, y_root;
};
}

97
src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs

@ -22,21 +22,73 @@ namespace Avalonia.Gtk3
Native.GtkWidgetRealize(gtkWidget);
Connect<Native.D.signal_widget_draw>("draw", OnDraw);
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);
}
private Size _lastSize;
private Point _lastPosition;
private bool OnConfigured(IntPtr gtkwidget, IntPtr ev, IntPtr userdata)
{
Debug.WriteLine("Configured");
Resized?.Invoke(ClientSize);
var size = ClientSize;
if (_lastSize != size)
{
_lastSize = size;
Resized?.Invoke(size);
}
var pos = Position;
if (_lastPosition != pos)
{
_lastPosition = pos;
PositionChanged?.Invoke(pos);
}
return false;
}
private static InputModifiers GetModifierKeys(GdkModifierType state)
{
var rv = InputModifiers.None;
if (state.HasFlag(GdkModifierType.ControlMask))
rv |= InputModifiers.Control;
if (state.HasFlag(GdkModifierType.ShiftMask))
rv |= InputModifiers.Shift;
if (state.HasFlag(GdkModifierType.Mod1Mask))
rv |= InputModifiers.Control;
if (state.HasFlag(GdkModifierType.Button1Mask))
rv |= InputModifiers.LeftMouseButton;
if (state.HasFlag(GdkModifierType.Button2Mask))
rv |= InputModifiers.RightMouseButton;
if (state.HasFlag(GdkModifierType.Button3Mask))
rv |= InputModifiers.MiddleMouseButton;
return rv;
}
private unsafe bool OnButton(IntPtr w, IntPtr ev, IntPtr userdata)
{
var evnt = (GdkEventButton*)ev;
var e = new RawMouseEventArgs(
Gtk3Platform.Mouse,
evnt->time,
_inputRoot,
evnt->type == GdkEventType.ButtonRelease
? evnt->button == 1
? RawMouseEventType.LeftButtonUp
: evnt->button == 3 ? RawMouseEventType.RightButtonUp : RawMouseEventType.MiddleButtonUp
: evnt->button == 1
? RawMouseEventType.LeftButtonDown
: evnt->button == 3 ? RawMouseEventType.RightButtonDown : RawMouseEventType.MiddleButtonDown,
new Point(evnt->x, evnt->y), GetModifierKeys(evnt->state));
Input?.Invoke(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)
{
Debug.WriteLine("Draw");
Paint?.Invoke(new Rect(ClientSize));
return true;
}
@ -49,8 +101,6 @@ namespace Avalonia.Gtk3
//TODO
}
public abstract Size ClientSize { get; set; }
public Size MaxClientSize
{
get
@ -71,9 +121,10 @@ namespace Avalonia.Gtk3
public Action Deactivated { get; set; } //TODO
public Action<RawInputEventArgs> Input { get; set; } //TODO
public Action<Rect> Paint { get; set; }
public Action<Size> Resized { get; set; } //TODO
public Action<Size> Resized { get; set; }
public Action<double> ScalingChanged { get; set; } //TODO
public Action<Point> PositionChanged { get; set; } //TODO
public Action<Point> PositionChanged { get; set; }
public void Activate()
{
throw new NotImplementedException();
@ -88,12 +139,17 @@ namespace Avalonia.Gtk3
public Point PointToClient(Point point)
{
throw new NotImplementedException();
int x, y;
Native.GdkWindowGetOrigin(Native.GtkWidgetGetWindow(GtkWidget), out x, out y);
return new Point(point.X - x, point.Y - y);
}
public Point PointToScreen(Point point)
{
throw new NotImplementedException();
int x, y;
Native.GdkWindowGetOrigin(Native.GtkWidgetGetWindow(GtkWidget), out x, out y);
return new Point(point.X + x, point.Y + y);
}
public void SetCursor(IPlatformHandle cursor)
@ -115,7 +171,28 @@ namespace Avalonia.Gtk3
//STUB
}
public Point Position { get; set; }
public Size ClientSize
{
get
{
int w, h;
Native.GtkWindowGetSize(GtkWidget, out w, out h);
return new Size(w, h);
}
set { Native.GtkWindowResize(GtkWidget, (int)value.Width, (int)value.Height); }
}
public Point Position
{
get
{
int x, y;
Native.GtkWindowGetPosition(GtkWidget, out x, out y);
return new Point(x, y);
}
set { Native.GtkWindowMove(GtkWidget, (int)value.X, (int)value.Y); }
}
IntPtr IPlatformHandle.Handle => Native.GetNativeGdkWindowHandle(Native.GtkWidgetGetWindow(GtkWidget));
public IEnumerable<object> Surfaces => new object[] {Handle};

11
src/Gtk/Avalonia.Gtk3/WindowImpl.cs

@ -31,17 +31,6 @@ namespace Avalonia.Gtk3
{
}
public override Size ClientSize
{
get
{
int w, h;
Native.GtkWindowGetSize(GtkWidget, out w, out h);
return new Size(w, h);
}
set { Native.GtkWindowResize(GtkWidget, (int) value.Width, (int) value.Height); }
}
public void SetCoverTaskbarWhenMaximized(bool enable)
{
//Why do we even have that?

Loading…
Cancel
Save