[gnome-maps] Make search results popup in a GtkComboBox



commit 24a2f3eec58aff94930c4287a97e5c0b9af6a9c1
Author: Jonas Danielsson <jonas threetimestwo org>
Date:   Thu Aug 1 09:38:30 2013 +0200

    Make search results popup in a GtkComboBox
    
    https://bugzilla.gnome.org/show_bug.cgi?id=698025

 src/main-window.ui |    3 +-
 src/mainWindow.js  |   65 ++++++++++++++++++++++++++++++++++++++++++++++++---
 src/mapView.js     |   39 ++++++++++--------------------
 3 files changed, 76 insertions(+), 31 deletions(-)
---
diff --git a/src/main-window.ui b/src/main-window.ui
index b7d833b..3216a93 100644
--- a/src/main-window.ui
+++ b/src/main-window.ui
@@ -29,9 +29,10 @@
           <class name="titlebar"/>
         </style>
         <child type="title">
-          <object class="GtkSearchEntry" id="search-entry">
+          <object class="GtkComboBox" id="search-box">
             <property name="visible">True</property>
             <property name="width_request">500</property>
+            <property name="has_entry">True</property>
           </object>
         </child>
         <child>
diff --git a/src/mainWindow.js b/src/mainWindow.js
index 4990cda..29b4b83 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -24,6 +24,7 @@
 const Gdk = imports.gi.Gdk;
 const GLib = imports.gi.GLib;
 const Gtk = imports.gi.Gtk;
+const GObject = imports.gi.GObject;
 const Champlain = imports.gi.Champlain;
 
 const Lang = imports.lang;
@@ -40,6 +41,11 @@ const _CONFIGURE_ID_TIMEOUT = 100; // msecs
 const _WINDOW_MIN_WIDTH = 600;
 const _WINDOW_MIN_HEIGHT = 500;
 
+const SearchResults = {
+    COL_DESCRIPTION:  0,
+    COL_LOCATION:     1
+};
+
 const MainWindow = new Lang.Class({
     Name: 'MainWindow',
 
@@ -47,11 +53,11 @@ const MainWindow = new Lang.Class({
         this._configureId = 0;
         let ui = Utils.getUIObject('main-window', [ 'app-window',
                                                     'window-content',
-                                                    'search-entry',
+                                                    'search-box',
                                                     'track-user-button']);
         let grid = ui.windowContent,
             toggle = ui.trackUserButton;
-        this._searchEntry = ui.searchEntry;
+        this._searchBox = ui.searchBox;
         this.window = ui.appWindow;
         this.window.application = app;
 
@@ -59,6 +65,7 @@ const MainWindow = new Lang.Class({
 
         this.mapView.gotoUserLocation(false);
 
+        this._initSearchWidgets();
         this._initActions();
         this._initSignals();
         this._restoreWindowGeometry();
@@ -68,6 +75,20 @@ const MainWindow = new Lang.Class({
         grid.show_all();
     },
 
+    _initSearchWidgets: function() {
+        this._searchEntry = new Gtk.SearchEntry();
+        this._searchBox.add(this._searchEntry);
+
+        let model = new Gtk.ListStore();
+        model.set_column_types([GObject.TYPE_STRING,
+                                GObject.TYPE_OBJECT]);
+        this._searchBox.model = model;
+        this._searchBox.entry_text_column = SearchResults.COL_DESCRIPTION;
+        this._searchBox.connect('changed',
+                                this._onSearchBoxChanged.bind(this));
+        this._searchBox.show_all();
+    },
+
     _initActions: function() {
         Utils.initActions(this.window, [
             {
@@ -189,10 +210,46 @@ const MainWindow = new Lang.Class({
         return false;
     },
 
+    _onSearchBoxChanged: function() {
+        let ret = this._searchBox.get_active_iter();
+        let is_set = ret[0];
+        let iter = ret[1];
+
+        if (is_set) {
+            let location =
+                this._searchBox.model.get_value(iter,
+                                                SearchResults.COL_LOCATION);
+            this.mapView.showLocation(location);
+        }
+    },
+
     _onSearchActivate: function() {
-        let string = this._searchEntry.get_text();
+        let searchString = this._searchEntry.get_text();
+
+        if (searchString.length > 0) {
+            this.mapView.geocodeSearch(searchString,
+                                       this._showSearchResults.bind(this));
+        }
+    },
+
+    _showSearchResults: function(places) {
+        this._searchBox.model.clear();
+
+        places.forEach((function(place) {
+            let iter = this._searchBox.model.append();
+            let location = place.get_location();
+
+            if (location == null)
+                return;
+
+            this._searchBox.model.set(iter,
+                                      [SearchResults.COL_DESCRIPTION,
+                                       SearchResults.COL_LOCATION],
+                                      [location.description,
+                                       location]);
+        }).bind(this));
 
-        this.mapView.geocodeSearch(string);
+        this._searchBox.popup();
     },
 
     _quit: function() {
diff --git a/src/mapView.js b/src/mapView.js
index 3783af1..2137eaf 100644
--- a/src/mapView.js
+++ b/src/mapView.js
@@ -93,25 +93,19 @@ const MapView = new Lang.Class({
         this.view.set_map_source(source);
     },
 
-    geocodeSearch: function(string) {
-        let forward = Geocode.Forward.new_for_string(string);
+    geocodeSearch: function(searchString, searchCompleteCallback) {
+        let forward = Geocode.Forward.new_for_string(searchString);
+        let places = [];
+
+        this._lastSearch = searchString;
         forward.search_async (null, (function(forward, res) {
             try {
-                let places = forward.search_finish(res);
-                log (places.length + " places found");
-                let mapLocations = [];
-                places.forEach((function(place) {
-                    let location = place.get_location();
-                    if (!location)
-                        return;
-
-                    let mapLocation = new MapLocation.MapLocation(location, this);
-                    mapLocations.push(mapLocation);
-                }).bind(this));
-                this._showLocations(mapLocations);
+                places = forward.search_finish(res);
             } catch (e) {
-                log ("Failed to search '" + string + "': " + e.message);
+                places = null;
             }
+            if (places !== null)
+                searchCompleteCallback(places);
         }).bind(this));
     },
 
@@ -153,19 +147,12 @@ const MapView = new Lang.Class({
         this.emit('user-location-changed');
     },
 
-    _showLocations: function(locations) {
-        if (locations.length === 0)
-            return;
+    showLocation: function(location) {
         this._markerLayer.remove_all();
+        let mapLocation = new MapLocation.MapLocation(location, this);
 
-        locations.forEach((function(location) {
-            location.show(this._markerLayer);
-        }).bind(this));
-
-        if (locations.length === 1)
-            locations[0].goTo(true);
-        else
-            this.ensureVisible(locations);
+        mapLocation.show(this._markerLayer);
+        mapLocation.goTo(true);
     },
 
     _onViewMoved: function() {


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