[gnome-maps] Add search popup and use it to show search results
- From: Zeeshan Ali Khattak <zeeshanak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-maps] Add search popup and use it to show search results
- Date: Tue, 20 Aug 2013 12:08:50 +0000 (UTC)
commit 3cd8ce0e317c2d8c5012b94d380263853286ac39
Author: Jonas Danielsson <jonas threetimestwo org>
Date: Tue Aug 20 11:18:47 2013 +0200
Add search popup and use it to show search results
https://bugzilla.gnome.org/show_bug.cgi?id=706300
data/gnome-maps.css | 7 +++
src/Makefile-js.am | 3 +-
src/gnome-maps.gresource.xml | 1 +
src/main-window.ui | 3 +-
src/mainWindow.js | 67 ++++++++++++++---------------
src/mapView.js | 1 +
src/search-popup.ui | 22 ++++++++++
src/searchPopup.js | 95 ++++++++++++++++++++++++++++++++++++++++++
8 files changed, 162 insertions(+), 37 deletions(-)
---
diff --git a/data/gnome-maps.css b/data/gnome-maps.css
index c68f822..187f442 100644
--- a/data/gnome-maps.css
+++ b/data/gnome-maps.css
@@ -6,6 +6,13 @@
border-width: 0 1px 0 0;
}
+.search-popup {
+ border-style: solid;
+ border-width: 5px;
+ border-color: black;
+ border-radius: 6px 6px 6px 6px;
+}
+
.zoom-control {
background-color: transparent;
}
diff --git a/src/Makefile-js.am b/src/Makefile-js.am
index 53296db..90365a3 100644
--- a/src/Makefile-js.am
+++ b/src/Makefile-js.am
@@ -10,7 +10,8 @@ dist_js_DATA = \
utils.js \
userLocation.js \
geoclue.js \
- zoomControl.js
+ zoomControl.js \
+ searchPopup.js
BUILT_SOURCES += \
path.js \
diff --git a/src/gnome-maps.gresource.xml b/src/gnome-maps.gresource.xml
index ded3871..0265ec2 100644
--- a/src/gnome-maps.gresource.xml
+++ b/src/gnome-maps.gresource.xml
@@ -4,6 +4,7 @@
<file preprocess="xml-stripblanks">app-menu.ui</file>
<file preprocess="xml-stripblanks">main-window.ui</file>
<file preprocess="xml-stripblanks">zoom-control.ui</file>
+ <file preprocess="xml-stripblanks">search-popup.ui</file>
<file alias="application.css">../data/gnome-maps.css</file>
<file alias="zoom-in.png">../data/media/zoom-in.png</file>
<file alias="zoom-out.png">../data/media/zoom-out.png</file>
diff --git a/src/main-window.ui b/src/main-window.ui
index 3216a93..b7d833b 100644
--- a/src/main-window.ui
+++ b/src/main-window.ui
@@ -29,10 +29,9 @@
<class name="titlebar"/>
</style>
<child type="title">
- <object class="GtkComboBox" id="search-box">
+ <object class="GtkSearchEntry" id="search-entry">
<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 44376b2..1cd92f9 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -32,6 +32,7 @@ const Mainloop = imports.mainloop;
const Application = imports.application;
const MapView = imports.mapView;
+const SearchPopup = imports.searchPopup;
const Utils = imports.utils;
const Config = imports.config;
@@ -53,11 +54,11 @@ const MainWindow = new Lang.Class({
this._configureId = 0;
let ui = Utils.getUIObject('main-window', [ 'app-window',
'window-content',
- 'search-box',
+ 'search-entry',
'track-user-button']);
let grid = ui.windowContent,
toggle = ui.trackUserButton;
- this._searchBox = ui.searchBox;
+ this._searchEntry = ui.searchEntry;
this.window = ui.appWindow;
this.window.application = app;
@@ -70,23 +71,26 @@ const MainWindow = new Lang.Class({
this._initSignals();
this._restoreWindowGeometry();
- grid.add(this.mapView);
+ this._mapOverlay = new Gtk.Overlay({ visible: true });
+ this._mapOverlay.add(this.mapView);
+ this._mapOverlay.add_overlay(this._searchPopup);
+
+ grid.add(this._mapOverlay);
grid.show_all();
},
_initSearchWidgets: function() {
- this._searchEntry = new Gtk.SearchEntry();
- this._searchBox.add(this._searchEntry);
+ this._searchPopup = new SearchPopup.SearchPopup(this.window);
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();
+ this._searchPopup.setModel(model);
+ this._searchPopup.connect('selected',
+ this._onSearchPopupSelected.bind(this));
+ this.mapView.view.connect('button-press-event',
+ this._searchPopup.hide.bind(this._searchPopup));
},
_initActions: function() {
@@ -210,19 +214,12 @@ 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);
- } else {
- this._searchBox.model.clear();
- }
+ _onSearchPopupSelected: function(widget, iter) {
+ let model = this._searchPopup.getModel();
+ let location = model.get_value(iter, SearchResults.COL_LOCATION);
+
+ this.mapView.showLocation(location);
+ this._searchPopup.hide();
},
_onSearchActivate: function() {
@@ -235,23 +232,25 @@ const MainWindow = new Lang.Class({
},
_showSearchResults: function(places) {
- this._searchBox.model.clear();
+ let model = this._searchPopup.getModel();
- places.forEach((function(place) {
- let iter = this._searchBox.model.append();
+ model.clear();
+ places.forEach(function(place) {
+ let iter = 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._searchBox.popup();
+ let description_markup = '<b>' + location.description + '</b>';
+ model.set(iter,
+ [SearchResults.COL_DESCRIPTION,
+ SearchResults.COL_LOCATION],
+ [description_markup,
+ location]);
+ });
+ this._searchPopup.setModel(model);
+ this._searchPopup.show();
},
_quit: function() {
diff --git a/src/mapView.js b/src/mapView.js
index 2137eaf..cd59c14 100644
--- a/src/mapView.js
+++ b/src/mapView.js
@@ -59,6 +59,7 @@ const MapView = new Lang.Class({
this.actor = this.get_view();
this.view = this.actor;
this.view.set_zoom_level(3);
+ this.view.set_reactive(true);
this.view.connect('notify::latitude', this._onViewMoved.bind(this));
this.view.connect('notify::longitude', this._onViewMoved.bind(this));
diff --git a/src/search-popup.ui b/src/search-popup.ui
new file mode 100644
index 0000000..780ffc5
--- /dev/null
+++ b/src/search-popup.ui
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.10 -->
+ <object class="GtkFrame" id="frame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <style>
+ <class name="search-popup" />
+ </style>
+ <child>
+ <object class="GtkTreeView" id="treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="expand">True</property>
+ <property name="headers-visible">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection"/>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/src/searchPopup.js b/src/searchPopup.js
new file mode 100644
index 0000000..d8731fb
--- /dev/null
+++ b/src/searchPopup.js
@@ -0,0 +1,95 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * GNOME Maps 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 Maps 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 Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Jonas Danielsson <jonas threetimestwo org>
+ */
+
+const Gtk = imports.gi.Gtk;
+
+const Lang = imports.lang;
+const Utils = imports.utils;
+
+const Columns = {
+ TEXT: 0
+};
+
+const SearchPopup = new Lang.Class({
+ Name: 'SearchPopup',
+ Extends: Gtk.Bin,
+
+ _init: function (window) {
+ this.parent({ width_request: 500,
+ halign: Gtk.Align.CENTER,
+ valign: Gtk.Align.START,
+ margin_top: 10,
+ no_show_all: true,
+ visible: true });
+
+ let ui = Utils.getUIObject('search-popup', ['frame',
+ 'treeview',
+ 'treeview-selection']);
+ this._treeView = ui.treeview;
+ this._treeViewSelection = ui.treeviewSelection;
+ this._treeView.connect('button-press-event',
+ this._onListButtonPress.bind(this));
+ this._initList();
+
+ this.add(ui.frame);
+ this.hide();
+ },
+
+ _initList: function() {
+ let cell = new Gtk.CellRendererText({ xpad: 16,
+ ypad: 8 });
+ let column = new Gtk.TreeViewColumn();
+
+ this._treeView.append_column(column);
+ column.pack_start(cell, true);
+ column.add_attribute(cell, 'markup', Columns.TEXT);
+ },
+
+ _onListButtonPress: function(widget, event) {
+ let path_valid, path;
+ let bool, coordX, coordY;
+
+ [bool, coordX, coordY] = event.get_coords();
+ [path_valid, path] = this._treeView.get_path_at_pos(coordX, coordY,
+ null, null, null);
+ if (path_valid) {
+ let model = this.getModel();
+ let iter_valid, iter;
+
+ if (model === null)
+ return;
+
+ [iter_valid, iter] = model.get_iter(path);
+ if (!iter_valid)
+ return;
+
+ this.emit('selected', iter);
+ }
+ },
+
+ setModel: function(model) {
+ this._treeView.set_model(model);
+ },
+
+ getModel: function() {
+ return this._treeView.get_model();
+ },
+});
+Utils.addSignalMethods(SearchPopup.prototype);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]