diff --git a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj b/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj index dd35532830..e0e773aaa6 100644 --- a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj +++ b/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj @@ -55,6 +55,7 @@ + diff --git a/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs b/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs index 2aee41e617..81aac5e2dc 100644 --- a/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs +++ b/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs @@ -49,10 +49,7 @@ namespace Avalonia.Gtk3 throw new NotImplementedException(); } - public IPopupImpl CreatePopup() - { - throw new NotImplementedException(); - } + public IPopupImpl CreatePopup() => new PopupImpl(); diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs index 0508dcadc1..736ec7e191 100644 --- a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs +++ b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs @@ -59,7 +59,8 @@ namespace Avalonia.Gtk3.Interop [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.Gdk)] + public delegate void gdk_window_resize(IntPtr gtkWindow, int width, int height); [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] @@ -77,6 +78,10 @@ namespace Avalonia.Gtk3.Interop [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_widget_set_size_request(IntPtr gtkWindow, int width, int height); + [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] + public delegate void gtk_window_set_default_size(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); @@ -128,6 +133,8 @@ namespace Avalonia.Gtk3.Interop [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] public delegate IntPtr gdk_window_get_pointer(IntPtr raw, out int x, out int y, out int mask); + [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] + public delegate void gtk_window_set_geometry_hints(IntPtr window, IntPtr geometry_widget, ref GdkGeometry geometry, GdkWindowHints geom_mask); [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] public delegate void gdk_window_invalidate_rect(IntPtr window, ref GdkRectangle rect, bool invalidate_children); @@ -175,6 +182,9 @@ 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.gdk_window_resize GdkWindowResize; + public static D.gtk_widget_set_size_request GtkWindowSetSizeRequest; + public static D.gtk_window_set_default_size GtkWindowSetDefaultSize; public static D.gtk_window_get_position GtkWindowGetPosition; public static D.gtk_window_move GtkWindowMove; public static D.g_signal_connect_object GSignalConnectObject; @@ -364,6 +374,7 @@ namespace Avalonia.Gtk3.Interop public GdkWindowState new_window_state; } + [StructLayout(LayoutKind.Sequential)] unsafe struct GdkEventKey { public GdkEventType type; @@ -392,4 +403,33 @@ namespace Avalonia.Gtk3.Interop Focused = 128, Ttiled = 256 } + + [StructLayout(LayoutKind.Sequential)] + struct GdkGeometry + { + gint min_width; + gint min_height; + gint max_width; + gint max_height; + gint base_width; + gint base_height; + gint width_inc; + gint height_inc; + gdouble min_aspect; + gdouble max_aspect; + gint win_gravity; + } + + enum GdkWindowHints + { + GDK_HINT_POS = 1 << 0, + GDK_HINT_MIN_SIZE = 1 << 1, + GDK_HINT_MAX_SIZE = 1 << 2, + GDK_HINT_BASE_SIZE = 1 << 3, + GDK_HINT_ASPECT = 1 << 4, + GDK_HINT_RESIZE_INC = 1 << 5, + GDK_HINT_WIN_GRAVITY = 1 << 6, + GDK_HINT_USER_POS = 1 << 7, + GDK_HINT_USER_SIZE = 1 << 8 + } } diff --git a/src/Gtk/Avalonia.Gtk3/PopupImpl.cs b/src/Gtk/Avalonia.Gtk3/PopupImpl.cs new file mode 100644 index 0000000000..4cc01c625f --- /dev/null +++ b/src/Gtk/Avalonia.Gtk3/PopupImpl.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Avalonia.Gtk3.Interop; +using Avalonia.Platform; + +namespace Avalonia.Gtk3 +{ + class PopupImpl : TopLevelImpl, IPopupImpl + { + static IntPtr CreateWindow() + { + var window = Native.GtkWindowNew(GtkWindowType.Popup); + Native.GtkWindowSetSizeRequest(window, 1, 1); + Native.GtkWindowSetDefaultSize(window, 200, 200); + + return window; + } + + public PopupImpl() : base(CreateWindow()) + { + + + } + + public override Size ClientSize + { + get + { + return base.ClientSize; + } + set + { + Native.GtkWindowSetDefaultSize(GtkWidget, (int)value.Width, (int)value.Height); + base.ClientSize = value; + var size = ClientSize; + } + } + } +} diff --git a/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs b/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs index aa0044328e..989a0584fa 100644 --- a/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs +++ b/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs @@ -281,7 +281,7 @@ namespace Avalonia.Gtk3 } - public Size ClientSize + public virtual Size ClientSize { get { @@ -289,7 +289,13 @@ namespace Avalonia.Gtk3 Native.GtkWindowGetSize(GtkWidget, out w, out h); return new Size(w, h); } - set { Native.GtkWindowResize(GtkWidget, (int)value.Width, (int)value.Height); } + set + { + Native.GtkWindowResize(GtkWidget, (int)value.Width, (int)value.Height); + if (Native.GtkWidgetGetWindow(GtkWidget) == IntPtr.Zero) + Native.GtkWidgetRealize(GtkWidget); + Native.GdkWindowResize(Native.GtkWidgetGetWindow(GtkWidget), (int)value.Width, (int)value.Height); + } } public Point Position