[gnome-documents] all: factor out the embedded child of MainWindow into a separate class



commit 82eeeb7a2053a96ddbdaf7dc104ac3c11430a433
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Tue Sep 6 14:35:13 2011 -0400

    all: factor out the embedded child of MainWindow into a separate class
    
    This allows us to avoid using a GtkClutterWindow as toplevel. Instead,
    create a GtkClutterEmbed manually only when we need to display the
    preview, and revert to a normal widget hierarchy when in the overview.

 src/Makefile-js.am |    1 +
 src/application.js |    1 +
 src/embed.js       |  361 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/global.js      |    1 +
 src/mainToolbar.js |   32 ++++-
 src/mainWindow.js  |  349 +++-----------------------------------------------
 src/preview.js     |   17 +++
 src/sidebar.js     |    9 +-
 src/windowMode.js  |   34 +++++-
 9 files changed, 472 insertions(+), 333 deletions(-)
---
diff --git a/src/Makefile-js.am b/src/Makefile-js.am
index 48c902f..eda1c2a 100644
--- a/src/Makefile-js.am
+++ b/src/Makefile-js.am
@@ -4,6 +4,7 @@ dist_js_DATA = \
     categories.js \
     changeMonitor.js \
     documents.js \
+    embed.js \
     error.js \
     errorBox.js \
     filterController.js \
