[sushi/wip/cosimoc/no-clutter: 51/66] Make renderers GtkWidgets



commit cb9537fd019c3d380567a52a8a9009b46415a970
Author: Cosimo Cecchi <cosimo endlessm com>
Date:   Wed Jun 5 19:26:29 2019 -0700

    Make renderers GtkWidgets
    
    This simplifies management of renderers, which can be instantiated
    directly as widgets after this commit.

 flatpak/org.gnome.NautilusPreviewer.json |  7 ++--
 src/js/ui/application.js                 |  4 +--
 src/js/ui/fallbackRenderer.js            | 25 ++++++--------
 src/js/ui/mainWindow.js                  | 56 ++++++++------------------------
 src/js/ui/mimeHandler.js                 |  7 ++--
 src/js/ui/spinnerBox.js                  | 24 +++++++-------
 src/js/viewers/audio.js                  | 28 +++++++---------
 src/js/viewers/evince.js                 | 22 ++++++-------
 src/js/viewers/font.js                   | 18 ++++------
 src/js/viewers/gst.js                    | 22 ++++++-------
 src/js/viewers/html.js                   | 18 ++++------
 src/js/viewers/image.js                  | 25 +++++++-------
 src/js/viewers/text.js                   | 16 +++------
 13 files changed, 105 insertions(+), 167 deletions(-)
---
diff --git a/flatpak/org.gnome.NautilusPreviewer.json b/flatpak/org.gnome.NautilusPreviewer.json
index b82d260..6e98ae0 100644
--- a/flatpak/org.gnome.NautilusPreviewer.json
+++ b/flatpak/org.gnome.NautilusPreviewer.json
@@ -27,8 +27,7 @@
         "--filesystem=~/.config/dconf:ro",
         "--filesystem=host:ro",
         "--filesystem=home",
