[gnome-characters] window: Refactor spinner page using nested stack



commit d2eba58d14852cf3e64d1bef8eb50800f829f788
Author: Daiki Ueno <dueno src gnome org>
Date:   Fri Feb 13 16:31:45 2015 +0900

    window: Refactor spinner page using nested stack
    
    Suggested by Matthias Clasen in:
    https://mail.gnome.org/archives/gtk-devel-list/2014-December/msg00015.html

 data/{mainview.ui => characterlist.ui}       |    2 +-
 data/org.gnome.Characters.data.gresource.xml |    2 +-
 po/POTFILES.in                               |    2 +-
 src/characterList.js                         |  101 ++++++++++++++++++++
 src/window.js                                |  131 ++++----------------------
 5 files changed, 123 insertions(+), 115 deletions(-)
---
diff --git a/data/mainview.ui b/data/characterlist.ui
similarity index 97%
rename from data/mainview.ui
rename to data/characterlist.ui
index b08a0e0..6e48526 100644
--- a/data/mainview.ui
+++ b/data/characterlist.ui
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk+" version="3.12"/>
-  <template class="Gjs_MainView" parent="GtkStack">
+  <template class="Gjs_CharacterListView" parent="GtkStack">
     <property name="visible">True</property>
     <child>
       <object class="GtkGrid" id="search-banner-grid">
diff --git a/data/org.gnome.Characters.data.gresource.xml b/data/org.gnome.Characters.data.gresource.xml
index 41136b5..5ad4f21 100644
--- a/data/org.gnome.Characters.data.gresource.xml
+++ b/data/org.gnome.Characters.data.gresource.xml
@@ -3,8 +3,8 @@
   <gresource prefix="/org/gnome/Characters">
     <file preprocess="xml-stripblanks">app-menu.ui</file>
     <file preprocess="xml-stripblanks">mainwindow.ui</file>
-    <file preprocess="xml-stripblanks">mainview.ui</file>
     <file preprocess="xml-stripblanks">character.ui</file>
+    <file preprocess="xml-stripblanks">characterlist.ui</file>
     <file>application.css</file>
   </gresource>
 </gresources>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index b7b4941..da16fd5 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,7 +1,7 @@
 [type: gettext/glade]data/app-menu.ui
 [type: gettext/glade]data/character.ui
+[type: gettext/glade]data/characterlist.ui
 [type: gettext/glade]data/mainwindow.ui
-[type: gettext/glade]data/mainview.ui
 data/org.gnome.Characters.appdata.xml.in
 data/org.gnome.Characters.desktop.in
 data/org.gnome.Characters.gschema.xml
diff --git a/src/characterList.js b/src/characterList.js
index 7334103..00eb693 100644
--- a/src/characterList.js
+++ b/src/characterList.js
@@ -223,3 +223,104 @@ const CharacterListWidget = new Lang.Class({
         }
     }
 });
