[gnome-documents/wip/split-view-2: 1/4] embed, view: Move the no-results page into the ViewContainer



commit 4f77c97271d4f1a7098a7fc81ad7301acba856ba
Author: Debarshi Ray <debarshir gnome org>
Date:   Fri Oct 17 15:25:30 2014 +0200

    embed, view: Move the no-results page into the ViewContainer
    
    With multiple views, it is simpler to give view its own no-results
    page, so that they can individually react to the presence or absence
    of items.
    
    Instead of listening to TrackerChangeMonitor, we use the
    OffsetController and we reset the item count as new items are added to
    ViewModel. This is useful because each view will have its own separate
    OffsetController and ViewModel to filter the global item set, while
    TrackerChangeMonitor has no such filtering and gets bombarded with
    every change in the tracker database.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=686461

 src/embed.js |  118 ------------------------------------------------------
 src/view.js  |  125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 122 insertions(+), 121 deletions(-)
---
diff --git a/src/embed.js b/src/embed.js
index 2056065..3643dd9 100644
--- a/src/embed.js
+++ b/src/embed.js
@@ -118,88 +118,6 @@ const ErrorBox = new Lang.Class({
     }
 });
 
-const EmptyResultsBox = new Lang.Class({
-    Name: 'EmptyResultsBox',
-
-    _init: function() {
-        this.widget = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL,
-                                     column_spacing: 12,
-                                     hexpand: true,
-                                     vexpand: true,
-                                     halign: Gtk.Align.CENTER,
-                                     valign: Gtk.Align.CENTER });
-        this.widget.get_style_context().add_class('dim-label');
-
-        this._image = new Gtk.Image({ pixel_size: 64,
-                                      icon_name: 'emblem-documents-symbolic' });
-        this.widget.add(this._image);
-
-        this._labelsGrid = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL,
-                                          row_spacing: 12 });
-        this.widget.add(this._labelsGrid);
-
-        let titleLabel = new Gtk.Label({ label: '<b><span size="large">' +
-                                         _("No Documents Found") +
-                                         '</span></b>',
-                                         use_markup: true,
-                                         halign: Gtk.Align.START,
-                                         vexpand: true });
-        this._labelsGrid.add(titleLabel);
-
-        if (Application.sourceManager.hasOnlineSources()) {
-            titleLabel.valign = Gtk.Align.CENTER;
-        } else {
-            titleLabel.valign = Gtk.Align.START;
-            this._addSystemSettingsLabel();
-        }
-
-        this.widget.show_all();
-    },
-
-    _addSystemSettingsLabel: function() {
-        let detailsStr =
-            // Translators: %s here is "Settings", which is in a separate string due to
-            // markup, and should be translated only in the context of this sentence
-            _("You can add your online accounts in %s").format(
-            " <a href=\"system-settings\">" +
-            // Translators: this should be translated in the context of the
-            // "You can add your online accounts in Settings" sentence above
-            _("Settings") +
-            "</a>");
-        let details = new Gtk.Label({ label: detailsStr,
-                                      use_markup: true,
-                                      halign: Gtk.Align.START,
-                                      xalign: 0,
-                                      max_width_chars: 24,
-                                      wrap: true });
-        this._labelsGrid.add(details);
-
-        details.connect('activate-link', Lang.bind(this,
-            function(label, uri) {
-                if (uri != 'system-settings')
-                    return false;
-
-                try {
-                    let app = Gio.AppInfo.create_from_commandline(
-                        'gnome-control-center online-accounts', null, 0);
-
-                    let screen = this.widget.get_screen();
-                    let display = screen ? screen.get_display() : Gdk.Display.get_default();
-                    let ctx = display.get_app_launch_context();
-
-                    if (screen)
-                        ctx.set_screen(screen);
-
-                    app.launch([], ctx);
-                } catch(e) {
-                    log('Unable to launch gnome-control-center: ' + e.message);
-                }
-
-                return true;
-            }));
-    }
-});
-
 const Embed = new Lang.Class({
     Name: 'Embed',
 
@@ -246,9 +164,6 @@ const Embed = new Lang.Class({
         this._errorBox = new ErrorBox();
         this._stack.add_named(this._errorBox.widget, 'error');
 
-        this._noResults = new EmptyResultsBox();
-        this._stack.add_named(this._noResults.widget, 'no-results');
-
         Application.modeController.connect('window-mode-changed',
                                            Lang.bind(this, this._onWindowModeChanged));
 
@@ -259,9 +174,6 @@ const Embed = new Lang.Class({
         Application.trackerController.connect('query-error',
                                               Lang.bind(this, this._onQueryError));
 
-        Application.offsetController.connect('item-count-changed',
-                                             Lang.bind(this, this._onItemCountChanged));
-
         Application.documentManager.connect('active-changed',
                                             Lang.bind(this, this._onActiveItemChanged));
         Application.documentManager.connect('load-started',
@@ -302,36 +214,6 @@ const Embed = new Lang.Class({
         }
     },
 
-    _hideNoResultsPage: function() {
-        if (this._noResultsChangeId != 0) {
-            Application.changeMonitor.disconnect(this._noResultsChangeId);
-            this._noResultsChangeId = 0;
-        }
-
-        this._stack.set_visible_child_name('view');
-    },
-
-    _onItemCountChanged: function() {
-        let windowMode = Application.modeController.getWindowMode();
-        if (windowMode != WindowMode.WindowMode.OVERVIEW)
-            return;
-
-        let itemCount = Application.offsetController.getItemCount();
-
-        if (itemCount == 0) {
-            // also listen to changes-pending while in this mode
-            this._noResultsChangeId =
-                Application.changeMonitor.connect('changes-pending', Lang.bind(this,
-                    function() {
-                        this._hideNoResultsPage();
-                    }));
-
-            this._stack.set_visible_child_name('no-results');
-        } else {
-            this._hideNoResultsPage();
-        }
-    },
-
     _onQueryError: function(manager, message, exception) {
         this._setError(message, exception.message);
     },
diff --git a/src/view.js b/src/view.js
index c84424b..ff97e83 100644
--- a/src/view.js
+++ b/src/view.js
@@ -105,6 +105,8 @@ const LoadMoreButton = new Lang.Class({
     }
 });
 
+const _RESET_COUNT_TIMEOUT = 500; // msecs
+
 const ViewModel = new Lang.Class({
     Name: 'ViewModel',
 
@@ -121,6 +123,8 @@ const ViewModel = new Lang.Class({
         this.model.set_sort_column_id(Gd.MainColumns.MTIME,
                                       Gtk.SortType.DESCENDING);
 
+        this._resetCountId = 0;
+
         Application.documentManager.connect('item-added',
             Lang.bind(this, this._onItemAdded));
         Application.documentManager.connect('item-removed',
@@ -145,6 +149,11 @@ const ViewModel = new Lang.Class({
     },
 
     _onItemAdded: function(source, doc) {
+        // Update the count so that OffsetController has the correct
+        // values. Otherwise things like the "Load More" button and "No
+        // Results" page will not work correctly.
+        this._resetCount();
+
         let iter = this.model.append();
         this.model.set(iter,
             [ 0, 1, 2, 3, 4, 5 ],
@@ -181,6 +190,99 @@ const ViewModel = new Lang.Class({
 
                 return false;
             }));
+    },
+
+    _resetCount: function() {
+        if (this._resetCountId == 0) {
+            this._resetCountId = Mainloop.timeout_add(_RESET_COUNT_TIMEOUT, Lang.bind(this,
+                function() {
+                    this._resetCountId = 0;
+                    Application.offsetController.resetItemCount();
+                    return false;
+                }));
+        }
+    }
+});
+
+const EmptyResultsBox = new Lang.Class({
+    Name: 'EmptyResultsBox',
+
+    _init: function() {
+        this.widget = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL,
+                                     column_spacing: 12,
+                                     hexpand: true,
+                                     vexpand: true,
+                                     halign: Gtk.Align.CENTER,
+                                     valign: Gtk.Align.CENTER });
+        this.widget.get_style_context().add_class('dim-label');
+
+        this._image = new Gtk.Image({ pixel_size: 64,
+                                      icon_name: 'emblem-documents-symbolic' });
+        this.widget.add(this._image);
+
+        this._labelsGrid = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL,
+                                          row_spacing: 12 });
+        this.widget.add(this._labelsGrid);
+
+        let titleLabel = new Gtk.Label({ label: '<b><span size="large">' +
+                                         _("No Documents Found") +
+                                         '</span></b>',
+                                         use_markup: true,
+                                         halign: Gtk.Align.START,
+                                         vexpand: true });
+        this._labelsGrid.add(titleLabel);
+
+        if (Application.sourceManager.hasOnlineSources()) {
+            titleLabel.valign = Gtk.Align.CENTER;
+        } else {
+            titleLabel.valign = Gtk.Align.START;
+            this._addSystemSettingsLabel();
+        }
+
+        this.widget.show_all();
+    },
+
+    _addSystemSettingsLabel: function() {
+        let detailsStr =
+            // Translators: %s here is "Settings", which is in a separate string due to
+            // markup, and should be translated only in the context of this sentence
+            _("You can add your online accounts in %s").format(
+            " <a href=\"system-settings\">" +
+            // Translators: this should be translated in the context of the
+            // "You can add your online accounts in Settings" sentence above
+            _("Settings") +
+            "</a>");
+        let details = new Gtk.Label({ label: detailsStr,
+                                      use_markup: true,
+                                      halign: Gtk.Align.START,
+                                      xalign: 0,
+                                      max_width_chars: 24,
+                                      wrap: true });
+        this._labelsGrid.add(details);
+
+        details.connect('activate-link', Lang.bind(this,
+            function(label, uri) {
+                if (uri != 'system-settings')
+                    return false;
+
+                try {
+                    let app = Gio.AppInfo.create_from_commandline(
+                        'gnome-control-center online-accounts', null, 0);
+
+                    let screen = this.widget.get_screen();
+                    let display = screen ? screen.get_display() : Gdk.Display.get_default();
+                    let ctx = display.get_app_launch_context();
+
+                    if (screen)
+                        ctx.set_screen(screen);
+
+                    app.launch([], ctx);
+                } catch(e) {
+                    log('Unable to launch gnome-control-center: ' + e.message);
+                }
+
+                return true;
+            }));
     }
 });
 
@@ -194,14 +296,23 @@ const ViewContainer = new Lang.Class({
 
         this._model = new ViewModel();
 
-        this.widget = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL });
+        this.widget = new Gtk.Stack({ homogeneous: true,
+                                      transition_type: Gtk.StackTransitionType.CROSSFADE });
+
+        let grid = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL });
+        this.widget.add_named(grid, 'view');
+
+        this._noResults = new EmptyResultsBox();
+        this.widget.add_named(this._noResults.widget, 'no-results');
+
         this.view = new Gd.MainView({ shadow_type: Gtk.ShadowType.NONE });
-        this.widget.add(this.view);
+        grid.add(this.view);
 
         this._loadMore = new LoadMoreButton();
-        this.widget.add(this._loadMore.widget);
+        grid.add(this._loadMore.widget);
 
         this.widget.show_all();
+        this.widget.set_visible_child_full('view', Gtk.StackTransitionType.NONE);
 
         this.view.connect('item-activated',
                             Lang.bind(this, this._onItemActivated));
@@ -236,6 +347,14 @@ const ViewContainer = new Lang.Class({
                 this.view.unselect_all();
             }));
 
+        Application.offsetController.connect('item-count-changed', Lang.bind(this,
+            function(controller, count) {
+                if (count == 0)
+                    this.widget.set_visible_child_name('no-results');
+                else
+                    this.widget.set_visible_child_name('view');
+            }));
+
         this._queryId = Application.trackerController.connect('query-status-changed',
             Lang.bind(this, this._onQueryStatusChanged));
         // ensure the tracker controller is started


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