The trick here is to add a layout and set the resize callback not to the window but to the layout. It's not perfect, it's a bit dirty but works. Initial positioning not working good but there's rooms to improvement.
Must check Gtk.Widget and Gtk.Containers for requested, allocated and natural sizes or even use Gdk methods. Getting late, hope this will lead you in the right direction.
PS: I'm using a endless.png image but feel free to use another one, just change the code to reflect it.
using Gtk;
public int main (string[] args) {
Gtk.Image image;
Gtk.Layout layout;
Gtk.Window window;
Gdk.Pixbuf pixbuf;
Gtk.init (ref args);
window = new Gtk.Window ();
layout = new Gtk.Layout ();
image = new Gtk.Image ();
try {
pixbuf = new Gdk.Pixbuf.from_file ("endless.png");
image = new Gtk.Image.from_pixbuf (pixbuf);
layout.put (image, 0,0);
window.add (layout);
layout.size_allocate.connect ((allocation) => {
print ("Width: %d Height: %d\n", allocation.width, allocation.height);
var pxb = pixbuf.scale_simple (allocation.width, allocation.height, Gdk.InterpType.BILINEAR);
image.set_from_pixbuf (pxb);
});
window.destroy.connect (Gtk.main_quit);
window.show_all ();
Gtk.main ();
return 0;
} catch (Error e) {
stderr.printf ("Could not load file...exit (%s)\n", e.message);
return 1;
}
}
EDIT:
A simple cairo version:
using Gtk;
using Cairo;
public int main (string[] args) {
Cairo.ImageSurface image;
image = new Cairo.ImageSurface.from_png ("endless.png");
Gtk.init (ref args);
var window = new Gtk.Window ();
var darea = new DrawingArea ();
window.add (darea);
window.show_all ();
darea.draw.connect ((cr) => {
float xscale;
float yscale;
cr.save ();
xscale = (float) darea.get_allocated_width () / image.get_width ();
yscale = (float) darea.get_allocated_height () / image.get_height ();
cr.scale (xscale, yscale);
cr.set_source_surface (image, 0, 0);
cr.paint ();
cr.restore ();
return true;
});
window.destroy.connect (Gtk.main_quit);
Gtk.main ();
return 0;
}
EDIT 2:
I've created another version to toggle between 2 images and check if while doing this quite a few times and check if the memory increases, but it does not. Added a couple of Boxes, and added 2 buttons.
using Gtk;
using Cairo;
public int main (string[] args) {
Cairo.ImageSurface image;
image = new Cairo.ImageSurface.from_png ("endless.png");
Gtk.init (ref args);
var window = new Gtk.Window ();
var box1 = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
var box2 = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
var b1 = new Gtk.Button.with_label ("Image1");
var b2 = new Gtk.Button.with_label ("Image2");
box2.pack_start (b1, true, true, 0);
box2.pack_end (b2, true, true, 0);
var darea = new DrawingArea ();
box1.pack_start (box2, false, false, 0);
box1.pack_end (darea, true, true, 0);
window.add (box1);
window.show_all ();
b1.clicked.connect (() => {
image = new Cairo.ImageSurface.from_png ("endless.png");
darea.queue_draw ();
});
b2.clicked.connect (() => {
image = new Cairo.ImageSurface.from_png ("Gnome-logo.png");
darea.queue_draw ();
});
darea.draw.connect ((cr) => {
float xscale;
float yscale;
cr.save ();
xscale = (float) darea.get_allocated_width () / image.get_width ();
yscale = (float) darea.get_allocated_height () / image.get_height ();
cr.scale (xscale, yscale);
cr.set_source_surface (image, 0, 0);
cr.paint ();
cr.restore ();
return true;
});
window.destroy.connect (Gtk.main_quit);
Gtk.main ();
return 0;
}