[sushi/wip/cosimoc/no-clutter: 12/50] Don't use Clutter to render the texture
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sushi/wip/cosimoc/no-clutter: 12/50] Don't use Clutter to render the texture
- Date: Mon, 17 Jun 2019 18:33:37 +0000 (UTC)
commit 52b839ebea465b4baaa02064ae72865b6c7f9c90
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Mon Apr 3 12:35:21 2017 -0700
Don't use Clutter to render the texture
This also changes the renderer interface to require a GtkWidget.
All the renderers have been changed to return a widget.
The image renderer uses a custom widget that allows us to have
the desired scaling behavior while preserving aspect ratio.
src/js/ui/fallbackRenderer.js | 4 +-
src/js/ui/mainWindow.js | 94 ++++++++++----------------------------
src/js/ui/spinnerBox.js | 35 +++------------
src/js/viewers/audio.js | 4 +-
src/js/viewers/evince.js | 6 +--
src/js/viewers/font.js | 7 +--
src/js/viewers/html.js | 6 +--
src/js/viewers/image.js | 102 ++++++++++++++++++++++++++++++++++++++----
src/js/viewers/text.js | 5 +--
9 files changed, 130 insertions(+), 133 deletions(-)
---
diff --git a/src/js/ui/fallbackRenderer.js b/src/js/ui/fallbackRenderer.js
index 57243a3..9e9bfbe 100644
--- a/src/js/ui/fallbackRenderer.js
+++ b/src/js/ui/fallbackRenderer.js
@@ -97,14 +97,12 @@ var FallbackRenderer = new Lang.Class({
this._applyLabels();
this._box.show_all();
- this._actor = new GtkClutter.Actor({ contents: this._box });
- Utils.alphaGtkWidget(this._actor.get_widget());
callback();
},
render : function() {
- return this._actor;
+ return this._box;
},
_applyLabels : function() {
diff --git a/src/js/ui/mainWindow.js b/src/js/ui/mainWindow.js
index 6123274..a6f11d5 100644
--- a/src/js/ui/mainWindow.js
+++ b/src/js/ui/mainWindow.js
@@ -52,7 +52,7 @@ var MainWindow = new Lang.Class({
this._isFullScreen = false;
this._pendingRenderer = null;
this._renderer = null;
- this._texture = null;
+ this._view = null;
this._toolbar = null;
this._toolbarId = 0;
@@ -60,7 +60,6 @@ var MainWindow = new Lang.Class({
this._application = args.application;
this._createGtkWindow();
- this._createClutterEmbed();
this.file = null;
},
@@ -89,29 +88,13 @@ var MainWindow = new Lang.Class({
this._gtkWindow.connect('realize',
Lang.bind(this, this._onRealize));
- this._embed = new Gtk.Overlay();
- this._gtkWindow.add(this._embed);
- },
-
- _createClutterEmbed : function() {
- this._clutterEmbed = new GtkClutter.Embed();
- this._embed.add(this._clutterEmbed);
-
- this._clutterEmbed.set_receives_default(true);
- this._clutterEmbed.set_can_default(true);
+ let eventBox = new Gtk.EventBox({ visible_window: false });
+ eventBox.connect('button-press-event',
+ Lang.bind(this, this._onButtonPressEvent));
+ this._gtkWindow.add(eventBox);
- this._stage = this._clutterEmbed.get_stage();
- this._stage.set_use_alpha(true);
- this._stage.set_opacity(0);
- this._stage.set_color(new Clutter.Color({ red: 0,
- green: 0,
- blue: 0,
- alpha: 255 }));
-
- this._stage.set_layout_manager(new Clutter.BinLayout());
-
- this._stage.connect('button-press-event',
- Lang.bind(this, this._onButtonPressEvent));
+ this._embed = new Gtk.Overlay();
+ eventBox.add(this._embed);
},
/**************************************************************************
@@ -143,20 +126,14 @@ var MainWindow = new Lang.Class({
return false;
},
- _onButtonPressEvent : function(actor, event) {
- let stageWin = ClutterGdk.get_stage_window(this._stage);
- let win_coords = event.get_coords();
-
- if (event.get_source() == this._texture &&
- !this._renderer.moveOnClick)
+ _onButtonPressEvent : function(window, event) {
+ if (!this._renderer.moveOnClick)
return false;
- let root_coords = stageWin.get_root_coords(win_coords[0],
- win_coords[1]);
-
- this._gtkWindow.begin_move_drag(event.get_button(),
- root_coords[0],
- root_coords[1],
+ let [, rootX, rootY] = event.get_root_coords();
+ let [, button] = event.get_button();
+ this._gtkWindow.begin_move_drag(button,
+ rootX, rootY,
event.get_time());
return false;
@@ -200,27 +177,8 @@ var MainWindow = new Lang.Class({
},
_positionTexture : function() {
- let yFactor = 0;
-
- let textureSize = this._getTextureSize();
let windowSize = this._getWindowSize();
- if (textureSize[0] < Constants.VIEW_MIN &&
- textureSize[1] < Constants.VIEW_MIN) {
- yFactor = 0.52;
- }
-
- if (yFactor == 0) {
- if (this._isFullScreen &&
- (textureSize[0] > textureSize[1]))
- yFactor = 0.52;
- else
- yFactor = 0.92;
- }
-
- this._texture.set_size(textureSize[0], textureSize[1]);
- this._textureYAlign.factor = yFactor;
-
if (this._lastWindowSize &&
windowSize[0] == this._lastWindowSize[0] &&
windowSize[1] == this._lastWindowSize[1])
@@ -275,28 +233,22 @@ var MainWindow = new Lang.Class({
this._pendingRenderer = null;
/* generate the texture and toolbar for the new renderer */
- this._createTexture();
+ this._createView();
this._createToolbar();
},
- _createTexture : function() {
- if (this._texture) {
- this._texture.destroy();
- this._texture = null;
+ _createView : function() {
+ if (this._view) {
+ this._view.destroy();
+ this._view = null;
}
- this._texture = this._renderer.render();
- this._textureYAlign =
- new Clutter.AlignConstraint({ source: this._stage,
- factor: 0.5,
- align_axis: Clutter.AlignAxis.Y_AXIS });
- this._texture.add_constraint(this._textureYAlign);
- this._texture.add_constraint(
- new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.SIZE,
- source: this._stage }));
+ this._view = this._renderer.render();
+ this._view.expand = true;
+ this._view.show();
+ this._embed.add(this._view);
this.refreshSize();
- this._stage.add_child(this._texture);
},
/**************************************************************************
@@ -386,7 +338,7 @@ var MainWindow = new Lang.Class({
setFile : function(file) {
this.file = file;
this._createRenderer(file);
- this._createTexture();
+ this._createView();
this._createToolbar();
this._gtkWindow.show_all();
diff --git a/src/js/ui/spinnerBox.js b/src/js/ui/spinnerBox.js
index 32c132e..2d2475f 100644
--- a/src/js/ui/spinnerBox.js
+++ b/src/js/ui/spinnerBox.js
@@ -26,9 +26,7 @@
const Gettext = imports.gettext.domain('sushi');
const _ = Gettext.gettext;
const Gtk = imports.gi.Gtk;
-const GtkClutter = imports.gi.GtkClutter;
-const Tweener = imports.ui.tweener;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
@@ -44,26 +42,20 @@ var SpinnerBox = new Lang.Class({
this.canFullScreen = false;
this.moveOnClick = true;
- this._spinnerBox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
- spacing: 12 });
- this._spinnerBox.show();
-
this._spinner = new Gtk.Spinner();
- this._spinner.show();
this._spinner.set_size_request(SPINNER_SIZE, SPINNER_SIZE);
- this._spinnerBox.pack_start(this._spinner, true, true, 0);
this._label = new Gtk.Label();
this._label.set_text(_("Loading…"));
- this._label.show();
- this._spinnerBox.pack_start(this._label, true, true, 0);
- this.actor = new GtkClutter.Actor({ contents: this._spinnerBox });
- this.actor.set_opacity(0);
+ this._spinnerBox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
+ spacing: 12 });
+ this._spinnerBox.pack_start(this._spinner, true, true, 0);
+ this._spinnerBox.pack_start(this._label, true, true, 0);
},
render : function() {
- return this.actor;
+ return this._spinnerBox;
},
getSizeForAllocation : function() {
@@ -88,24 +80,11 @@ var SpinnerBox = new Lang.Class({
this._timeoutId = 0;
}
- Tweener.addTween(this.actor,
- { opacity: 0,
- time: 0.15,
- transition: 'easeOutQuad',
- onComplete: function() {
- this.actor.destroy();
- },
- onCompleteScope: this
- });
+ this._spinnerBox.destroy();
},
_onTimeoutCompleted : function() {
this._timeoutId = 0;
-
- Tweener.addTween(this.actor,
- { opacity: 255,
- time: 0.3,
- transition: 'easeOutQuad'
- });
+ this._spinnerBox.show_all();
},
});
diff --git a/src/js/viewers/audio.js b/src/js/viewers/audio.js
index 604b9f1..d6307ab 100644
--- a/src/js/viewers/audio.js
+++ b/src/js/viewers/audio.js
@@ -27,7 +27,6 @@ const GdkPixbuf = imports.gi.GdkPixbuf;
const Gio = imports.gi.Gio;
const Gst = imports.gi.Gst;
const Gtk = imports.gi.Gtk;
-const GtkClutter = imports.gi.GtkClutter;
const Sushi = imports.gi.Sushi;
const Gettext = imports.gettext.domain('sushi');
@@ -80,13 +79,12 @@ const AudioRenderer = new Lang.Class({
vbox.pack_start(this._albumLabel, false, false, 0);
this._box.show_all();
- this._actor = new GtkClutter.Actor({ contents: this._box });
this._callback();
},
render : function() {
- return this._actor;
+ return this._box;
},
_createPlayer : function(file) {
diff --git a/src/js/viewers/evince.js b/src/js/viewers/evince.js
index e1188d5..b93b8f8 100644
--- a/src/js/viewers/evince.js
+++ b/src/js/viewers/evince.js
@@ -26,7 +26,6 @@
const EvDoc = imports.gi.EvinceDocument;
const EvView = imports.gi.EvinceView;
const Gtk = imports.gi.Gtk;
-const GtkClutter = imports.gi.GtkClutter;
const Sushi = imports.gi.Sushi;
const Gettext = imports.gettext.domain('sushi');
@@ -59,7 +58,7 @@ const EvinceRenderer = new Lang.Class({
},
render : function() {
- return this._actor;
+ return this._scrolledWin;
},
_updatePageLabel : function() {
@@ -91,9 +90,6 @@ const EvinceRenderer = new Lang.Class({
this._view.set_model(this._model);
this._scrolledWin.add(this._view);
- this._actor = new GtkClutter.Actor({ contents: this._scrolledWin });
- this._actor.set_reactive(true);
-
this._callback();
},
diff --git a/src/js/viewers/font.js b/src/js/viewers/font.js
index 0f3426e..4871f76 100644
--- a/src/js/viewers/font.js
+++ b/src/js/viewers/font.js
@@ -24,11 +24,9 @@
*/
const MimeHandler = imports.ui.mimeHandler;
-const Utils = imports.ui.utils;
const Lang = imports.lang;
-const GtkClutter = imports.gi.GtkClutter;
const Gtk = imports.gi.Gtk;
const GLib = imports.gi.GLib;
const Sushi = imports.gi.Sushi;
@@ -50,9 +48,6 @@ const FontRenderer = new Lang.Class({
this._fontWidget.show();
this._fontWidget.connect('loaded',
Lang.bind(this, this._onFontLoaded));
-
- this._fontActor = new GtkClutter.Actor({ contents: this._fontWidget });
- Utils.alphaGtkWidget(this._fontActor.get_widget());
},
_onFontLoaded : function() {
@@ -60,7 +55,7 @@ const FontRenderer = new Lang.Class({
},
render : function() {
- return this._fontActor;
+ return this._fontWidget;
},
getSizeForAllocation : function(allocation) {
diff --git a/src/js/viewers/html.js b/src/js/viewers/html.js
index cd70d4f..a26e4a3 100644
--- a/src/js/viewers/html.js
+++ b/src/js/viewers/html.js
@@ -23,7 +23,6 @@
*
*/
-const GtkClutter = imports.gi.GtkClutter;
const Gtk = imports.gi.Gtk;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
@@ -55,14 +54,11 @@ const HTMLRenderer = new Lang.Class({
this._webView.load_uri(file.get_uri());
- this._actor = new GtkClutter.Actor({ contents: this._webView });
- this._actor.set_reactive(true);
-
this._callback();
},
render : function() {
- return this._actor;
+ return this._webView;
},
getSizeForAllocation : function(allocation) {
diff --git a/src/js/viewers/image.js b/src/js/viewers/image.js
index 08dc97f..82b4ca5 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,
@@ -79,9 +166,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();
@@ -100,9 +185,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() {
diff --git a/src/js/viewers/text.js b/src/js/viewers/text.js
index 3a3cea6..1c0cd4a 100644
--- a/src/js/viewers/text.js
+++ b/src/js/viewers/text.js
@@ -26,7 +26,6 @@
imports.gi.versions.GtkSource = '4';
const Gdk = imports.gi.Gdk;
-const GtkClutter = imports.gi.GtkClutter;
const Gtk = imports.gi.Gtk;
const GLib = imports.gi.GLib;
const GtkSource = imports.gi.GtkSource;
@@ -71,7 +70,7 @@ const TextRenderer = new Lang.Class({
},
render : function() {
- return this._actor;
+ return this._scrolledWin;
},
_onBufferLoaded : function(loader, buffer) {
@@ -103,8 +102,6 @@ const TextRenderer = new Lang.Class({
this._scrolledWin.add(this._view);
this._scrolledWin.show_all();
- this._actor = new GtkClutter.Actor({ contents: this._scrolledWin });
- this._actor.set_reactive(true);
this._callback();
},
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]