[gnome-weather] Add a welcome screen for when there are no locations added



commit 5bd0b2a60ed08cbbb2a41348837ff47d980bf692
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sat Mar 16 00:28:17 2013 +0100

    Add a welcome screen for when there are no locations added
    
    Following the example of gnome-documents and gnome-clocks, add some
    placeholder text when the content view is empty.
    Then also tie the availability of the select button to the emptyness
    of the view.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=695852

 data/application.css |    5 +++
 src/window.js        |   46 +++++++++++++-----------
 src/world.js         |   96 +++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 125 insertions(+), 22 deletions(-)
---
diff --git a/data/application.css b/data/application.css
index fdc895e..1a17a2a 100644
--- a/data/application.css
+++ b/data/application.css
@@ -3,6 +3,11 @@
     icon-shadow: inset 1px 1px 3px black;
 }
 
+#weather-page-placeholder-title {
+    font-weight: bold;
+    font-size: 1.2em;
+}
+
 #weather-page-content-view {
     background-color: black;
     background-size: cover;
diff --git a/src/window.js b/src/window.js
index f2525a9..14eaeaf 100644
--- a/src/window.js
+++ b/src/window.js
@@ -56,8 +56,8 @@ const SelectionToolbar = new Lang.Class({
         this._box.add(button);
 
         button.connect('clicked', Lang.bind(this, function() {
-            let items = this._worldView.get_selection();
-            let model = this._worldView.get_model();
+            let items = this._worldView.iconView.get_selection();
+            let model = this._worldView.iconView.model;
 
             for (let i = items.length - 1; i >= 0; i--) {
                 let [res, iter] = model.get_iter(items[i]);
@@ -150,19 +150,20 @@ const MainWindow = new Lang.Class({
                                                 vexpand: true });
         this._stack.add(this._cityView);
 
-        this._worldView = new World.WorldView(this.application.model);
+        this._worldView = new World.WorldContentView(this.application.model, { visible: true });
+        let iconView = this._worldView.iconView;
         this._stack.add(this._worldView);
 
-        this._worldView.connect('item-activated', Lang.bind(this, this._itemActivated));
+        iconView.connect('item-activated', Lang.bind(this, this._itemActivated));
 
         select.connect('clicked', Lang.bind(this, function() {
-            this._worldView.selection_mode = true;
+            this._worldView.iconView.selection_mode = true;
         }));
         selectDone.connect('clicked', Lang.bind(this, function() {
-            this._worldView.selection_mode = false;
+            this._worldView.iconView.selection_mode = false;
         }));
-        this._worldView.connect('notify::selection-mode', Lang.bind(this, function() {
-            if (this._worldView.selection_mode) {
+        iconView.connect('notify::selection-mode', Lang.bind(this, function() {
+            if (iconView.selection_mode) {
                 this._header.get_style_context().add_class('selection-mode');
                 this._header.set_custom_title(this._selectionMenuButton);
             } else {
@@ -171,12 +172,15 @@ const MainWindow = new Lang.Class({
             }
         }));
 
-        this._worldView.bind_property('selection-mode', newButton, 'visible',
+        iconView.bind_property('selection-mode', newButton, 'visible',
+                               GObject.BindingFlags.INVERT_BOOLEAN);
+        iconView.bind_property('selection-mode', select, 'visible',
+                               GObject.BindingFlags.INVERT_BOOLEAN);
+        iconView.bind_property('selection-mode', selectDone, 'visible',
+                               GObject.BindingFlags.SYNC_CREATE);
+        this._worldView.bind_property('empty', select, 'sensitive',
+                                      GObject.BindingFlags.SYNC_CREATE |
                                       GObject.BindingFlags.INVERT_BOOLEAN);
-        this._worldView.bind_property('selection-mode', select, 'visible',
-                                      GObject.BindingFlags.INVERT_BOOLEAN);
-        this._worldView.bind_property('selection-mode', selectDone, 'visible',
-                                      GObject.BindingFlags.SYNC_CREATE);
 
         this._stack.set_visible_child(this._worldView);
 
@@ -187,8 +191,8 @@ const MainWindow = new Lang.Class({
         this._selectionToolbar = new SelectionToolbar(this._worldView);
         this._overlay.add_overlay(this._selectionToolbar);
 
-        this._worldView.connect('view-selection-changed', Lang.bind(this, function() {
-            let items = this._worldView.get_selection();
+        iconView.connect('view-selection-changed', Lang.bind(this, function() {
+            let items = iconView.get_selection();
             let label = _("Click on locations to select them");
 
             if (items.length > 0) {
@@ -255,8 +259,8 @@ const MainWindow = new Lang.Class({
     },
 
     _itemActivated: function(view, id, path) {
-        let [ok, iter] = this._worldView.model.get_iter(path);
-        let info = this._worldView.model.get_value(iter, World.Columns.INFO);
+        let [ok, iter] = view.model.get_iter(path);
+        let info = view.model.get_value(iter, World.Columns.INFO);
 
         this._cityView.info = info;
         this._stack.set_visible_child(this._cityView);
@@ -307,16 +311,16 @@ const MainWindow = new Lang.Class({
     },
 
     _exitSelectionMode: function() {
-        this._worldView.selection_mode = false;
+        this._worldView.iconView.selection_mode = false;
     },
 
     _selectAll: function() {
-        this._worldView.selection_mode = true;
-        this._worldView.select_all();
+        this._worldView.iconView.selection_mode = true;
+        this._worldView.iconView.select_all();
     },
 
     _selectNone: function() {
-        this._worldView.unselect_all();
+        this._worldView.iconView.unselect_all();
     },
 
     _showAbout: function() {
diff --git a/src/world.js b/src/world.js
index b5c4049..dd38da2 100644
--- a/src/world.js
+++ b/src/world.js
@@ -160,7 +160,7 @@ const WorldModel = new Lang.Class({
     },
 });
 
-const WorldView = new Lang.Class({
+const WorldIconView = new Lang.Class({
     Name: 'WorldView',
     Extends: Gd.MainView,
 
@@ -174,3 +174,97 @@ const WorldView = new Lang.Class({
         }));
     }
 });
+
+const WorldContentView = new Lang.Class({
+    Name: 'WorldContentView',
+    Extends: Gtk.Bin,
+    Properties: { 'empty': GObject.ParamSpec.boolean('empty', '', '', GObject.ParamFlags.READABLE, false) },
+
+    _init: function(model, params) {
+        params = Params.fill(params, { hexpand: true, vexpand: true,
+                                       halign: Gtk.Align.FILL, valign: Gtk.Align.FILL });
+        this.parent(params);
+
+        this.iconView = new WorldIconView(model, { visible: true });
+
+        this._placeHolder = new Gtk.Grid({ halign: Gtk.Align.CENTER,
+                                           valign: Gtk.Align.CENTER,
+                                           name: 'weather-page-placeholder',
+                                           column_spacing: 6 });
+        this._placeHolder.get_style_context().add_class('dim-label');
+
+        let iconGrid = new Gtk.Grid({ row_spacing: 4, column_spacing: 4 });
+        iconGrid.attach(new Gtk.Image({ icon_name: 'weather-overcast-symbolic',
+                                        icon_size: Gtk.IconSize.LARGE_TOOLBAR }),
+                        0, 0, 1, 1);
+        iconGrid.attach(new Gtk.Image({ icon_name: 'weather-few-clouds-symbolic',
+                                        icon_size: Gtk.IconSize.LARGE_TOOLBAR }),
+                        1, 0, 1, 1);
+        iconGrid.attach(new Gtk.Image({ icon_name: 'weather-clear-symbolic',
+                                        icon_size: Gtk.IconSize.LARGE_TOOLBAR }),
+                        0, 1, 1, 1);
+        iconGrid.attach(new Gtk.Image({ icon_name: 'weather-showers-symbolic',
+                                        icon_size: Gtk.IconSize.LARGE_TOOLBAR }),
+                        1, 1, 1, 1);
+
+        this._placeHolder.attach(iconGrid, 0, 0, 1, 2);
+
+        this._placeHolder.attach(new Gtk.Label({ name: 'weather-page-placeholder-title',
+                                                 label: _("Add locations"),
+                                                 xalign: 0.0 }),
+                                 1, 0, 1, 1);
+        this._placeHolder.attach(new Gtk.Label({ label: _("Use the <b>New</b> button on the toolbar to add 
more world locations"),
+                                                 use_markup: true,
+                                                 max_width_chars: 30,
+                                                 wrap: true,
+                                                 halign: Gtk.Align.START,
+                                                 valign: Gtk.Align.START }),
+                                 1, 1, 1, 1);
+        this._placeHolder.show_all();
+
+        this.model = model;
+        this._rowInsertedId = model.connect('row-inserted', Lang.bind(this, this._updateEmpty));
+        this._rowDeletedId = model.connect('row-deleted', Lang.bind(this, this._updateEmpty));
+
+        let [ok, ] = model.get_iter_first();
+        if (ok)
+            this.add(this.iconView);
+        else
+            this.add(this._placeHolder);
+        this._empty = !ok;
+    },
+
+    get empty() {
+        return this._empty;
+    },
+
+    vfunc_destroy: function() {
+        if (this._rowInsertedId) {
+            this.model.disconnect(this._rowInsertedId);
+            this._rowInsertedId = 0;
+        }
+        if (this._rowDeletedId) {
+            this.model.disconnect(this._rowDeletedId);
+            this._rowDeletedId = 0;
+        }
+
+        this.parent();
+    },
+
+    _updateEmpty: function() {
+        let [ok, iter] = this.model.get_iter_first();
+
+        if (!ok != this._empty) {
+            if (ok) {
+                this.remove(this._placeHolder);
+                this.add(this.iconView);
+            } else {
+                this.remove(this.iconView);
+                this.add(this._placeHolder);
+            }
+
+            this._empty = !ok;
+            this.notify('empty');
+        }
+    }
+});


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