[sushi/wip/cosimoc/no-clutter: 14/66] 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: 14/66] image: port to use a custom GtkWidget
- Date: Sat, 8 Jun 2019 18:41:20 +0000 (UTC)
commit 6015dd2b4dd9668e4bac1ef56724ad4e6c1bba0e
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.
flatpak/org.gnome.NautilusPreviewer.json | 3 +-
src/js/viewers/image.js | 102 ++++++++++++++++++++++++++++---
2 files changed, 96 insertions(+), 9 deletions(-)
---
diff --git a/flatpak/org.gnome.NautilusPreviewer.json b/flatpak/org.gnome.NautilusPreviewer.json
index 696c8e4..b82d260 100644
--- a/flatpak/org.gnome.NautilusPreviewer.json
+++ b/flatpak/org.gnome.NautilusPreviewer.json
@@ -27,7 +27,8 @@
"--filesystem=~/.config/dconf:ro",
"--filesystem=host:ro",
"--filesystem=home",
- "--env=DCONF_USER_CONFIG_DIR=.config/dconf"
+ "--env=DCONF_USER_CONFIG_DIR=.config/dconf",
+ "--env=GST_DEBUG=2,Sushi*:6"
],
"modules": [
{
diff --git a/src/js/viewers/image.js b/src/js/viewers/image.js
index dea3dc5..8144769 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,90 @@ 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 = width / origWidth;
+ let scaleY = height / origHeight;
+ let scale = Math.min(scaleX, scaleY);
+
+ let newWidth = Math.floor(origWidth * scale);
+ let 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) {
+ if (!this._scaledSurface)
+ return false;
+
+ 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._scaledSurface = null;
+ this.queue_resize();
+ },
+
+ get pix() {
+ return this._pix;
+ }
+});
+
const ImageRenderer = new Lang.Class({
Name: 'ImageRenderer',
@@ -58,6 +143,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 +165,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 +184,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]