110 lines
No EOL
2.6 KiB
C#
110 lines
No EOL
2.6 KiB
C#
// 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);
|
|
}
|
|
}
|
|
} |