[sushi/wip/cosimoc/no-clutter: 31/67] image: port to use a custom GtkWidget
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sushi/wip/cosimoc/no-clutter: 31/67] image: port to use a custom GtkWidget
- Date: Mon, 30 Apr 2018 15:16:15 +0000 (UTC)
commit 8187b1fba0649bd5df88b57a747d67fe03ff9b91
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Mon Apr 3 12:39:51 2017 -0700
image: port to use a custom GtkWidget
The Image class will draw an image at the right scale, while preserving
the aspect ratio.
src/js/viewers/image.js | 106 +++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 98 insertions(+), 8 deletions(-)
---
diff --git a/src/js/viewers/image.js b/src/js/viewers/image.js
index dea3dc5..4902d3a 100644
--- a/src/js/viewers/image.js
+++ b/src/js/viewers/image.js
@@ -23,10 +23,11 @@
*
*/
+const Gdk = imports.gi.Gdk;
const GdkPixbuf = imports.gi.GdkPixbuf;
-const GtkClutter = imports.gi.GtkClutter;
-const Gtk = imports.gi.Gtk;
const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
+const Gtk = imports.gi.Gtk;
const Gettext = imports.gettext.domain('sushi');
const _ = Gettext.gettext;
@@ -36,6 +37,94 @@ const Mainloop = imports.mainloop;
const MimeHandler = imports.ui.mimeHandler;
const Utils = imports.ui.utils;
+const Image = new Lang.Class({
+ Name: 'Image',
+ Extends: Gtk.DrawingArea,
+ Properties: {
+ 'pix': GObject.ParamSpec.object('pix', '', '',
+ GObject.ParamFlags.READWRITE,
+ GdkPixbuf.Pixbuf)
+ },
+
+ _init: function() {
+ this._pix = null;
+ this._scaledSurface = null;
+
+ this.parent();
+ },
+
+ _ensureScaledPix: function() {
+ let scaleFactor = this.get_scale_factor();
+ let width = this.get_allocated_width() * scaleFactor;
+ let height = this.get_allocated_height() * scaleFactor;
+
+ // Downscale original to fit, if necessary
+ let origWidth = this._pix.get_width();
+ let origHeight = this._pix.get_height();
+
+ let scaleX = origWidth / width;
+ let scaleY = origHeight / height;
+ let scale = Math.max(scaleX, scaleY);
+
+ let newWidth;
+ let newHeight;
+
+ if (scale < 1) {
+ newWidth = Math.min(width, origWidth * scaleFactor);
+ newHeight = Math.min(height, origHeight * scaleFactor);
+ } else {
+ newWidth = Math.floor(origWidth / scale);
+ newHeight = Math.floor(origHeight / scale);
+ }
+
+ let scaledWidth = this._scaledSurface ? this._scaledSurface.getWidth() : 0;
+ let scaledHeight = this._scaledSurface ? this._scaledSurface.getHeight() : 0;
+
+ if (newWidth != scaledWidth || newHeight != scaledHeight) {
+ let scaledPixbuf = this._pix.scale_simple(newWidth, newHeight,
+ GdkPixbuf.InterpType.BILINEAR);
+ this._scaledSurface = Gdk.cairo_surface_create_from_pixbuf(scaledPixbuf,
+ scaleFactor,
+ this.get_window());
+ }
+ },
+
+ vfunc_get_preferred_width: function() {
+ return [1, this._pix ? this.pix.get_width() : 1];
+ },
+
+ vfunc_get_preferred_height: function() {
+ return [1, this._pix ? this.pix.get_height() : 1];
+ },
+
+ vfunc_size_allocate: function(allocation) {
+ this.parent(allocation);
+ this._ensureScaledPix();
+ },
+
+ vfunc_draw: function(context) {
+ let width = this.get_allocated_width();
+ let height = this.get_allocated_height();
+
+ let scaleFactor = this.get_scale_factor();
+ let offsetX = (width - this._scaledSurface.getWidth() / scaleFactor) / 2;
+ let offsetY = (height - this._scaledSurface.getHeight() / scaleFactor) / 2;
+
+ context.setSourceSurface(this._scaledSurface, offsetX, offsetY);
+ context.paint();
+ return false;
+ },
+
+ set pix(p) {
+ this._pix = p;
+ this.queue_resize();
+ },
+
+ get pix() {
+ return this._pix;
+ }
+});
+
const ImageRenderer = new Lang.Class({
Name: 'ImageRenderer',
@@ -58,6 +147,8 @@ const ImageRenderer = new Lang.Class({
},
_createImageTexture : function(file) {
+ this._texture = new Image();
+
file.read_async
(GLib.PRIORITY_DEFAULT, null,
Lang.bind(this,
@@ -78,9 +169,7 @@ const ImageRenderer = new Lang.Class({
this._iter = anim.get_iter(null);
let pix = this._iter.get_pixbuf().apply_embedded_orientation();
-
- this._texture = new GtkClutter.Texture({ keep_aspect_ratio: true });
- this._texture.set_from_pixbuf(pix);
+ this._texture.pix = pix;
if (!anim.is_static_image())
this._startTimeout();
@@ -99,9 +188,10 @@ const ImageRenderer = new Lang.Class({
}));
},
- getSizeForAllocation : function(allocation, fullScreen) {
- let baseSize = this._texture.get_base_size();
- return Utils.getScaledSize(baseSize, allocation, fullScreen);
+ getSizeForAllocation : function(allocation) {
+ let width = this._texture.pix.get_width();
+ let height = this._texture.pix.get_height();
+ return Utils.getScaledSize([width, height], allocation, false);
},
_startTimeout : function() {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]