diff --git a/src/application.js b/src/application.js
index 05b694d..e2a7b36 100644
--- a/src/application.js
+++ b/src/application.js
@@ -153,6 +153,7 @@ Application.prototype = {
                         Global.trackerController = new TrackerController.TrackerController();
                         Global.changeMonitor = new ChangeMonitor.TrackerChangeMonitor();
                         Global.modeController = new WindowMode.ModeController();
+                        Global.focusController = new WindowMode.FocusController();
 
                         this._mainWindow = new MainWindow.MainWindow();
                         this.activate();
diff --git a/src/embed.js b/src/embed.js
new file mode 100644
index 0000000..69062af
--- /dev/null
+++ b/src/embed.js
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2011 Red Hat, Inc.
+ *
+ * Gnome Documents is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Gnome Documents is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Gnome Documents; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Cosimo Cecchi <cosimoc redhat com>
+ *
+ */
+
+const Lang = imports.lang;
+const Mainloop = imports.mainloop;
+
+const ErrorBox = imports.errorBox;
+const Global = imports.global;
+const IconView = imports.iconView;
+const ListView = imports.listView;
+const LoadMore = imports.loadMore;
+const MainToolbar = imports.mainToolbar;
+const Preview = imports.preview;
+const SpinnerBox = imports.spinnerBox;
+const WindowMode = imports.windowMode;
+
+const Clutter = imports.gi.Clutter;
+const EvView = imports.gi.EvinceView;
+const Gdk = imports.gi.Gdk;
+const Gio = imports.gi.Gio;
+const Gtk = imports.gi.Gtk;
+const GtkClutter = imports.gi.GtkClutter;
+
+const _PDF_LOADER_TIMEOUT = 300;
+const _FULLSCREEN_TOOLBAR_TIMEOUT = 2;
+
+function ViewEmbed() {
+    this._init();
+}
+
+ViewEmbed.prototype  = {
+    _init: function() {
+        this._loaderCancellable = null;
+        this._loaderTimeout = 0;
+        this._motionTimeoutId = 0;
+        this._queryErrorId = 0;
+        this._viewSettingsId = 0;
+
+        this.widget = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL });
+
+        this._toolbar = new MainToolbar.MainToolbar();
+        this.widget.add(this._toolbar.widget);
+
+        Global.errorHandler.connect('load-error',
+                                    Lang.bind(this, this._onLoadError));
+
+        Global.modeController.connect('window-mode-changed',
+                                      Lang.bind(this, this._onWindowModeChanged));
+        Global.modeController.connect('fullscreen-changed',
+                                      Lang.bind(this, this._onFullscreenChanged));
+        this._onWindowModeChanged();
+    },
+
+    _onFullscreenChanged: function(controller, fullscreen) {
+        this._motionTimeoutId = 0;
+
+        if (fullscreen)
+            this._createFullscreenToolbar();
+        else
+            this._destroyFullscreenToolbar();
+
+        Gtk.Settings.get_default().gtk_application_prefer_dark_theme = fullscreen;
+        this._toolbar.widget.visible = !fullscreen;
+    },
+
+    _createFullscreenToolbar: function() {
+        this._fsToolbar = new MainToolbar.FullscreenToolbar();
+        this._fsToolbar.setModel(this._docModel, this._document);
+
+        this._stage.add_actor(this._fsToolbar.actor);
+
+        let vScrollbar = this._scrolledWin.get_vscrollbar();
+
+        let sizeConstraint = new Clutter.BindConstraint
+            ({ coordinate: Clutter.BindCoordinate.WIDTH,
+               source: this._stage,
+               offset: (vScrollbar.get_visible() ?
+                        (- (vScrollbar.get_preferred_width()[1])) : 0 ) });
+
+        // update the constraint size when the scrollbar changes visibility
+        vScrollbar.connect('notify::visible',
+            function() {
+                sizeConstraint.offset = (vScrollbar.get_visible() ?
+                                         (- (vScrollbar.get_preferred_width()[1])) : 0 );
+            });
+
+        this._fsToolbar.actor.add_constraint(sizeConstraint);
+    },
+
+    _destroyFullscreenToolbar: function() {
+        this._fsToolbar.destroy();
+        this._fsToolbar = null;
+    },
+
+    _onWindowModeChanged: function() {
+        let mode = Global.modeController.getWindowMode();
+
+        // destroy every child except for the main toolbar
+        this.widget.foreach(Lang.bind(this,
+            function(widget) {
+                if (widget != this._toolbar.widget)
+                    widget.destroy();
+            }));
+
+        if (mode == WindowMode.WindowMode.OVERVIEW)
+            this._prepareForOverview();
+        else
+            this._prepareForPreview();
+    },
+
+    _destroyScrollChild: function() {
+        let child = this._scrolledWin.get_child();
+        if (child)
+            child.destroy();
+    },
+
+    _initView: function() {
+        let isList = Global.settings.get_boolean('list-view');
+
+        this._destroyScrollChild();
+
+        if (isList)
+            this._view = new ListView.ListView(this);
+        else
+            this._view = new IconView.IconView(this);
+
+        this._view.connect('item-activated', Lang.bind(this, this._onViewItemActivated));
+        this._scrolledWin.add(this._view.widget);
+    },
+
+    _onViewItemActivated: function(view, urn) {
+        if (this._loaderTimeout != 0) {
+            Mainloop.source_remove(this._loaderTimeout);
+            this._loaderTimeout = 0;
+        }
+
+        let doc = Global.documentManager.lookupDocument(urn);
+        Global.documentManager.setActiveDocument(doc);
+
+        this._loaderTimeout = Mainloop.timeout_add(_PDF_LOADER_TIMEOUT,
+            Lang.bind(this, this._onPdfLoaderTimeout));
+
+        this._loaderCancellable = new Gio.Cancellable();
+        doc.loadPreview(this._loaderCancellable, Lang.bind(this, this._onDocumentLoaded));
+    },
+
+    _onPdfLoaderTimeout: function() {
+        this._loaderTimeout = 0;
+
+        Global.modeController.setWindowMode(WindowMode.WindowMode.PREVIEW);
+
+        let spinnerBox = new SpinnerBox.SpinnerBox();
+        this._scrolledWin.add_with_viewport(spinnerBox.widget);
+
+        return false;
+    },
+
+    _onDocumentLoaded: function(document) {
+        this._loaderCancellable = null;
+        let model = EvView.DocumentModel.new_with_document(document);
+
+        if (this._loaderTimeout) {
+            Mainloop.source_remove(this._loaderTimeout);
+            this._loaderTimeout = 0;
+        }
+
+        Global.modeController.setWindowMode(WindowMode.WindowMode.PREVIEW);
+        Global.modeController.setCanFullscreen(true);
+
+        this._preview = new Preview.PreviewView(model, document);
+
+        if (this._fsToolbar)
+            this._fsToolbar.setModel(model, document);
+
+        this._toolbar.setModel(model, document);
+
+        this._docModel = model;
+        this._document = document;
+
+        this._preview.widget.connect('motion-notify-event',
+                                     Lang.bind(this, this._fullscreenMotionHandler));
+
+        this._destroyScrollChild();
+        this._scrolledWin.add(this._preview.widget);
+    },
+
+    _fullscreenMotionHandler: function(widget, event) {
+        if (!Global.modeController.getFullscreen())
+            return false;
+
+        // if we were idle fade in the toolbar, otherwise reset
+        // the timeout
+        if (this._motionTimeoutId == 0)
+            this._fsToolbar.show();
+        else
+            Mainloop.source_remove(this._motionTimeoutId);
+
+        this._motionTimeoutId = Mainloop.timeout_add_seconds
+            (_FULLSCREEN_TOOLBAR_TIMEOUT, Lang.bind(this,
+                function() {
+                    this._motionTimeoutId = 0;
+
+                    if (this._fsToolbar)
+                        this._fsToolbar.hide();
+
+                    return false;
+            }));
+
+        return false;
+    },
+
+    _prepareForOverview: function() {
+        if (this._loaderCancellable) {
+            this._loaderCancellable.cancel();
+            this._loaderCancellable = null;
+        }
+
+        if (this._pdfLodaer)
+            this._pdfLoader = null;
+
+        if (this._preview) {
+            this._preview.destroy();
+            this._preview = null;
+        }
+
+        this._actor = null;
+        this._clutterEmbed = null;
+        this._docModel = null;
+        this._document = null;
+        this._stage = null;
+
+        Global.documentManager.setActiveDocument(null);
+
+        this._scrolledWin = new Gtk.ScrolledWindow({ hexpand: true,
+                                                     vexpand: true,
+                                                     shadow_type: Gtk.ShadowType.IN });
+        this._scrolledWin.get_style_context().set_junction_sides(Gtk.JunctionSides.BOTTOM);
+        this.widget.add(this._scrolledWin);
+
+        this._loadMore = new LoadMore.LoadMoreButton();
+        this.widget.add(this._loadMore.widget);
+
+        this._initView();
+
+        this._scrolledWin.vadjustment.connect('value-changed',
+                                              Lang.bind(this, this._onAdjustmentChange));
+        this._onAdjustmentChange(this._scrolledWin.vadjustment);
+
+        this._viewSettingsId =
+            Global.settings.connect('changed::list-view',
+                                    Lang.bind(this, this._initView));
+        this._queryErrorId =
+            Global.errorHandler.connect('query-error',
+                                        Lang.bind(this, this._onQueryError));
+
+        this.widget.show_all();
+    },
+
+    _onAdjustmentChange: function(adjustment) {
+        let end = (adjustment.value == (adjustment.upper - adjustment.get_page_size()));
+
+        // special case this values which happen at construction
+        if (adjustment.value == 0 &&
+            adjustment.upper == 1 &&
+            adjustment.get_page_size() == 1)
+            end = false;
+
+        if (end) {
+            if (!this._adjChangedId) {
+                this._loadMore.setBlock(false);
+
+                //wait for a changed event
+                this._adjChangedId = adjustment.connect('changed', Lang.bind(this,
+                    function(adjustment) {
+                        adjustment.disconnect(this._adjChangedId);
+                        this._adjChangedId = 0;
+
+                        this._loadMore.setBlock(true);
+                    }));
+            }
+        } else {
+            this._loadMore.setBlock(true);
+        }
+    },
+
+    _onQueryError: function(manager, message, exception) {
+        this._destroyScrollChild();
+
+        let errorBox = new ErrorBox.ErrorBox(message, exception.toString());
+        this._scrolledWin.add_with_viewport(errorBox.widget);
+    },
+
+    _prepareForPreview: function() {
+        this._view = null;
+
+        if (this._viewSettingsId != 0) {
+            Global.settings.disconnect(this._viewSettingsId);
+            this._viewSettingsId = 0;
+        }
+
+        if (this._queryErrorId != 0) {
+            Global.settings.disconnect(this._queryErrorId);
+            this._queryErrorId = 0;
+        }
+
+        this._clutterEmbed = new GtkClutter.Embed();
+        this.widget.add(this._clutterEmbed);
+
+        this._scrolledWin = new Gtk.ScrolledWindow({ hexpand: true,
+                                                     vexpand: true,
+                                                     shadow_type: Gtk.ShadowType.IN });
+        this._actor = new GtkClutter.Actor({ contents: this._scrolledWin });
+
+        this._stage = this._clutterEmbed.get_stage();
+        this._actor.add_constraint(
+            new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.WIDTH,
+                                         source: this._stage }));
+        this._actor.add_constraint(
+            new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.HEIGHT,
+                                         source: this._stage }));
+
+        this._stage.add_actor(this._actor);
+
+        this.widget.show_all();
+    },
+
+    _onLoadError: function(manager, message, exception) {
+        if (this._loaderTimeout != 0) {
+            Mainloop.source_remove(this._loaderTimeout);
+            this._loaderTimeout = 0;
+        }
+
+        this._loaderCancellable = null;
+        // FIXME: we need support for error codes in GJS
+        if (exception.toString().indexOf('Operation was cancelled') != -1)
+            return;
+
+        Global.modeController.setWindowMode(WindowMode.WindowMode.PREVIEW);
+
+        let errorBox = new ErrorBox.ErrorBox(message, exception.toString());
+        this._scrolledWin.add_with_viewport(errorBox.widget);
+    }
+};
diff --git a/src/global.js b/src/global.js
index 74fc9e1..3f2c710 100644
--- a/src/global.js
+++ b/src/global.js
@@ -24,6 +24,7 @@ let categoryManager = null;
 let connection = null;
 let documentManager = null;
 let errorHandler = null;
