Browse Source

Implemented icons

pull/875/head
Nikita Tsukanov 9 years ago
parent
commit
dd28488218
  1. 4
      src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj
  2. 2
      src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs
  3. 33
      src/Gtk/Avalonia.Gtk3/Interop/GException.cs
  4. 37
      src/Gtk/Avalonia.Gtk3/Interop/GObject.cs
  5. 30
      src/Gtk/Avalonia.Gtk3/Interop/Native.cs
  6. 68
      src/Gtk/Avalonia.Gtk3/Interop/Pixbuf.cs
  7. 5
      src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs
  8. 20
      src/Gtk/Avalonia.Gtk3/PlatformIconLoader.cs
  9. 10
      src/Gtk/Avalonia.Gtk3/Stubs.cs
  10. 5
      src/Gtk/Avalonia.Gtk3/WindowImpl.cs

4
src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj

@ -48,14 +48,18 @@
<Compile Include="FramebufferManager.cs" /> <Compile Include="FramebufferManager.cs" />
<Compile Include="GdkKey.cs" /> <Compile Include="GdkKey.cs" />
<Compile Include="Gtk3Platform.cs" /> <Compile Include="Gtk3Platform.cs" />
<Compile Include="Interop\GException.cs" />
<Compile Include="Interop\GObject.cs" />
<Compile Include="Interop\ICustomGtk3NativeLibraryResolver.cs" /> <Compile Include="Interop\ICustomGtk3NativeLibraryResolver.cs" />
<Compile Include="Interop\DynLoader.cs" /> <Compile Include="Interop\DynLoader.cs" />
<Compile Include="Interop\GlibTimeout.cs" /> <Compile Include="Interop\GlibTimeout.cs" />
<Compile Include="Interop\Native.cs" /> <Compile Include="Interop\Native.cs" />
<Compile Include="Interop\NativeException.cs" /> <Compile Include="Interop\NativeException.cs" />
<Compile Include="Interop\Pixbuf.cs" />
<Compile Include="Interop\Resolver.cs" /> <Compile Include="Interop\Resolver.cs" />
<Compile Include="Interop\Signal.cs" /> <Compile Include="Interop\Signal.cs" />
<Compile Include="ImageSurfaceFramebuffer.cs" /> <Compile Include="ImageSurfaceFramebuffer.cs" />
<Compile Include="PlatformIconLoader.cs" />
<Compile Include="PopupImpl.cs" /> <Compile Include="PopupImpl.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Stubs.cs" /> <Compile Include="Stubs.cs" />

2
src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs

@ -38,7 +38,7 @@ namespace Avalonia.Gtk3
.Bind<IPlatformThreadingInterface>().ToConstant(Instance) .Bind<IPlatformThreadingInterface>().ToConstant(Instance)
.Bind<ISystemDialogImpl>().ToSingleton<SystemDialogStub>() .Bind<ISystemDialogImpl>().ToSingleton<SystemDialogStub>()
.Bind<IRenderLoop>().ToConstant(new DefaultRenderLoop(60)) .Bind<IRenderLoop>().ToConstant(new DefaultRenderLoop(60))
.Bind<IPlatformIconLoader>().ToConstant(new PlatformIconLoaderStub()); .Bind<IPlatformIconLoader>().ToConstant(new PlatformIconLoader());
} }

33
src/Gtk/Avalonia.Gtk3/Interop/GException.cs

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Avalonia.Gtk3.Interop
{
public class GException : Exception
{
[StructLayout(LayoutKind.Sequential)]
struct GError
{
UInt32 domain;
int code;
public IntPtr message;
};
static unsafe string GetError(IntPtr error)
{
if (error == IntPtr.Zero)
return "Unknown error";
return Utf8Buffer.StringFromPtr(((GError*) error)->message);
}
public GException(IntPtr error) : base(GetError(error))
{
}
}
}

37
src/Gtk/Avalonia.Gtk3/Interop/GObject.cs

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Avalonia.Gtk3.Interop
{
class GObject : SafeHandle
{
public GObject() : base(IntPtr.Zero, true)
{
}
public GObject(IntPtr handle, bool owned = true) : base(IntPtr.Zero, owned)
{
this.handle = handle;
}
protected override bool ReleaseHandle()
{
if (handle != IntPtr.Zero)
Native.GObjectUnref(handle);
handle = IntPtr.Zero;
return true;
}
public override bool IsInvalid => handle == IntPtr.Zero;
}
class GInputStream : GObject
{
}
}

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