-        "--env=DCONF_USER_CONFIG_DIR=.config/dconf",
-        "--env=GST_DEBUG=2,Sushi*:6"
+        "--env=DCONF_USER_CONFIG_DIR=.config/dconf"
     ],
     "modules": [
         {
@@ -115,8 +114,8 @@
             "buildsystem": "meson",
             "sources": [
                 {
-                    "type": "git",
-                    "url": ".."
+                    "type": "dir",
+                    "path": ".."
                 }
             ]
         }
diff --git a/src/js/ui/application.js b/src/js/ui/application.js
index 0594326..23052f7 100644
--- a/src/js/ui/application.js
+++ b/src/js/ui/application.js
@@ -88,7 +88,7 @@ var Application = new Lang.Class({
     },
 
     Close: function() {
-        this._mainWindow.close();
+        this._mainWindow.destroy();
     },
 
     ShowFile : function(uri, xid, closeIfAlreadyShown) {
@@ -96,7 +96,7 @@ var Application = new Lang.Class({
        if (closeIfAlreadyShown &&
            this._mainWindow.file &&
            this._mainWindow.file.equal(file)) {
-           this._mainWindow.close();
+           this._mainWindow.destroy();
            return;
        }
         this._mainWindow.setParent(xid);
diff --git a/src/js/ui/fallbackRenderer.js b/src/js/ui/fallbackRenderer.js
index 5d30ca1..d9af592 100644
--- a/src/js/ui/fallbackRenderer.js
+++ b/src/js/ui/fallbackRenderer.js
@@ -34,16 +34,15 @@ const Lang = imports.lang;
 
 var FallbackRenderer = new Lang.Class({
     Name: 'FallbackRenderer',
+    Extends: Gtk.Box,
 
-    _init : function() {
-        this._fileLoader = null;
-        this._fileLoaderId = 0;
+    _init : function(file, mainWindow) {
+        this.parent({ orientation: Gtk.Orientation.HORIZONTAL,
+                      spacing: 6 });
 
         this.moveOnClick = true;
         this.canFullScreen = false;
-    },
 
-    render : function(file, mainWindow) {
         this._mainWindow = mainWindow;
         this._lastWidth = 0;
         this._lastHeight = 0;
@@ -54,10 +53,8 @@ var FallbackRenderer = new Lang.Class({
             this._fileLoader.connect('notify',
                                      Lang.bind(this, this._onFileInfoChanged));
 
-        this._box = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
-                                  spacing: 6 });
         this._image = new Gtk.Image();
-        this._box.pack_start(this._image, false, false, 0);
+        this.pack_start(this._image, false, false, 0);
         this._updateIcon(new Gio.ThemedIcon({ name: 'text-x-generic' }));
 
         let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
@@ -65,7 +62,7 @@ var FallbackRenderer = new Lang.Class({
                                  margin_top: 48,
                                  margin_start: 12,
                                  margin_end: 12 });
-        this._box.pack_start(vbox, false, false, 0);
+        this.pack_start(vbox, false, false, 0);
 
         let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
                                  spacing: 6 });
@@ -94,9 +91,7 @@ var FallbackRenderer = new Lang.Class({
 
         this._applyLabels();
 
-        this._box.show_all();
-
-        return this._box;
+        this.connect('destroy', this._onDestroy.bind(this));
     },
 
     _applyLabels : function() {
@@ -157,7 +152,7 @@ var FallbackRenderer = new Lang.Class({
         this._mainWindow.resizeWindow();
     },
 
-    clear : function() {
+    _onDestroy : function() {
         if (this._fileLoader) {
             this._fileLoader.disconnect(this._fileLoaderId);
             this._fileLoaderId = 0;
@@ -168,8 +163,8 @@ var FallbackRenderer = new Lang.Class({
     },
 
     getSizeForAllocation : function(allocation) {
-        let width = this._box.get_preferred_width()[1];
-        let height = this._box.get_preferred_height()[1];
+        let width = this.get_preferred_width()[1];
+        let height = this.get_preferred_height()[1];
 
         /* never make it shrink; this could happen when the
          * spinner hides.
diff --git a/src/js/ui/mainWindow.js b/src/js/ui/mainWindow.js
index 543c9e7..146cb60 100644
--- a/src/js/ui/mainWindow.js
+++ b/src/js/ui/mainWindow.js
@@ -100,7 +100,7 @@ var MainWindow = new Lang.Class({
      ****************** main object event callbacks ***************************
      **************************************************************************/
     _onDeleteEvent : function() {
-        this._clearAndQuit();
+        this.destroy();
     },
 
     _onRealize: function() {
@@ -116,7 +116,7 @@ var MainWindow = new Lang.Class({
         if (key == Gdk.KEY_Escape ||
             key == Gdk.KEY_space ||
             key == Gdk.KEY_q)
-            this._clearAndQuit();
+            this.destroy();
 
         if (key == Gdk.KEY_f ||
             key == Gdk.KEY_F11)
@@ -158,18 +158,6 @@ var MainWindow = new Lang.Class({
     },
 
     _createRenderer : function(file) {
-        if (this._renderer) {
-            if (this._renderer.clear)
-                this._renderer.clear();
-
-            this._renderer = null;
-        }
-
-        /* create a temporary spinner renderer, that will timeout and show itself
-         * if the loading takes too long.
-         */
-        this._renderer = new SpinnerBox.SpinnerBox();
-
         file.query_info_async
         (Gio.FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME + ',' +
          Gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
@@ -181,27 +169,27 @@ var MainWindow = new Lang.Class({
                  this.setTitle(this._fileInfo.get_display_name());
 
                  /* now prepare the real renderer */
-                 this._renderer = this._mimeHandler.getObject(this._fileInfo.get_content_type());
-                 this._createView(file);
+                 let klass = this._mimeHandler.getKlass(this._fileInfo.get_content_type());
+                 this._createView(file, klass);
                  this._createToolbar();
              } catch(e) {
                  /* FIXME: report the error */
-                 logError(e, 'Error calling prepare() on viewer');
+                 logError(e, 'Error creating viewer');
              }})
         );
     },
 
-    _createView : function(file) {
-        if (this._view) {
-            this._view.destroy();
-            this._view = null;
+    _createView : function (file, klass) {
+        if (this._renderer) {
+            this._renderer.destroy()
+            this._renderer = null;
         }
 
-        this._view = this._renderer.render(file, this);
-        this._view.expand = true;
-        this._view.show();
+        this._renderer = new klass(file, this);
+        this._renderer.show_all();
+        this._renderer.expand = true;
+        this._embed.add(this._renderer);
 
-        this._embed.add(this._view);
         this.resizeWindow();
     },
 
@@ -265,16 +253,6 @@ var MainWindow = new Lang.Class({
         return false;
     },
 
-    /**************************************************************************
-     *********************** Window move/fade helpers *************************
-     **************************************************************************/
-    _clearAndQuit : function() {
-        if (this._renderer.clear)
-            this._renderer.clear();
-
-        this.destroy();
-    },
-
     /**************************************************************************
      ************************ public methods **********************************
      **************************************************************************/
@@ -292,10 +270,6 @@ var MainWindow = new Lang.Class({
     setFile : function(file) {
         this.file = file;
         this._createRenderer(file);
-        this._createView();
-        this._createToolbar();
-
-        this.show_all();
     },
 
     setTitle : function(label) {
@@ -317,9 +291,5 @@ var MainWindow = new Lang.Class({
         }
 
         return this._isFullScreen;
-    },
-
-    close : function() {
-        this._clearAndQuit();
     }
 });
diff --git a/src/js/ui/mimeHandler.js b/src/js/ui/mimeHandler.js
index f82264d..b7542e9 100644
--- a/src/js/ui/mimeHandler.js
+++ b/src/js/ui/mimeHandler.js
@@ -58,11 +58,10 @@ MimeHandler.prototype = {
             this.registerMime(mimeTypes[idx], klass);
     },
 
-    getObject: function(mime) {
+    getKlass: function(mime) {
         if (this._mimeTypes[mime]) {
             /* first, try a direct match with the mimetype itself */
-            let klass = this._mimeTypes[mime];
-            return new klass();
+            return this._mimeTypes[mime];
         } else {
             /* if this fails, try to see if we have any handlers
              * registered for a parent type.
@@ -73,7 +72,7 @@ MimeHandler.prototype = {
             }
 
             /* finally, resort to the fallback renderer */
-            return new FallbackRenderer.FallbackRenderer();
+            return FallbackRenderer.FallbackRenderer;
         }
     }
 }
diff --git a/src/js/ui/spinnerBox.js b/src/js/ui/spinnerBox.js
index 0db678e..402244d 100644
--- a/src/js/ui/spinnerBox.js
+++ b/src/js/ui/spinnerBox.js
@@ -33,8 +33,13 @@ let SPINNER_SIZE = 48;
 
 var SpinnerBox = new Lang.Class({
     Name: 'SpinnerBox',
+    Extends: Gtk.Box,
+
+    _init : function() {
+        this.parent({ orientation: Gtk.Orientation.VERTICAL,
+                      valign: Gtk.Align.CENTER,
+                      spacing: 12 });
 
-    _init : function(args) {
         this.canFullScreen = false;
         this.moveOnClick = true;
 
@@ -44,22 +49,15 @@ var SpinnerBox = new Lang.Class({
         this._label = new Gtk.Label();
         this._label.set_text(_("Loading…"));
 
-        this._spinnerBox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
-                                         valign: Gtk.Align.CENTER,
-                                         spacing: 12 });
-        this._spinnerBox.pack_start(this._spinner, true, true, 0);
-        this._spinnerBox.pack_start(this._label, true, true, 0);
-
-        this._spinnerBox.show_all();
-    },
+        this.pack_start(this._spinner, true, true, 0);
+        this.pack_start(this._label, true, true, 0);
 
-    render : function() {
-        this._spinner.start();
-        return this._spinnerBox;
+        this.start();
+        this.show_all();
     },
 
     getSizeForAllocation : function() {
-        let spinnerSize = this._spinnerBox.get_preferred_size();
+        let spinnerSize = this.get_preferred_size();
         return [ spinnerSize[0].width,
                  spinnerSize[0].height ];
     }
diff --git a/src/js/viewers/audio.js b/src/js/viewers/audio.js
index 6743ffe..9357921 100644
--- a/src/js/viewers/audio.js
+++ b/src/js/viewers/audio.js
@@ -56,30 +56,30 @@ function _formatTimeString(timeVal) {
 
 const AudioRenderer = new Lang.Class({
     Name: 'AudioRenderer',
+    Extends: Gtk.Box,
+
+    _init : function(file, mainWindow) {
+        this.parent({ orientation: Gtk.Orientation.HORIZONTAL,
+                      spacing: 6 });
 
-    _init : function() {
         this.moveOnClick = true;
         this.canFullScreen = false;
-    },
 
-    render : function(file, mainWindow) {
         this._mainWindow = mainWindow;
         this._file = file;
 
         this._createPlayer(file);
 
-        this._box = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
-                                  spacing: 6 });
         this._image = new Gtk.Image({ icon_name: 'media-optical-symbolic',
                                       pixel_size: 256 });
-        this._box.pack_start(this._image, false, false, 0);
+        this.pack_start(this._image, false, false, 0);
 
         let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
                                  spacing: 1,
                                  margin_top: 48,
                                  margin_start: 12,
                                  margin_end: 12 });
-        this._box.pack_start(vbox, false, false, 0);
+        this.pack_start(vbox, false, false, 0);
 
         this._titleLabel = new Gtk.Label();
         this._titleLabel.set_halign(Gtk.Align.START);
@@ -93,9 +93,7 @@ const AudioRenderer = new Lang.Class({
         this._albumLabel.set_halign(Gtk.Align.START);
         vbox.pack_start(this._albumLabel, false, false, 0);
 
-        this._box.show_all();
-
-        return this._box;
+        this.connect('destroy', this._onDestroy.bind(this));
     },
 
     _createPlayer : function(file) {
@@ -121,7 +119,7 @@ const AudioRenderer = new Lang.Class({
                                  Lang.bind(this, this._onCoverArtChanged)));
     },
 
-    clear : function(file) {
+    _onDestroy : function() {
         this._playerNotifies.forEach(Lang.bind(this,
             function(id) {
                 this._player.disconnect(id);
@@ -198,8 +196,6 @@ const AudioRenderer = new Lang.Class({
                                  Lang.bind(this, this._onCoverArtChanged));
 
         this._artFetcher.taglist = tags;
-
-        this._mainWindow.queue_allocate();
     },
 
     _updateProgressBar : function() {
@@ -251,11 +247,11 @@ const AudioRenderer = new Lang.Class({
     },
 
     getSizeForAllocation : function(allocation) {
-        let width = this._box.get_preferred_width();
-        let height = this._box.get_preferred_height();
+        let width = this.get_preferred_width()[1];
+        let height = this.get_preferred_height()[1];
 
         /* return the natural */
-        return [ width[1], height[1] ];
+        return [ width, height ];
     },
 
     populateToolbar : function (toolbar) {
diff --git a/src/js/viewers/evince.js b/src/js/viewers/evince.js
index 1c5ed9f..1833034 100644
--- a/src/js/viewers/evince.js
+++ b/src/js/viewers/evince.js
@@ -38,15 +38,17 @@ const Utils = imports.ui.utils;
 
 const EvinceRenderer = new Lang.Class({
     Name: 'EvinceRenderer',
+    Extends: Gtk.ScrolledWindow,
 
-    _init : function(args) {
-        EvDoc.init();
+    _init : function(file, mainWindow) {
+        this.parent({ visible: true });
+
+        this.set_min_content_width(Constants.VIEW_MIN);
+        this.set_min_content_height(Constants.VIEW_MIN);
 
         this.moveOnClick = false;
         this.canFullScreen = true;
-    },
 
-    render : function(file, mainWindow) {
         this._mainWindow = mainWindow;
         this._file = file;
 
@@ -55,16 +57,11 @@ const EvinceRenderer = new Lang.Class({
                                 Lang.bind(this, this._onDocumentLoaded));
         this._pdfLoader.uri = file.get_uri();
 
-        this._scrolledWin = new Gtk.ScrolledWindow();
-        this._scrolledWin.set_min_content_width(Constants.VIEW_MIN);
-        this._scrolledWin.set_min_content_height(Constants.VIEW_MIN);
-        this._scrolledWin.show();
-
         this._view = EvView.View.new();
         this._view.show();
-        this._scrolledWin.add(this._view);
+        this.add(this._view);
 
-        return this._scrolledWin;
+        this.connect('destroy', this._onDestroy.bind(this));
     },
 
     _updatePageLabel : function() {
@@ -135,13 +132,14 @@ const EvinceRenderer = new Lang.Class({
         toolbar.insert(toolbarZoom, -1);
     },
 
-    clear : function() {
+    _onDestroy : function() {
         this._pdfLoader = null;
     }
 });
 
 let handler = new MimeHandler.MimeHandler();
 
+EvDoc.init();
 let mimeTypes = Sushi.query_supported_document_types();
 handler.registerMimeTypes(mimeTypes, EvinceRenderer);
 
diff --git a/src/js/viewers/font.js b/src/js/viewers/font.js
index 666d9ac..1141ce9 100644
--- a/src/js/viewers/font.js
+++ b/src/js/viewers/font.js
@@ -33,24 +33,20 @@ const Sushi = imports.gi.Sushi;
 
 const FontRenderer = new Lang.Class({
     Name: 'FontRenderer',
+    Extends: Sushi.FontWidget,
+
+    _init : function(file, mainWindow) {
+        this.parent({ uri: file.get_uri(),
+                      visible: true })
 
-    _init : function(args) {
         this.moveOnClick = true;
         this.canFullScreen = true;
-    },
-
-    render : function(file, mainWindow) {
         this._file = file;
-
-        this._fontWidget = new Sushi.FontWidget({ uri: file.get_uri() });
-        this._fontWidget.show();
-
-        return this._fontWidget;
     },
 
     getSizeForAllocation : function(allocation) {
-        let size = [ this._fontWidget.get_preferred_size()[1].width,
-                     this._fontWidget.get_preferred_size()[1].height ];
+        let size = [ this.get_preferred_size()[1].width,
+                     this.get_preferred_size()[1].height ];
 
         if (size[0] > allocation[0])
             size[0] = allocation[0];
diff --git a/src/js/viewers/gst.js b/src/js/viewers/gst.js
index 48daa5f..d273ba2 100644
--- a/src/js/viewers/gst.js
+++ b/src/js/viewers/gst.js
@@ -33,40 +33,38 @@ const Utils = imports.ui.utils;
 
 const GstRenderer = new Lang.Class({
     Name: 'GstRenderer',
+    Extends: Sushi.MediaBin,
+
+    _init : function(file, mainWindow) {
+        this.parent({ uri: file.get_uri() });
 
-    _init : function(args) {
         this.moveOnClick = true;
         // fullscreen is handled internally by the widget
         this.canFullScreen = false;
-    },
 
-    render : function(file, mainWindow) {
-        this._player = new Sushi.MediaBin({ uri: file.get_uri() });
-        this._player.connect('size-change', function() {
+        this.connect('size-change', function() {
             mainWindow.resizeWindow();
         });
 
         this._autoplayId = GLib.idle_add(0, () => {
             this._autoplayId = 0;
-            this._player.play();
+            this.play();
             return false;
         });
 
-        return this._player;
+        this.connect('destroy', this._onDestroy.bind(this));
     },
 
-    clear : function() {
+    _onDestroy : function() {
         if (this._autoplayId > 0) {
             GLib.source_remove(this._autoplayId);
             this._autoplayId = 0;
-        } else {
-            this._player.stop();
         }
     },
 
     getSizeForAllocation : function(allocation) {
-        let baseSize = [this._player.get_preferred_width()[1],
-                        this._player.get_preferred_height()[1]];
+        let baseSize = [this.get_preferred_width()[1],
+                        this.get_preferred_height()[1]];
         return Utils.getScaledSize(baseSize, allocation, true);
     }
 });
diff --git a/src/js/viewers/html.js b/src/js/viewers/html.js
index 6360b9d..b3a3ca4 100644
--- a/src/js/viewers/html.js
+++ b/src/js/viewers/html.js
@@ -34,26 +34,22 @@ const Utils = imports.ui.utils;
 
 const HTMLRenderer = new Lang.Class({
     Name: 'HTMLRenderer',
+    Extends: WebKit.WebView,
+
+    _init : function(file, mainWindow) {
+        this.parent();
 
-    _init : function(args) {
         this.moveOnClick = false;
         this.canFullScreen = true;
-    },
 
-    render : function(file, mainWindow) {
         this._mainWindow = mainWindow;
         this._file = file;
 
-        this._webView = new WebKit.WebView();
-        this._webView.show_all();
-
         /* disable the default context menu of the web view */
-        this._webView.connect ("context-menu",
-                               function() {return true;});
-
-        this._webView.load_uri(file.get_uri());
+        this.connect('context-menu',
+                     function() {return true;});
 
-        return this._webView;
+        this.load_uri(file.get_uri());
     },
 
     getSizeForAllocation : function(allocation) {
diff --git a/src/js/viewers/image.js b/src/js/viewers/image.js
index 7194941..2fd18be 100644
--- a/src/js/viewers/image.js
+++ b/src/js/viewers/image.js
@@ -128,24 +128,24 @@ const Image = new Lang.Class({
 
 const ImageRenderer = new Lang.Class({
     Name: 'ImageRenderer',
+    Extends: Image,
+
+    _init : function(file, mainWindow) {
+        this.parent();
 
-    _init : function(args) {
         this._timeoutId = 0;
         this.moveOnClick = true;
         this.canFullScreen = true;
-    },
 
-    render : function(file, mainWindow) {
         this._mainWindow = mainWindow;
         this._file = file;
 
         this._createImageTexture(file);
-        return this._texture;
+
+        this.connect('destroy', this._onDestroy.bind(this));
     },
 
     _createImageTexture : function(file) {
-        this._texture = new Image();
-
         file.read_async
         (GLib.PRIORITY_DEFAULT, null,
          Lang.bind(this,
@@ -165,8 +165,7 @@ const ImageRenderer = new Lang.Class({
              let anim = GdkPixbuf.PixbufAnimation.new_from_stream_finish(res);
 
              this._iter = anim.get_iter(null);
-             let pix = this._iter.get_pixbuf().apply_embedded_orientation();
-             this._texture.pix = pix;
+             this.pix = this._iter.get_pixbuf().apply_embedded_orientation();
 
              if (!anim.is_static_image())
                  this._startTimeout();
@@ -183,11 +182,11 @@ const ImageRenderer = new Lang.Class({
     },
 
     getSizeForAllocation : function(allocation) {
-        if (!this._texture.pix)
+        if (!this.pix)
             return allocation;
 
-        let width = this._texture.pix.get_width();
-        let height = this._texture.pix.get_height();
+        let width = this.pix.get_width();
+        let height = this.pix.get_height();
         return Utils.getScaledSize([width, height], allocation, false);
     },
 
@@ -202,7 +201,7 @@ const ImageRenderer = new Lang.Class({
         toolbar.insert(toolbarZoom, 0);
     },
 
-    destroy : function () {
+    _onDestroy : function () {
         /* We should do the check here because it is possible
          * that we never created a source if our image is
          * not animated. */
@@ -215,7 +214,7 @@ const ImageRenderer = new Lang.Class({
     _advanceImage : function () {
         this._iter.advance(null);
         let pix = this._iter.get_pixbuf().apply_embedded_orientation();
-        this._texture.set_from_pixbuf(pix);
+        this.set_from_pixbuf(pix);
         return true;
     },
 });
diff --git a/src/js/viewers/text.js b/src/js/viewers/text.js
index a33fd7a..eaf035d 100644
--- a/src/js/viewers/text.js
+++ b/src/js/viewers/text.js
@@ -38,13 +38,13 @@ const Utils = imports.ui.utils;
 
 const TextRenderer = new Lang.Class({
     Name: 'TextRenderer',
+    Extends: Gtk.ScrolledWindow,
+
+    _init : function(file, mainWindow) {
+        this.parent();
 
-    _init : function(args) {
         this.moveOnClick = false;
         this.canFullScreen = true;
-    },
-
-    render : function(file, mainWindow) {
         this._mainWindow = mainWindow;
         this._file = file;
 
@@ -76,13 +76,7 @@ const TextRenderer = new Lang.Class({
             return false;
         }));
 
-        this._scrolledWin = new Gtk.ScrolledWindow();
-        this._scrolledWin.add(this._view);
-        this._scrolledWin.show_all();
-    },
-
-    render : function() {
-        return this._scrolledWin;
+        this.add(this._view);
     },
 
     _onBufferLoaded : function(loader, buffer) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]