+let focusController = null;
 let goaClient = null;
 let modeController = null;
 let offsetController = null;
diff --git a/src/mainToolbar.js b/src/mainToolbar.js
index 87aec30..5ce0d1f 100644
--- a/src/mainToolbar.js
+++ b/src/mainToolbar.js
@@ -30,6 +30,7 @@ const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const Global = imports.global;
+const Tweener = imports.util.tweener;
 const WindowMode = imports.windowMode;
 
 const _SEARCH_ENTRY_TIMEOUT = 200;
@@ -42,6 +43,7 @@ MainToolbar.prototype = {
     _init: function() {
         this._model = null;
         this._document = null;
+        this._searchFocusId = 0;
         this._searchEntryTimeout = 0;
 
         this.widget = new Gtk.Toolbar({ icon_size: Gtk.IconSize.MENU });
@@ -54,9 +56,17 @@ MainToolbar.prototype = {
     },
 
     _clearToolbar: function() {
+        if (this._searchFocusId != 0) {
+            Global.focusController.disconnect(this._searchFocusId);
+            this._searchFocusId = 0;
+        }
+
         this.widget.foreach(Lang.bind(this, function(widget) {
             widget.destroy();
         }));
+
+        this._model = null;
+        this._document = null;
     },
 
     _populateForOverview: function() {
@@ -124,6 +134,12 @@ MainToolbar.prototype = {
             this._searchEntry.set_text('');
         }));
 
+        this._searchFocusId =
+            Global.focusController.connect('focus-search', Lang.bind(this,
+                function() {
+                    this._searchEntry.grab_focus();
+                }));
+
         this.widget.insert(item, 0);
         this.widget.insert(item2, 1);
 
@@ -205,7 +221,7 @@ MainToolbar.prototype = {
     },
 
     setModel: function(model, document) {
-        if (!this._model || !this._document)
+        if (!model || !document)
             return;
 
         this._model = model;
@@ -243,7 +259,17 @@ FullscreenToolbar.prototype = {
                                             opacity: 0 });
     },
 