@ -38,6 +38,9 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_widget_hide(IntPtr gtkWidget); public delegate void gtk_widget_hide(IntPtr gtkWidget);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_set_icon(IntPtr window, Pixbuf pixbuf);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] //No manual import [UnmanagedFunctionPointer(CallingConvention.Cdecl)] //No manual import
public delegate IntPtr gdk_get_native_handle(IntPtr gdkWindow); public delegate IntPtr gdk_get_native_handle(IntPtr gdkWindow);
@ -160,12 +163,31 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_clipboard_clear(IntPtr clipboard); public delegate void gtk_clipboard_clear(IntPtr clipboard);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.GdkPixBuf)]
public delegate IntPtr gdk_pixbuf_new_from_file(Utf8Buffer filename, out IntPtr error);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.GdkPixBuf)]
public delegate IntPtr gdk_pixbuf_new_from_stream(GInputStream stream, IntPtr cancel, out IntPtr error);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.GdkPixBuf)]
public delegate bool gdk_pixbuf_save_to_bufferv(Pixbuf pixbuf, out IntPtr buffer, out IntPtr buffer_size,
Utf8Buffer type, IntPtr option_keys, IntPtr option_values, out IntPtr error);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)]
public delegate void g_object_unref(IntPtr instance);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)]
public delegate ulong g_signal_connect_object(IntPtr instance, Utf8Buffer signal, IntPtr handler, IntPtr userData, int flags); public delegate ulong g_signal_connect_object(IntPtr instance, Utf8Buffer signal, IntPtr handler, IntPtr userData, int flags);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)]
public delegate ulong g_signal_handler_disconnect(IntPtr instance, ulong connectionId); public delegate ulong g_signal_handler_disconnect(IntPtr instance, ulong connectionId);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)] [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)]
public delegate ulong g_timeout_add(uint interval, timeout_callback callback, IntPtr data); public delegate ulong g_timeout_add(uint interval, timeout_callback callback, IntPtr data);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)]
public delegate ulong g_free(IntPtr data);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gio)]
public delegate GInputStream g_memory_input_stream_new_from_data(IntPtr ptr, IntPtr len, IntPtr destroyCallback);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate bool signal_widget_draw(IntPtr gtkWidget, IntPtr cairoContext, IntPtr userData); public delegate bool signal_widget_draw(IntPtr gtkWidget, IntPtr cairoContext, IntPtr userData);
@ -191,6 +213,7 @@ namespace Avalonia.Gtk3.Interop
public static D.gtk_application_new GtkApplicationNew; public static D.gtk_application_new GtkApplicationNew;
public static D.gtk_main_iteration GtkMainIteration; public static D.gtk_main_iteration GtkMainIteration;
public static D.gtk_window_new GtkWindowNew; public static D.gtk_window_new GtkWindowNew;
public static D.gtk_window_set_icon GtkWindowSetIcon;
public static D.gtk_init GtkInit; public static D.gtk_init GtkInit;
public static D.gtk_window_present GtkWindowPresent; public static D.gtk_window_present GtkWindowPresent;
public static D.gtk_widget_hide GtkWidgetHide; public static D.gtk_widget_hide GtkWidgetHide;
@ -205,9 +228,12 @@ namespace Avalonia.Gtk3.Interop
public static D.gtk_window_set_default_size GtkWindowSetDefaultSize; public static D.gtk_window_set_default_size GtkWindowSetDefaultSize;
public static D.gtk_window_get_position GtkWindowGetPosition; public static D.gtk_window_get_position GtkWindowGetPosition;
public static D.gtk_window_move GtkWindowMove; public static D.gtk_window_move GtkWindowMove;
public static D.g_object_unref GObjectUnref;
public static D.g_signal_connect_object GSignalConnectObject; public static D.g_signal_connect_object GSignalConnectObject;
public static D.g_signal_handler_disconnect GSignalHandlerDisconnect; public static D.g_signal_handler_disconnect GSignalHandlerDisconnect;
public static D.g_timeout_add GTimeoutAdd; public static D.g_timeout_add GTimeoutAdd;
public static D.g_free GFree;
public static D.g_memory_input_stream_new_from_data GMemoryInputStreamNewFromData;
public static D.gtk_widget_set_double_buffered GtkWidgetSetDoubleBuffered; public static D.gtk_widget_set_double_buffered GtkWidgetSetDoubleBuffered;
public static D.gtk_widget_set_events GtkWidgetSetEvents; public static D.gtk_widget_set_events GtkWidgetSetEvents;
public static D.gdk_window_invalidate_rect GdkWindowInvalidateRect; public static D.gdk_window_invalidate_rect GdkWindowInvalidateRect;
@ -232,6 +258,10 @@ namespace Avalonia.Gtk3.Interop
public static D.gdk_window_begin_move_drag GdkWindowBeginMoveDrag; public static D.gdk_window_begin_move_drag GdkWindowBeginMoveDrag;
public static D.gdk_window_begin_resize_drag GdkWindowBeginResizeDrag; public static D.gdk_window_begin_resize_drag GdkWindowBeginResizeDrag;
public static D.gdk_pixbuf_new_from_file GdkPixbufNewFromFile;
public static D.gdk_pixbuf_new_from_stream GdkPixbufNewFromStream;
public static D.gdk_pixbuf_save_to_bufferv GdkPixbufSaveToBufferv;
public static D.cairo_image_surface_create CairoImageSurfaceCreate; public static D.cairo_image_surface_create CairoImageSurfaceCreate;
public static D.cairo_image_surface_get_data CairoImageSurfaceGetData; public static D.cairo_image_surface_get_data CairoImageSurfaceGetData;
public static D.cairo_image_surface_get_stride CairoImageSurfaceGetStride; public static D.cairo_image_surface_get_stride CairoImageSurfaceGetStride;

