[sushi] mainwindow: add a spinnerBox pseudo-renderer to use for loading feedback
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sushi] mainwindow: add a spinnerBox pseudo-renderer to use for loading feedback
- Date: Fri, 13 May 2011 21:36:43 +0000 (UTC)
commit 4d469b2bfa955b2f5e55defcac74552463b73552
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Fri May 13 17:21:43 2011 -0400
mainwindow: add a spinnerBox pseudo-renderer to use for loading feedback
Instead of having every plugin implement its own loading spinbox, make
it a window-owned renderer, and let the window do all the
allocation/positioning magic.
src/Makefile-js.am | 1 +
src/js/ui/mainWindow.js | 65 ++++++++++++++++++++++++--------------
src/js/ui/spinnerBox.js | 81 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 123 insertions(+), 24 deletions(-)
---
diff --git a/src/Makefile-js.am b/src/Makefile-js.am
index 18f580d..82d7edb 100644
--- a/src/Makefile-js.am
+++ b/src/Makefile-js.am
@@ -6,6 +6,7 @@ dist_jsui_DATA = \
js/ui/fallbackRenderer.js \
js/ui/mainWindow.js \
js/ui/mimeHandler.js \
+ js/ui/spinnerBox.js \
js/ui/utils.js
jsviewersdir = $(pkgdatadir)/js/viewers
diff --git a/src/js/ui/mainWindow.js b/src/js/ui/mainWindow.js
index 2509d54..9d8957f 100644
--- a/src/js/ui/mainWindow.js
+++ b/src/js/ui/mainWindow.js
@@ -15,6 +15,7 @@ const Mainloop = imports.mainloop;
const MimeHandler = imports.ui.mimeHandler;
const Constants = imports.util.constants;
+const SpinnerBox = imports.ui.spinnerBox;
const Sushi = imports.gi.Sushi;
@@ -246,18 +247,50 @@ MainWindow.prototype = {
delete this._renderer;
}
- let info = file.query_info("standard::content-type",
- 0, null);
- this._renderer = this._mimeHandler.getObject(info.get_content_type());
+ /* create a temporary spinner renderer, that will timeout and show itself
+ * if the loading takes too long.
+ */
+ this._renderer = new SpinnerBox.SpinnerBox();
+ this._renderer.startTimeout();
+
+ file.query_info_async
+ (Gio.FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME + "," +
+ Gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ Gio.FileQueryInfoFlags.NONE,
+ GLib.PRIORITY_DEFAULT, null,
+ Lang.bind (this,
+ function(obj, res) {
+ try {
+ this._fileInfo = obj.query_info_finish(res);
+ this._titleLabel.set_text(this._fileInfo.get_display_name());
+
+ /* now prepare the real renderer */
+ this._pendingRenderer = this._mimeHandler.getObject(this._fileInfo.get_content_type());
+ this._pendingRenderer.prepare(file, this, Lang.bind(this, this._onRendererPrepared));
+ } catch(e) {
+ /* FIXME: report the error */
+ }}));
+ },
+
+ _onRendererPrepared : function() {
+ /* destroy the spinner renderer */
+ this._renderer.destroy();
+
+ this._renderer = this._pendingRenderer;
+ delete this._pendingRenderer;
+
+ /* generate the texture and toolbar for the new renderer */
+ this._createTexture();
+ this._createToolbar();
},
- _createTexture : function(file) {
+ _createTexture : function() {
if (this._texture) {
this._texture.destroy();
delete this._texture;
}
- this._texture = this._renderer.render(file, this);
+ this._texture = this._renderer.render();
this._textureXAlign =
new Clutter.AlignConstraint({ source: this._stage,
@@ -481,33 +514,17 @@ MainWindow.prototype = {
},
- _updateLabel : function(file) {
- file.query_info_async(Gio.FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
- Gio.FileQueryInfoFlags.NONE,
- GLib.PRIORITY_DEFAULT, null,
- Lang.bind (this,
- function (obj, res) {
- try {
- let info = obj.query_info_finish(res);
- this._titleLabel.set_label(info.get_display_name());
- } catch (e) {
- }
- }));
- },
-
/**************************************************************************
************************ titlebar helpers ********************************
**************************************************************************/
- _createTitle : function(file) {
+ _createTitle : function() {
if (this._titleLabel) {
- this._updateLabel(file);
this._titleActor.raise_top();
this._quitActor.raise_top();
return;
}
this._titleLabel = new Gtk.Label({ label: "" });
- this._updateLabel(file);
this._titleLabel.get_style_context().add_class("np-decoration");
this._titleLabel.show();
@@ -621,9 +638,9 @@ MainWindow.prototype = {
this.file = file;
this._createAlphaBackground();
this._createRenderer(file);
- this._createTexture(file);
+ this._createTexture();
this._createToolbar();
- this._createTitle(file);
+ this._createTitle();
if (!this._gtkWindow.get_visible()) {
this._moveWindow();
diff --git a/src/js/ui/spinnerBox.js b/src/js/ui/spinnerBox.js
new file mode 100644
index 0000000..1eb24c6
--- /dev/null
+++ b/src/js/ui/spinnerBox.js
@@ -0,0 +1,81 @@
+let Clutter = imports.gi.Clutter;
+let Gtk = imports.gi.Gtk;
+
+let Tweener = imports.ui.tweener;
+let Mainloop = imports.mainloop;
+
+let SPINNER_SIZE = 48;
+let TIMEOUT = 500;
+
+function SpinnerBox(args) {
+ this._init(args);
+ this.canFullScreen = false;
+ this.moveOnClick = true;
+}
+
+SpinnerBox.prototype = {
+ _init : function(args) {
+ this._spinnerBox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 12);
+ this._spinnerBox.show();
+
+ this._spinner = Gtk.Spinner.new();
+ 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);
+ },
+
+ render : function() {
+ return this.actor;
+ },
+
+ getSizeForAllocation : function() {
+ let spinnerSize = this._spinnerBox.get_preferred_size();
+ return [ spinnerSize[0].width,
+ spinnerSize[0].height ];
+ },
+
+ startTimeout : function() {
+ if (this._timeoutId)
+ return;
+
+ this._spinner.start();
+ this._timeoutId = Mainloop.timeout_add(TIMEOUT,
+ Lang.bind(this,
+ this._onTimeoutCompleted));
+ },
+
+ destroy : function() {
+ if (this._timeoutId) {
+ Mainloop.source_remove(this._timeoutId);
+ delete this._timeoutId;
+ }
+
+ Tweener.addTween(this.actor,
+ { opacity: 0,
+ time: 0.15,
+ transition: 'easeOutQuad',
+ onComplete: function() {
+ this.actor.destroy();
+ },
+ onCompleteScope: this
+ });
+ },
+
+ _onTimeoutCompleted : function() {
+ delete this._timeoutId;
+
+ Tweener.addTween(this.actor,
+ { opacity: 255,
+ time: 0.3,
+ transition: 'easeOutQuad'
+ });
+ },
+}
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]