+
+const MAX_SEARCH_RESULTS = 100;
+
+const CharacterListView = new Lang.Class({
+    Name: 'CharacterListView',
+    Extends: Gtk.Stack,
+    Template: 'resource:///org/gnome/Characters/characterlist.ui',
+    InternalChildren: ['loading-banner-spinner'],
+
+    _init: function(params) {
+        let filtered = Params.filter(params, { characterList: null });
+        params = Params.fill(params, { hexpand: true, vexpand: true });
+        this.parent(params);
+
+        this._characterList = filtered.characterList;
+        let scroll = new Gtk.ScrolledWindow({
+            hscrollbar_policy: Gtk.PolicyType.NEVER
+        });
+        scroll.add(this._characterList);
+        this.add_named(scroll, 'character-list');
+
+        this._spinnerTimeoutId = 0;
+        this._cancellable = new Gio.Cancellable();
+    },
+
+    _startSearch: function() {
+        this._cancellable.cancel();
+        this._cancellable.reset();
+
+        this._spinnerTimeoutId =
+            GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000,
+                             Lang.bind(this, function () {
+                                 this._loading_banner_spinner.start();
+                                 this.visible_child_name = 'loading-banner';
+                                 this.show_all();
+                             }));
+    },
+
+    _finishSearch: function(result) {
+        if (this._spinnerTimeoutId > 0) {
+            GLib.source_remove(this._spinnerTimeoutId);
+            this._spinnerTimeoutId = 0;
+            this._loading_banner_spinner.stop();
+        }
+
+        let characters = [];
+        for (let index = 0; index < result.len; index++) {
+            characters.push(Gc.search_result_get(result, index));
+        }
+
+        this.setCharacters(characters)
+    },
+
+    setCharacters: function(characters) {
+        this._characterList.setCharacters(characters);
+        if (characters.length == 0) {
+            this.visible_child_name = 'search-banner';
+        } else {
+            this.visible_child_name = 'character-list';
+        }
+        this.show_all();
+    },
+
+    searchByCategory: function(category) {
+        this._startSearch();
+        Gc.search_by_category(
+            category.category,
+            -1,
+            this._cancellable,
+            Lang.bind(this,
+                      function(source_object, res, user_data) {
+                          try {
+                              let result = Gc.search_finish(res);
+                              this._finishSearch(result);
+                          } catch (e) {
+                              log("Failed to search by category: " + e);
+                          }
+                      }));
+    },
+
+    searchByKeywords: function(keywords) {
+        this._startSearch()
+        Gc.search_by_keywords(
+            keywords,
+            MAX_SEARCH_RESULTS,
+            this._cancellable,
+            Lang.bind(this, function(source_object, res, user_data) {
+                try {
+                    let result = Gc.search_finish(res);
+                    this._finishSearch(result);
+                } catch (e) {
+                    log("Failed to search by keywords: " + e);
+                }
+            }));
+    },
+
+    cancelSearch: function() {
+        this._cancellable.cancel();
+        this._finishSearch([]);
+    }
+});
diff --git a/src/window.js b/src/window.js
index 4e5100c..98d9564 100644
--- a/src/window.js
+++ b/src/window.js
@@ -40,8 +40,6 @@ const Gettext = imports.gettext;
 const Main = imports.main;
 const Util = imports.util;
 