-    destroy: function() {
-        this.widget.destroy();
+    show: function() {
+        Tweener.addTween(this.actor,
+                         { opacity: 255,
+                           time: 0.20,
+                           transition: 'easeOutQuad' });
+    },
+
+    hide: function() {
+        Tweener.addTween(this.actor,
+                         { opacity: 0,
+                           time: 0.20,
+                           transition: 'easeOutQuad' });
     }
 };
diff --git a/src/mainWindow.js b/src/mainWindow.js
index 6300f3c..439418b 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -19,30 +19,16 @@
  *
  */
 
-const Clutter = imports.gi.Clutter;
-const EvView = imports.gi.EvinceView;
-const Gd = imports.gi.Gd;
 const Gdk = imports.gi.Gdk;
-const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
-const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const GtkClutter = imports.gi.GtkClutter;
 
 const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
-const ErrorBox = imports.errorBox;
+const Embed = imports.embed;
 const Global = imports.global;
-const LoadMore = imports.loadMore;
-const MainToolbar = imports.mainToolbar;
 const Sidebar = imports.sidebar;
-const IconView = imports.iconView;
-const ListView = imports.listView;
-const Preview = imports.preview;
-const SpinnerBox = imports.spinnerBox;
-const TrackerUtils = imports.trackerUtils;
-const Tweener = imports.util.tweener;
 const WindowMode = imports.windowMode;
 
 const _ = imports.gettext.gettext;
@@ -50,49 +36,27 @@ const _ = imports.gettext.gettext;
 const _WINDOW_DEFAULT_WIDTH = 768;
 const _WINDOW_DEFAULT_HEIGHT = 600;
 
