NeoLayoutViewer/src/scaling-image.vala

119 lines
3.3 KiB
Vala

/* vim: set tabstop=2:softtabstop=2:shiftwidth=2:noexpandtab */
// modules: Gtk Gdk
using Gtk;
using Gdk;
namespace NeoLayoutViewer {
/* Reacts on window size changes.
*
*/
class ScalingImage: Gtk.Image {
private Gtk.Window winMain;
private Gdk.Pixbuf[] source_pixbufs;
private Gdk.Pixbuf[] scaled_pixbufs;
private int width = -1;
private int height = -1;
private int start_width;
private int start_height;
private int reference_w;
private int reference_h;
private int win_width;
private int win_height;
private int source_index;
private static int __id = 0;
private int id;
public ScalingImage(
int start_width, int start_height,
Gtk.Window winMain, int reference_w, int reference_h,
Gdk.Pixbuf[] source_pixbufs,
int start_source_index = 0
)
{
this.id = ScalingImage.__id++;
this.winMain = winMain;
this.start_width = start_width;
this.start_height = start_height;
this.width = start_width;
this.height = start_height;
this.reference_w = reference_w;
this.reference_h = reference_h;
this.win_width = this.winMain.get_allocated_width();
this.win_height = this.winMain.get_allocated_height();
this.source_pixbufs = source_pixbufs;
this.scaled_pixbufs = new Gdk.Pixbuf[source_pixbufs.length];
this.source_index = start_source_index;
GLib.assert(this.source_index >= 0);
GLib.assert(this.source_index < this.source_pixbufs.length);
this.winMain.check_resize.connect(main_resized);
}
private void main_resized() {
// Get new window size
int win_width2;
int win_height2;
//win_width2 = this.winMain.get_allocated_width();
//win_height2 = this.winMain.get_allocated_height();
this.winMain.get_size(out win_width2, out win_height2);
if (win_width == win_width2 && win_height == win_height2) {
//debug(@"(ScalingImage $(this.id)) same width $(win_width)");
return;
}
debug(@"Window resize signal. New width/height: $(width)/$(height)\n");
if (win_width2 == 1 && win_height2 == 1) {
return; // (1, 1) send if user show/hides window very fast.
}
// Eval new image size
GLib.assert(this.win_width > 0);
GLib.assert(this.win_height > 0);
this.width = (this.start_width * win_width2)/this.reference_w;
this.height = (this.start_height * win_height2)/this.reference_h;
// Overwrite old window size
this.win_width = win_width2;
this.win_height = win_height2;
this.select_pixbuf(this.source_index);
}
public void select_pixbuf(int new_source_index)
{
GLib.assert(new_source_index >= 0);
GLib.assert(new_source_index < this.source_pixbufs.length);
GLib.assert(this.source_pixbufs.length == this.scaled_pixbufs.length);
this.source_index = new_source_index;
int i = new_source_index;
// Scale pixbuf if required
if (this.scaled_pixbufs[i] == null ||
this.width != this.scaled_pixbufs[i].width ||
this.height != this.scaled_pixbufs[i].height) {
//debug(@"(ScalingImage $(this.id)) scaling to $(this.width)x$(this.height)");
this.scaled_pixbufs[i] = this.source_pixbufs[i].scale_simple(
this.width, this.height, Gdk.InterpType.BILINEAR);
}
// Update displayed image
//debug(@"(ScalingImage $(this.id)) draw image");
this.set_from_pixbuf(this.scaled_pixbufs[i]);
}
} // End class ScalingImage
}