-const MAX_SEARCH_RESULTS = 100;
-
 const MainWindow = new Lang.Class({
     Name: 'MainWindow',
     Extends: Gtk.ApplicationWindow,
@@ -122,7 +120,7 @@ const MainWindow = new Lang.Class({
         if (keywords != this._searchKeywords) {
             this._searchKeywords = keywords;
             if (this._searchKeywords.length > 0)
-                this._mainView.startSearch(this._searchKeywords);
+                this._mainView.searchByKeywords(this._searchKeywords);
             else
                 this._mainView.cancelSearch();
         }
@@ -181,8 +179,6 @@ const MainWindow = new Lang.Class({
 const MainView = new Lang.Class({
     Name: 'MainView',
     Extends: Gtk.Stack,
-    Template: 'resource:///org/gnome/Characters/mainview.ui',
-    InternalChildren: ['loading-banner-spinner'],
     Properties: {
         'max-recent-characters': GObject.ParamSpec.uint(
             'max-recent-characters', '', '',
@@ -210,23 +206,14 @@ const MainView = new Lang.Class({
         let characterList;
         for (let index in CategoryList.Category) {
             let category = CategoryList.Category[index];
-            characterList = this._createCharacterList();
-            characterList.get_accessible().accessible_name =
-                _('%s Character List').format(category.title);
-            this._characterListWidgets[category.name] = characterList;
-            this.add_titled(this._createScrolledWindow(characterList),
-                            category.name,
-                            category.title);
+            characterList = this._createCharacterList(
+                category.name, _('%s Character List').format(category.title));
+            this.add_titled(characterList, category.name, category.title);
         }
 
-        characterList = this._createCharacterList();
-        characterList.get_accessible().accessible_name =
-            _('Search Result Character List');
-        this.add_named(this._createScrolledWindow(characterList),
-                       'search-result');
-        this._characterListWidgets['search-result'] = characterList;
-
-        this._spinnerTimeoutId = 0;
+        characterList = this._createCharacterList(
+            'search-result', _('Search Result Character List'));
+        this.add_named(characterList, 'search-result');
 
         // FIXME: Can't use GSettings.bind with 'as' from Gjs
         let recentCharacters = Main.settings.get_value('recent-characters');
@@ -235,103 +222,36 @@ const MainView = new Lang.Class({
         Main.settings.bind('max-recent-characters', this,
                            'max-recent-characters',
                            Gio.SettingsBindFlags.DEFAULT);
-
-        this._cancellable = new Gio.Cancellable();
     },
 
-    _createCharacterList: function() {
+    _createCharacterList: function(name, accessible_name) {
         let widget = new CharacterList.CharacterListWidget({ hexpand: true,
                                                              vexpand: true });
         widget.connect('character-selected',
                        Lang.bind(this, this._handleCharacterSelected));
-        return widget;
-    },
-
-    _createScrolledWindow: function(widget) {
-        let scroll = new Gtk.ScrolledWindow({
-            hscrollbar_policy: Gtk.PolicyType.NEVER
-        });
-        scroll.add(widget);
-        return scroll;
-    },
-
-    _startSearch: function() {
-        this._cancellable.cancel();
-        this._cancellable.reset();
-
-        if (this.visible_child_name != 'search-banner' &&
-            this.visible_child_name != 'search-result')
-            this._lastPage = this.visible_child_name;
-
-        this._spinnerTimeoutId =
-            GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000,
-                             Lang.bind(this, function () {
-                                 this._loading_banner_spinner.start();
-                                 this.visible_child_name = 'loading-banner';
-                                 this.show_all();
-                             }));
-    },
-
-    _finishSearch: function(name, result) {
-        if (this._spinnerTimeoutId > 0) {
-            GLib.source_remove(this._spinnerTimeoutId);
-            this._spinnerTimeoutId = 0;
-            this._loading_banner_spinner.stop();
-        }
-
-        let characters = [];
-        for (let index = 0; index < result.len; index++) {
-            characters.push(Gc.search_result_get(result, index));
-        }
-
-        let characterList = this._characterListWidgets[name];
-        characterList.setCharacters(characters);
-
-        if (characters.length == 0) {
-            this.visible_child_name = 'search-banner';
-        } else {
-            this.visible_child_name = name;
-        }
-        this.show_all();
+        this._characterListWidgets[name] = widget;
+        widget.get_accessible().accessible_name = accessible_name;
+        return new CharacterList.CharacterListView({ characterList: widget });
     },
 
-    startSearch: function(keywords) {
-        this._startSearch();
-        Gc.search_by_keywords(
-            keywords,
-            MAX_SEARCH_RESULTS,
-            this._cancellable,
-            Lang.bind(this, function(source_object, res, user_data) {
-                try {
-                    let result = Gc.search_finish(res);
-                    this._finishSearch('search-result', result);
-                } catch (e) {
-                    log("Failed to search by keywords: " + e);
-                }
-            }));
+    searchByKeywords: function(keywords) {
+        this.visible_child_name = 'search-result';
+        this.visible_child.searchByKeywords(keywords);
     },
 
     cancelSearch: function() {
-        this._cancellable.cancel();
-        this._finishSearch('search-result', []);
-        if (this._lastPage)
-            this.visible_child_name = this._lastPage;
+        this.visible_child.cancelSearch();
     },
 
     setPage: function(name) {
         if (!(name in this._characterListWidgets))
             return;
 
+        this.visible_child_name = name;
+
         let characterList = this._characterListWidgets[name];
         if (name == 'recent') {
-            if (this._recentCharacters.length == 0)
-                this.visible_child_name = 'search-banner';
-            else {
-                characterList.setCharacters(this._recentCharacters);
-                characterList.show_all();
-                this.visible_child_name = name;
-            }
-            this.show_all();
+            this.visible_child.setCharacters(this._recentCharacters);
         } else {
             let category = null;
             for (let index in CategoryList.Category) {
@@ -341,20 +261,7 @@ const MainView = new Lang.Class({
             }
 
             Util.assertNotEqual(category, null);
-            this._startSearch();
-            Gc.search_by_category(
-                category.category,
-                -1,
-                this._cancellable,
-                Lang.bind(this,
-                          function(source_object, res, user_data) {
-                              try {
-                                  let result = Gc.search_finish(res);
-                                  this._finishSearch(name, result);
-                              } catch (e) {
-                                  log("Failed to search by category: " + e);
-                              }
-                          }));
+            this.visible_child.searchByCategory(category);
         }
     },
 


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