Merge pull request #151 from lytico/lytico_overridechain
Fix overide chain
This commit is contained in:
commit
7054da77af
7 changed files with 191 additions and 5 deletions
28
Source/Libs/GLibSharp/AbiStructExtensions.cs
Normal file
28
Source/Libs/GLibSharp/AbiStructExtensions.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace GLib
|
||||
{
|
||||
|
||||
public static class AbiStructExtension
|
||||
{
|
||||
public static N BaseOverride<N>(this AbiStruct class_abi, GType gtype, string fieldname) where N : Delegate
|
||||
{
|
||||
N unmanaged = null;
|
||||
unsafe {
|
||||
IntPtr raw_ptr = IntPtr.Zero;
|
||||
while (raw_ptr == IntPtr.Zero && GType.IsManaged(gtype)) {
|
||||
gtype = gtype.GetThresholdType();
|
||||
var abi_ptr = (IntPtr*) (((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset(fieldname));
|
||||
raw_ptr = *abi_ptr;
|
||||
}
|
||||
|
||||
if (raw_ptr != IntPtr.Zero) {
|
||||
unmanaged = Marshal.GetDelegateForFunctionPointer<N>(raw_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
return unmanaged;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
<EmbeddedResource Include="**\*.glade">
|
||||
<LogicalName>%(Filename)%(Extension)</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Testpic.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Sections\**\*.cs" Visible="false">
|
||||
|
|
110
Source/Samples/Sections/Widgets/CustomWidgets/ImageDrawn.cs
Normal file
110
Source/Samples/Sections/Widgets/CustomWidgets/ImageDrawn.cs
Normal file
|
@ -0,0 +1,110 @@
|
|||
// adopted from: https://github.com/mono/xwt/blob/master/Xwt.XamMac/Xwt.Mac/ImageHandler.cs
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Gtk;
|
||||
using Gdk;
|
||||
using System.Runtime.InteropServices;
|
||||
using Cairo;
|
||||
using Rectangle = Gdk.Rectangle;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
// This is a completely pointless widget, but its for testing subclassing Widget.OnDrawn
|
||||
public class GtkDrawingArea : Gtk.DrawingArea { }
|
||||
|
||||
public class ImageBox : GtkDrawingArea
|
||||
{
|
||||
Pixbuf image;
|
||||
float yalign = 0.5f, xalign = 0.5f;
|
||||
|
||||
public ImageBox(Pixbuf img) : this()
|
||||
{
|
||||
Image = img;
|
||||
}
|
||||
|
||||
public ImageBox()
|
||||
{
|
||||
this.HasWindow = false;
|
||||
this.AppPaintable = true;
|
||||
}
|
||||
|
||||
public Pixbuf Image {
|
||||
get { return image; }
|
||||
set {
|
||||
image = value;
|
||||
SetSizeRequest((int) image.Width, (int) image.Height);
|
||||
//QueueDraw();
|
||||
}
|
||||
}
|
||||
|
||||
private Size SizeRequestet { get; set; }
|
||||
|
||||
public float Yalign {
|
||||
get { return yalign; }
|
||||
set {
|
||||
yalign = value;
|
||||
QueueDraw();
|
||||
}
|
||||
}
|
||||
|
||||
public float Xalign {
|
||||
get { return xalign; }
|
||||
set {
|
||||
xalign = value;
|
||||
QueueDraw();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawPixbuf(Cairo.Context ctx, Gdk.Pixbuf img, double x, double y, Size idesc)
|
||||
{
|
||||
ctx.Save();
|
||||
ctx.Translate(x, y);
|
||||
|
||||
ctx.Scale(idesc.Width / (double) img.Width, idesc.Height / (double) img.Height);
|
||||
Gdk.CairoHelper.SetSourcePixbuf(ctx, img, 0, 0);
|
||||
|
||||
#pragma warning disable 618
|
||||
using (var p = ctx.Source) {
|
||||
if (p is SurfacePattern pattern) {
|
||||
if (idesc.Width > img.Width || idesc.Height > img.Height) {
|
||||
// Fixes blur issue when rendering on an image surface
|
||||
pattern.Filter = Cairo.Filter.Fast;
|
||||
} else
|
||||
pattern.Filter = Cairo.Filter.Good;
|
||||
}
|
||||
}
|
||||
#pragma warning restore 618
|
||||
|
||||
|
||||
ctx.Paint();
|
||||
|
||||
ctx.Restore();
|
||||
}
|
||||
|
||||
protected override bool OnDrawn(Cairo.Context cr)
|
||||
{
|
||||
if (image == default)
|
||||
return true;
|
||||
var a = Allocation;
|
||||
var size = Allocation.Size;
|
||||
Pixbuf pixbuff = image;
|
||||
// HACK: Gtk sends sometimes an expose/draw event while the widget reallocates.
|
||||
// In that case we would draw in the wrong area, which may lead to artifacts
|
||||
// if no other widget updates it. Alternative: we could clip the
|
||||
// allocation bounds, but this may have other issues.
|
||||
if (a.Width == 1 && a.Height == 1 && a.X == -1 && a.Y == -1) // the allocation coordinates on reallocation
|
||||
return base.OnDrawn(cr);
|
||||
|
||||
var x = (int) ((a.Width - (float) pixbuff.Width) * xalign);
|
||||
var y = (int) ((a.Height - (float) pixbuff.Height) * yalign);
|
||||
if (x < 0) x = 0;
|
||||
if (y < 0) y = 0;
|
||||
DrawPixbuf(cr, pixbuff, x, y, size);
|
||||
return base.OnDrawn(cr);
|
||||
}
|
||||
}
|
||||
}
|
50
Source/Samples/Sections/Widgets/ImageSection.cs
Normal file
50
Source/Samples/Sections/Widgets/ImageSection.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
// This is free and unencumbered software released into the public domain.
|
||||
// Happy coding!!! - GtkSharp Team
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Atk;
|
||||
using Gdk;
|
||||
using Gtk;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
[Section(ContentType = typeof(ImageBox), Category = Category.Widgets)]
|
||||
class ImageSection : ListSection
|
||||
{
|
||||
public ImageSection()
|
||||
{
|
||||
AddItem(CreateContainer());
|
||||
}
|
||||
|
||||
public (string, Widget) CreateContainer()
|
||||
{
|
||||
Stream GetResourceStream(Assembly assembly, string name)
|
||||
{
|
||||
var resources = assembly.GetManifestResourceNames();
|
||||
var resourceName = resources.SingleOrDefault(str => str == name);
|
||||
|
||||
// try harder:
|
||||
if (resourceName == default) {
|
||||
resourceName = resources.SingleOrDefault(str => str.EndsWith(name));
|
||||
}
|
||||
|
||||
if (resourceName == default)
|
||||
return default;
|
||||
var stream = assembly.GetManifestResourceStream(resourceName);
|
||||
return stream;
|
||||
}
|
||||
Pixbuf image = default;
|
||||
using (var stream = GetResourceStream(typeof(ImageSection).Assembly, "Testpic.png")) {
|
||||
image = new Pixbuf(stream);
|
||||
}
|
||||
|
||||
var container = new ImageBox(image);
|
||||
|
||||
|
||||
return ($"{nameof(ImageBox)}:", container);
|
||||
}
|
||||
}
|
||||
}
|
BIN
Source/Samples/Testpic.png
Normal file
BIN
Source/Samples/Testpic.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
|
@ -207,11 +207,7 @@ namespace GtkSharp.Generation {
|
|||
|
||||
this.GenerateMethodBody (sw, null);
|
||||
// Find the first unmanaged ancestor
|
||||
sw.WriteLine ("\t\t\t{0}NativeDelegate unmanaged = null;", Name);
|
||||
sw.WriteLine ("\t\t\tunsafe {");
|
||||
sw.WriteLine ("\t\t\t\tIntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset(\"{0}\"));", CName);
|
||||
sw.WriteLine ("\t\t\t\tunmanaged = ({0}NativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof({0}NativeDelegate));", this.Name);
|
||||
sw.WriteLine ("\t\t\t}");
|
||||
sw.WriteLine ($"\t\t\t{Name}NativeDelegate unmanaged = class_abi.BaseOverride<{Name}NativeDelegate>(this.LookupGType(), \"{CName}\");");
|
||||
sw.Write ("\t\t\tif (unmanaged == null) ");
|
||||
if (parms.HasOutParam)
|
||||
sw.WriteLine ("throw new InvalidOperationException (\"No base method to invoke\");");
|
||||
|
|
|
@ -147,6 +147,7 @@ namespace GtkSharp.Generation {
|
|||
sw.WriteLine ("\tusing System.Collections;");
|
||||
sw.WriteLine ("\tusing System.Collections.Generic;");
|
||||
sw.WriteLine ("\tusing System.Runtime.InteropServices;");
|
||||
sw.WriteLine ("\tusing static GLib.AbiStructExtension;");
|
||||
sw.WriteLine ();
|
||||
|
||||
SymbolTable table = SymbolTable.Table;
|
||||
|
|
Loading…
Reference in a new issue