68
src/Gtk/Avalonia.Gtk3/Interop/Pixbuf.cs

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Avalonia.Platform;
namespace Avalonia.Gtk3.Interop
{
internal class Pixbuf : GObject, IWindowIconImpl
{
Pixbuf(IntPtr handle) : base(handle)
{
}
public static Pixbuf NewFromFile(string filename)
{
using (var ub = new Utf8Buffer(filename))
{
IntPtr err;
var rv = Native.GdkPixbufNewFromFile(ub, out err);
if(rv != IntPtr.Zero)
return new Pixbuf(rv);
throw new GException(err);
}
}
public static unsafe Pixbuf NewFromBytes(byte[] data)
{
fixed (void* bytes = data)
{
using (var stream = Native.GMemoryInputStreamNewFromData(new IntPtr(bytes), new IntPtr(data.Length), IntPtr.Zero))
{
IntPtr err;
var rv = Native.GdkPixbufNewFromStream(stream, IntPtr.Zero, out err);
if (rv != IntPtr.Zero)
return new Pixbuf(rv);
throw new GException(err);
}
}
}
public static Pixbuf NewFromStream(Stream s)
{
if (s is MemoryStream)
return NewFromBytes(((MemoryStream) s).ToArray());
var ms = new MemoryStream();
s.CopyTo(ms);
return NewFromBytes(ms.ToArray());
}
public void Save(Stream outputStream)
{
IntPtr buffer, bufferLen, error;
using (var png = new Utf8Buffer("png"))
if (!Native.GdkPixbufSaveToBufferv(this, out buffer, out bufferLen, png,
IntPtr.Zero, IntPtr.Zero, out error))
throw new GException(error);
var data = new byte[bufferLen.ToInt32()];
Marshal.Copy(buffer, data, 0, bufferLen.ToInt32());
Native.GFree(buffer);
outputStream.Write(data, 0, data.Length);
}
}
}

5
src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs

@ -31,7 +31,8 @@ namespace Avalonia.Gtk3.Interop
Glib, Glib,
Gio, Gio,
Gobject, Gobject,
Cairo Cairo,
GdkPixBuf
} }
static class Resolver static class Resolver
@ -76,6 +77,8 @@ namespace Avalonia.Gtk3.Interop
return FormatName("gtk-3"); return FormatName("gtk-3");
case GtkDll.Gobject: case GtkDll.Gobject:
return FormatName("gobject-2.0"); return FormatName("gobject-2.0");
case GtkDll.GdkPixBuf:
return FormatName("gdk_pixbuf-2.0");
default: default:
throw new ArgumentException("Unknown lib: " + dll); throw new ArgumentException("Unknown lib: " + dll);
} }

20
src/Gtk/Avalonia.Gtk3/PlatformIconLoader.cs

@ -0,0 +1,20 @@
using System.IO;
using Avalonia.Gtk3.Interop;
using Avalonia.Platform;
namespace Avalonia.Gtk3
{
class PlatformIconLoader : IPlatformIconLoader
{
public IWindowIconImpl LoadIcon(string fileName) => Pixbuf.NewFromFile(fileName);
public IWindowIconImpl LoadIcon(Stream stream) => Pixbuf.NewFromStream(stream);
public IWindowIconImpl LoadIcon(IBitmapImpl bitmap)
{
var ms = new MemoryStream();
bitmap.Save(ms);
return Pixbuf.NewFromBytes(ms.ToArray());
}
}
}

10
src/Gtk/Avalonia.Gtk3/Stubs.cs

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -26,13 +25,4 @@ namespace Avalonia.Gtk3
public Task<string> ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent) public Task<string> ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent)
=> Task.FromResult((string) null); => Task.FromResult((string) null);
} }
class PlatformIconLoaderStub : IPlatformIconLoader
{
public IWindowIconImpl LoadIcon(string fileName) => null;
public IWindowIconImpl LoadIcon(Stream stream) => null;
public IWindowIconImpl LoadIcon(IBitmapImpl bitmap) => null;
}
} }

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

@ -22,10 +22,7 @@ namespace Avalonia.Gtk3
public void SetSystemDecorations(bool enabled) => Native.GtkWindowSetDecorated(GtkWidget, enabled); public void SetSystemDecorations(bool enabled) => Native.GtkWindowSetDecorated(GtkWidget, enabled);
public void SetIcon(IWindowIconImpl icon) public void SetIcon(IWindowIconImpl icon) => Native.GtkWindowSetIcon(GtkWidget, (Pixbuf) icon);
{
//STUB
}
public WindowImpl() : base(Native.GtkWindowNew(GtkWindowType.TopLevel)) public WindowImpl() : base(Native.GtkWindowNew(GtkWindowType.TopLevel))
{ {

Loading…
Cancel
Save