-const _PDF_LOADER_TIMEOUT = 300;
-
-const _FULLSCREEN_TOOLBAR_TIMEOUT = 2;
-
 function MainWindow() {
     this._init();
 }
 
 MainWindow.prototype = {
     _init: function() {
-        this._adjChangedId = 0;
-        this._docModel = null;
-        this._document = null;
-        this._fsToolbar = null;
-        this._pdfLoader = null;
-        this._fullscreen = false;
-        this._loaderCancellable = null;
-        this._loaderTimeout = 0;
-        this._lastFilter = '';
-        this._scrolledWindowId = 0;
-
-        this.window = new GtkClutter.Window({ type: Gtk.WindowType.TOPLEVEL,
+        this.window = new Gtk.Window({ type: Gtk.WindowType.TOPLEVEL,
                                        window_position: Gtk.WindowPosition.CENTER,
                                        title: _("Documents") });
 
+        Global.modeController.setWindowMode(WindowMode.WindowMode.OVERVIEW);
+
         this.window.set_size_request(_WINDOW_DEFAULT_WIDTH, _WINDOW_DEFAULT_HEIGHT);
         this.window.maximize();
         this.window.connect('delete-event',
                             Lang.bind(this, this._onDeleteEvent));
         this.window.connect('key-press-event',
                             Lang.bind(this, this._onKeyPressEvent));
-        this.window.connect('motion-notify-event',
-                            Lang.bind(this, this._fullscreenMotionHandler));
-
-        Global.settings.connect('changed::list-view',
-                                Lang.bind(this, this._refreshViewSettings));
-        Global.errorHandler.connect('query-error',
-                                    Lang.bind(this, this._onQueryError));
-        Global.errorHandler.connect('load-error',
-                                    Lang.bind(this, this._onLoadError));
 
-        Global.modeController.connect('window-mode-changed',
-                                      Lang.bind(this, this._onWindowModeChanged));
+        Global.modeController.connect('fullscreen-changed',
+                                      Lang.bind(this, this._onFullscreenChanged));
 
         this._grid = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL });
         this.window.add(this._grid);
@@ -100,24 +64,17 @@ MainWindow.prototype = {
         this._sidebar = new Sidebar.Sidebar();
         this._grid.add(this._sidebar.widget);
 
-        this._viewContainer = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL });
-        this._grid.add(this._viewContainer);
-
-        this._toolbar = new MainToolbar.MainToolbar();
-        this._viewContainer.add(this._toolbar.widget);
-
-        this._scrolledWin = new Gtk.ScrolledWindow({ hexpand: true,
-                                                     vexpand: true,
-                                                     shadow_type: Gtk.ShadowType.IN });
-        this._scrolledWin.get_style_context().set_junction_sides(Gtk.JunctionSides.BOTTOM);
-        this._viewContainer.add(this._scrolledWin);
-
-        this._loadMore = new LoadMore.LoadMoreButton();
-        this._viewContainer.add(this._loadMore.widget);
+        this._embed = new Embed.ViewEmbed();
+        this._grid.add(this._embed.widget);
 
         this._grid.show_all();
+    },
 
-        Global.modeController.setWindowMode(WindowMode.WindowMode.OVERVIEW);
+    _onFullscreenChanged: function(controller, fullscreen) {
+        if (fullscreen)
+            this.window.fullscreen();
+        else
+            this.window.unfullscreen();
     },
 
     _onKeyPressEvent: function(widget, event) {
@@ -130,20 +87,22 @@ MainWindow.prototype = {
             return true;
         }
 
-        if (this._windowMode == WindowMode.PREVIEW)
+        if (Global.modeController.getWindowMode() == WindowMode.WindowMode.PREVIEW)
             return this._handleKeyPreview(keyval, state);
         else
             return this._handleKeyOverview(keyval, state);
     },
 
     _handleKeyPreview: function(keyval, state) {
+        let fullscreen = Global.modeController.getFullscreen();
+
         if (keyval == Gdk.KEY_f) {
-            this._setFullscreen(!this._fullscreen);
+            Global.modeController.toggleFullscreen();
             return true;
         }
 
-        if (keyval == Gdk.KEY_Escape && this._fullscreen) {
-            this._setFullscreen(false);
+        if (keyval == Gdk.KEY_Escape && fullscreen) {
+            Global.modeController.setFullscreen(false);
             return true;
         }
 
@@ -160,280 +119,14 @@ MainWindow.prototype = {
             ((state & Gdk.ModifierType.CONTROL_MASK) != 0)) ||
             ((keyval == Gdk.KEY_s) &&
             ((state & Gdk.ModifierType.CONTROL_MASK) != 0))) {
-            this._toolbar.getSearchEntry().grab_focus();
+            Global.focusController.requestSearch();
             return true;
         }
 
         return false;
     },
 
-    _onAdjustmentChange: function(adjustment) {
-        let end = (adjustment.value == (adjustment.upper - adjustment.get_page_size()));
-
-        // special case this values which happen at construction
-        if (adjustment.value == 0 &&
-            adjustment.upper == 1 &&
-            adjustment.get_page_size() == 1)
-            end = false;
-
-        if (end) {
-            if (!this._adjChangedId) {
-                this._loadMore.setBlock(false);
-
-                //wait for a changed event
-                this._adjChangedId = adjustment.connect('changed', Lang.bind(this,
-                    function(adjustment) {
-                        adjustment.disconnect(this._adjChangedId);
-                        this._adjChangedId = 0;
-
-                        this._loadMore.setBlock(true);
-                    }));
-            }
-        } else {
-            this._loadMore.setBlock(true);
-        }
-    },
-
-    _destroyView: function() {
-        let child = this._scrolledWin.get_child();
-        if (child)
-            child.destroy();
-    },
-
-    _initView: function() {
-        let isList = Global.settings.get_boolean('list-view');
-
-        this._destroyView();
-
-        if (isList)
-            this.view = new ListView.ListView(this);
-        else
-            this.view = new IconView.IconView(this);
-
-        this.view.connect('item-activated', Lang.bind(this, this._onViewItemActivated));
-        this._scrolledWin.add(this.view.widget);
-    },
-
-    _refreshViewSettings: function() {
-        this._initView();
-    },
-
-    _onWindowModeChanged: function(controller, mode) {
-        if (mode == WindowMode.WindowMode.OVERVIEW)
-            this._prepareForOverview();
-        else
-            this._prepareForPreview();
-    },
-
-    _prepareForPreview: function(model, document) {
-        this._destroyView();
-        this._sidebar.widget.hide();
-
-        this._scrolledWin.vadjustment.disconnect(this._scrolledWindowId);
-    },
-
-    _prepareForOverview: function() {
-        if (this._loaderCancellable) {
-            this._loaderCancellable.cancel();
-            this._loaderCancellable = null;
-        }
-
-        if (this._pdfLodaer)
-            this._pdfLoader = null;
-
-        if (this._preview) {
-            this._preview.destroy();
-            this._preview = null;
-        }
-
-        this._docModel = null;
-        this._document = null;
-
-        Global.documentManager.setActiveDocument(null);
-
-        this._setFullscreen(false);
-
-        this._refreshViewSettings();
-        this._scrolledWindowId =
-            this._scrolledWin.vadjustment.connect('value-changed',
-                                                  Lang.bind(this, this._onAdjustmentChange));
-        this._onAdjustmentChange(this._scrolledWin.vadjustment);
-
-        this._sidebar.widget.show();
-    },
-
-    _createFullscreenToolbar: function() {
-        this._fsToolbar = new MainToolbar.FullscreenToolbar();
-        this._fsToolbar.setModel(this._docModel, this._document);
-
-        let vScrollbar = this._scrolledWin.get_vscrollbar();
-
-        let sizeConstraint = new Clutter.BindConstraint
-            ({ coordinate: Clutter.BindCoordinate.WIDTH,
-               source: this.window.get_stage(),
-               offset: (vScrollbar.get_visible() ?
-                        (- (vScrollbar.get_preferred_width()[1])) : 0 ) });
-        // update the constraint size when the scrollbar changes visibility
-        vScrollbar.connect('notify::visible',
-            function() {
-                sizeConstraint.offset = (vScrollbar.get_visible() ?
-                                         (- (vScrollbar.get_preferred_width()[1])) : 0 );
-            });
-
-        this._fsToolbar.actor.add_constraint(sizeConstraint);
-
-        this.window.get_stage().add_actor(this._fsToolbar.actor);
-    },
-
-    _destroyFullscreenToolbar: function() {
-        this._fsToolbar.destroy();
-        this._fsToolbar = null;
-    },
-
-    _setFullscreen: function(fullscreen) {
-        if (this._fullscreen == fullscreen)
-            return;
-
-        this._fullscreen = fullscreen;
-        this._motionTimeoutId = 0;
-
-        Gtk.Settings.get_default().gtk_application_prefer_dark_theme = this._fullscreen;
-        this._toolbar.widget.visible = !this._fullscreen;
-
-        if (this._fullscreen) {
-            this.window.fullscreen();
-            this._createFullscreenToolbar();
-        } else {
-            this._destroyFullscreenToolbar();
-            this.window.unfullscreen();
-        }
-    },
-
     _onDeleteEvent: function() {
         Global.application.quit();
-    },
-
-    _onViewItemActivated: function(view, urn) {
-        if (this._loaderTimeout != 0) {
-            Mainloop.source_remove(this._loaderTimeout);
-            this._loaderTimeout = 0;
-        }
-
-        let doc = Global.documentManager.lookupDocument(urn);
-        Global.documentManager.setActiveDocument(doc);
-
-        this._loaderTimeout = Mainloop.timeout_add(_PDF_LOADER_TIMEOUT,
-            Lang.bind(this, this._onPdfLoaderTimeout));
-
-        this._loaderCancellable = new Gio.Cancellable();
-        doc.loadPreview(this._loaderCancellable, Lang.bind(this, this._onDocumentLoaded));
-    },
-
-    _onPdfLoaderTimeout: function() {
-        this._loaderTimeout = 0;
-
-        Global.modeController.setWindowMode(WindowMode.WindowMode.PREVIEW);
-
-        let spinnerBox = new SpinnerBox.SpinnerBox();
-        this._scrolledWin.add_with_viewport(spinnerBox.widget);
-
-        return false;
-    },
-
-    _onDocumentLoaded: function(document) {
-        this._loaderCancellable = null;
-        let model = EvView.DocumentModel.new_with_document(document);
-
-        if (this._loaderTimeout) {
-            Mainloop.source_remove(this._loaderTimeout);
-            this._loaderTimeout = 0;
-        }
-
-        Global.modeController.setWindowMode(WindowMode.WindowMode.PREVIEW);
-        this._preview = new Preview.PreviewView(model, document);
-
-        if (this._fsToolbar)
-            this._fsToolbar.setModel(model, document);
-
-        this._toolbar.setModel(model, document);
-
-        this._docModel = model;
-        this._document = document;
-
-        this._preview.widget.connect('button-press-event',
-                                     Lang.bind(this, this._onPreviewButtonPressEvent));
-        this._preview.widget.connect('motion-notify-event',
-                                     Lang.bind(this, this._fullscreenMotionHandler));
-
-        this._destroyView();
-        this._scrolledWin.add(this._preview.widget);
-    },
-
-    _onPreviewButtonPressEvent: function(widget, event) {
-        let button = event.get_button()[1];
-        let clickCount = event.get_click_count()[1];
-
-        if (button == 1 && clickCount == 2) {
-            this._setFullscreen(!this._fullscreen);
-            return true;
-        }
-
-        return false;
-    },
-
-    _fullscreenMotionHandler: function(widget, event) {
-        if (!this._fullscreen)
-            return false;
-
-        // if we were idle fade in the toolbar, otherwise reset
-        // the timeout
-        if (this._motionTimeoutId == 0) {
-                Tweener.addTween(this._fsToolbar.actor,
-                                 { opacity: 255,
-                                   time: 0.20,
-                                   transition: 'easeOutQuad' });
-        } else {
-            Mainloop.source_remove(this._motionTimeoutId);
-        }
-
-        this._motionTimeoutId = Mainloop.timeout_add_seconds
-            (_FULLSCREEN_TOOLBAR_TIMEOUT, Lang.bind(this,
-                function() {
-                    this._motionTimeoutId = 0;
-
-                    if (this._fsToolbar)
-                        // fade out the toolbar
-                        Tweener.addTween(this._fsToolbar.actor,
-                                         { opacity: 0,
-                                         time: 0.20,
-                                         transition: 'easeOutQuad' });
-                    return false;
-            }));
-
-        return false;
-    },
-
-    _onLoadError: function(manager, message, exception) {
-        if (this._loaderTimeout != 0) {
-            Mainloop.source_remove(this._loaderTimeout);
-            this._loaderTimeout = 0;
-        }
-
-        this._loaderCancellable = null;
-        // FIXME: we need support for error codes in GJS
-        if (exception.toString().indexOf('Operation was cancelled') != -1)
-            return;
-
-        Global.modeController.setWindowMode(WindowMode.WindowMode.PREVIEW);
-
-        let errorBox = new ErrorBox.ErrorBox(message, exception.toString());
-        this._scrolledWin.add_with_viewport(errorBox.widget);
-    },
-
-    _onQueryError: function(manager, message, exception) {
-        this._destroyView();
-
-        let errorBox = new ErrorBox.ErrorBox(message, exception.toString());
-        this._scrolledWin.add_with_viewport(errorBox.widget);
     }
 };
diff --git a/src/preview.js b/src/preview.js
index 6f68e3d..fe1cc9c 100644
--- a/src/preview.js
+++ b/src/preview.js
@@ -24,6 +24,8 @@ const Gtk = imports.gi.Gtk;
 
 const Lang = imports.lang;
 
+const Global = imports.global;
+
 function PreviewView(model, document) {
     this._init(model, document);
 }
@@ -36,6 +38,21 @@ PreviewView.prototype = {
         this.widget = EvView.View.new();
         this.widget.set_model(this._model);
         this.widget.show();
+
+        this.widget.connect('button-press-event',
+                            Lang.bind(this, this._onButtonPressEvent));
+    },
+
+    _onButtonPressEvent: function(widget, event) {
+        let button = event.get_button()[1];
+        let clickCount = event.get_click_count()[1];
+
+        if (button == 1 && clickCount == 2) {
+            Global.modeController.toggleFullscreen();
+            return true;
+        }
+
+        return false;
     },
 
     destroy: function() {
diff --git a/src/sidebar.js b/src/sidebar.js
index b9ce9f7..059aed8 100644
--- a/src/sidebar.js
+++ b/src/sidebar.js
@@ -29,6 +29,7 @@ const Signals = imports.signals;
 
 const Global = imports.global;
 const Sources = imports.sources;
+const WindowMode = imports.windowMode;
 
 const _SIDEBAR_WIDTH_REQUEST = 240;
 
@@ -167,7 +168,9 @@ Sidebar.prototype = {
                                   Lang.bind(this, this._onSourcesButtonClicked));
 
         this.widget.set_current_page(_SIDEBAR_MAIN_PAGE);
-        this.widget.show_all();
+
+        Global.modeController.connect('window-mode-changed',
+                                      Lang.bind(this, this._onWindowModeChanged));
     },
 
     _onSourceClicked: function() {
@@ -176,5 +179,9 @@ Sidebar.prototype = {
 
     _onSourcesButtonClicked: function() {
         this.widget.set_current_page(_SIDEBAR_SOURCES_PAGE);
+    },
+
+    _onWindowModeChanged: function(controller, mode) {
+        this.widget.set_visible(mode == WindowMode.WindowMode.OVERVIEW);
     }
 };
diff --git a/src/windowMode.js b/src/windowMode.js
index 747fcc4..055dbf9 100644
--- a/src/windowMode.js
+++ b/src/windowMode.js
@@ -34,12 +34,16 @@ function ModeController() {
 ModeController.prototype = {
     _init: function() {
         this._mode = WindowMode.NONE;
+        this._fullscreen = false;
     },
 
     setWindowMode: function(mode) {
         if (this._mode == mode)
             return;
 
+        if (mode == WindowMode.OVERVIEW)
+            this.setCanFullscreen(false);
+
         this._mode = mode;
         this.emit('window-mode-changed', this._mode);
     },
@@ -48,6 +52,13 @@ ModeController.prototype = {
         return this._mode;
     },
 
+    setCanFullscreen: function(canFullscreen) {
+        this._canFullscreen = canFullscreen;
+
+        if (!this._canFullscreen && this._fullscreen)
+            this.setFullscreen(false);
+    },
+
     setFullscreen: function(fullscreen) {
         if (this._mode != WindowMode.PREVIEW)
             return;
@@ -55,8 +66,15 @@ ModeController.prototype = {
         if (this._fullscreen == fullscreen)
             return;
 
+        if (fullscreen && !this._canFullscreen)
+            return;
+
         this._fullscreen = fullscreen;
-        this.emit('fullscreen-changed');
+        this.emit('fullscreen-changed', this._fullscreen);
+    },
+
+    toggleFullscreen: function() {
+        this.setFullscreen(!this._fullscreen);
     },
 
     getFullscreen: function() {
@@ -64,3 +82,17 @@ ModeController.prototype = {
     }
 };
 Signals.addSignalMethods(ModeController.prototype);
+
+function FocusController() {
+    this._init();
+};
+
+FocusController.prototype = {
+    _init: function() {
+    },
+
+    requestSearch: function() {
+        this.emit('focus-search');
+    }
+};
+Signals.addSignalMethods(FocusController.prototype);



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