[gnome-maps] Convert SearchPopup to GtkListBox
- From: Jonas Danielsson <jonasdn src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-maps] Convert SearchPopup to GtkListBox
- Date: Fri, 21 Nov 2014 06:43:11 +0000 (UTC)
commit 11320aa33f9a2f1b17ca4558efe7af2dcd32bc90
Author: Jonas Danielsson <jonas danielsson threetimestwo org>
Date: Fri Nov 14 03:26:23 2014 -0500
Convert SearchPopup to GtkListBox
src/gnome-maps.data.gresource.xml | 1 +
src/placeEntry.js | 13 ++-
src/placeFormatter.js | 8 ++
src/search-popup-row.ui | 73 ++++++++++++++++++
src/search-popup.ui | 80 +++++++------------
src/searchPopup.js | 152 ++++++++++++++++---------------------
src/sidebar.js | 3 +-
7 files changed, 189 insertions(+), 141 deletions(-)
---
diff --git a/src/gnome-maps.data.gresource.xml b/src/gnome-maps.data.gresource.xml
index 450e6d1..5af82f8 100644
--- a/src/gnome-maps.data.gresource.xml
+++ b/src/gnome-maps.data.gresource.xml
@@ -6,6 +6,7 @@
<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 preprocess="xml-stripblanks">search-popup-row.ui</file>
<file preprocess="xml-stripblanks">sidebar.ui</file>
<file preprocess="xml-stripblanks">context-menu.ui</file>
<file preprocess="xml-stripblanks">layers-popover.ui</file>
diff --git a/src/placeEntry.js b/src/placeEntry.js
index cb57a28..409bc17 100644
--- a/src/placeEntry.js
+++ b/src/placeEntry.js
@@ -79,7 +79,7 @@ const PlaceEntry = new Lang.Class({
},
_init: function(props) {
- let numVisible = props.num_visible || 10;
+ let numVisible = props.num_visible || 6;
delete props.num_visible;
this._mapView = props.mapView;
delete props.mapView;
@@ -88,13 +88,16 @@ const PlaceEntry = new Lang.Class({
props.primary_icon_name = null;
delete props.loupe;
+ let maxChars = props.maxChars;
+ delete props.maxChars;
+
let parseOnFocusOut = props.parseOnFocusOut;
delete props.parseOnFocusOut;
props.completion = this._createCompletion();
this.parent(props);
- this._popover = this._createPopover(numVisible);
+ this._popover = this._createPopover(numVisible, maxChars);
this.connect('activate', this._onActivate.bind(this));
this.connect('search-changed', (function() {
@@ -127,11 +130,11 @@ const PlaceEntry = new Lang.Class({
return completion;
},
- _createPopover: function(numVisible) {
+ _createPopover: function(numVisible, maxChars) {
let popover = new SearchPopup.SearchPopup({ num_visible: numVisible,
relative_to: this,
- no_show_all: true,
- visible: true });
+ maxChars: maxChars});
+
this.connect('size-allocate', (function(widget, allocation) {
// Magic number to make the alignment pixel perfect.
let width_request = allocation.width + 20;
diff --git a/src/placeFormatter.js b/src/placeFormatter.js
index 6209241..895a762 100644
--- a/src/placeFormatter.js
+++ b/src/placeFormatter.js
@@ -56,6 +56,14 @@ const PlaceFormatter = new Lang.Class({
return this._rows;
},
+ getDetailsString: function() {
+ return this.rows.map((function(row) {
+ return row.map((function(prop) {
+ return this._place[prop];
+ }).bind(this)).join(', ');
+ }).bind(this)).join(', ');
+ },
+
_update: function() {
switch (this._place.place_type) {
case Geocode.PlaceType.COUNTRY:
diff --git a/src/search-popup-row.ui b/src/search-popup-row.ui
new file mode 100644
index 0000000..32d5519
--- /dev/null
+++ b/src/search-popup-row.ui
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface>
+ <requires lib="gtk+" version="3.12"/>
+ <template class="Gjs_SearchPopupRow" parent="GtkListBoxRow">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkGrid" id="grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="margin-bottom">5</property>
+ <child>
+ <object class="GtkImage" id="icon">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="margin_end">10</property>
+ <property name="pixel_size">32</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="height">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="typeIcon">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="margin_start">10</property>
+ <property name="pixel_size">32</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="height">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="name">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="details">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="use_markup">True</property>
+ <property name="ellipsize">end</property>
+ <style>
+ <class name="subtitle"/>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/search-popup.ui b/src/search-popup.ui
index 1ddfb17..a768c89 100644
--- a/src/search-popup.ui
+++ b/src/search-popup.ui
@@ -1,68 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.10 -->
- <object class="GtkStack" id="stack">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="transition-type">crossfade</property>
+ <template class="Gjs_SearchPopup" parent="GtkPopover">
+ <property name="visible">False</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">False</property>
<style>
- <class name="maps-stack"/>
+ <class name="maps-popover"/>
</style>
<child>
- <object class="GtkScrolledWindow" id="scrolled-window">
+ <object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="hscrollbar_policy">never</property>
- <property name="shadow_type">in</property>
+ <property name="transition-type">crossfade</property>
+ <style>
+ <class name="maps-stack"/>
+ </style>
<child>
- <object class="GtkTreeView" id="treeview">
+ <object class="GtkScrolledWindow" id="scrolledWindow">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="expand">True</property>
- <property name="headers-visible">False</property>
- <property name="hover-selection">True</property>
- <property name="activate-on-single-click">True</property>
- <child internal-child="selection">
- <object class="GtkTreeSelection" id="treeview-selection"/>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="icon-column">
- <child>
- <object class="GtkCellRendererPixbuf" id="icon-cell">
- <property name="xpad">2</property>
- </object>
- <attributes>
- <attribute name="pixbuf">0</attribute>
- </attributes>
- </child>
- </object>
- </child>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
<child>
- <object class="GtkTreeViewColumn" id="text-column">
- <child>
- <object class="GtkCellRendererText" id="text-cell">
- <property name="xpad">4</property>
- <property name="ypad">4</property>
- </object>
- <attributes>
- <attribute name="markup">2</attribute>
- </attributes>
- </child>
+ <object class="GtkListBox" id="list">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="expand">True</property>
+ <property name="activate_on_single_click">True</property>
</object>
</child>
</object>
</child>
+ <child>
+ <object class="GtkSpinner" id="spinner">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="width_request">16</property>
+ <property name="height_request">16</property>
+ </object>
+ </child>
</object>
</child>
- <child>
- <object class="GtkSpinner" id="spinner">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">center</property>
- <property name="valign">center</property>
- <property name="width_request">16</property>
- <property name="height_request">16</property>
- </object>
- </child>
- </object>
+ </template>
</interface>
diff --git a/src/searchPopup.js b/src/searchPopup.js
index 3517622..d793726 100644
--- a/src/searchPopup.js
+++ b/src/searchPopup.js
@@ -24,15 +24,54 @@ const GdkPixbuf = imports.gi.GdkPixbuf;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
+const PlaceFormatter = imports.placeFormatter;
const Utils = imports.utils;
-const Columns = {
- ICON: 0,
- PLACE: 1,
- DESCRIPTION: 2
-};
-
const _PLACE_ICON_SIZE = 20;
+const _ROW_HEIGHT = 50;
+
+const SearchPopupRow = new Lang.Class({
+ Name: 'SearchPopupRow',
+ Extends: Gtk.ListBoxRow,
+ Template: 'resource:///org/gnome/maps/search-popup-row.ui',
+ InternalChildren: [ 'icon',
+ 'name',
+ 'details' ],
+
+ _init: function(params) {
+ this.place = params.place;
+ delete params.place;
+
+ let searchString = params.searchString;
+ delete params.searchString;
+
+ let maxChars = params.maxChars || 40;
+ delete params.maxChars;
+
+ params.height_request = _ROW_HEIGHT;
+ this.parent(params);
+
+ let formatter = new PlaceFormatter.PlaceFormatter(this.place);
+ let title = GLib.markup_escape_text(formatter.title, -1);
+
+ this._name.label = this._boldMatch(title, searchString);
+ this._details.max_width_chars = maxChars;
+ this._details.label = formatter.getDetailsString();
+ this._icon.gicon = this.place.icon;
+ },
+
+ _boldMatch: function(title, string) {
+ string = string.toLowerCase();
+
+ let index = title.toLowerCase().indexOf(string);
+
+ if (index !== -1) {
+ let substring = title.substring(index, index + string.length);
+ title = title.replace(substring, substring.bold());
+ }
+ return title;
+ }
+});
const SearchPopup = new Lang.Class({
Name: 'SearchPopup',
@@ -40,52 +79,27 @@ const SearchPopup = new Lang.Class({
Signals : {
'selected' : { param_types: [ GObject.TYPE_OBJECT ] }
},
+ Template: 'resource:///org/gnome/maps/search-popup.ui',
+ InternalChildren: [ 'scrolledWindow',
+ 'stack',
+ 'spinner',
+ 'list' ],
_init: function(props) {
- this._numVisible = props.num_visible;
+ let numVisible = props.num_visible;
delete props.num_visible;
- let ui = Utils.getUIObject('search-popup', ['scrolled-window',
- 'stack',
- 'spinner',
- 'treeview',
- 'text-column',]);
- this._stack = ui.stack;
- this._scrolledWindow = ui.scrolledWindow;
- this._spinner = ui.spinner;
- this._treeView = ui.treeview;
-
- let model = new Gtk.ListStore();
- model.set_column_types([GdkPixbuf.Pixbuf,
- GObject.TYPE_OBJECT,
- GObject.TYPE_STRING]);
- this._treeView.model = model;
-
- this._treeView.connect('row-activated',
- this._onRowActivated.bind(this));
- let cellHeight = ui.textColumn.cell_get_size(null)[3];
- this.height_request = cellHeight * this._numVisible;
- this._scrolledWindow.set_min_content_height(this.height_request);
+ this._maxChars = props.maxChars;
+ delete props.maxChars;
this.parent(props);
- this.get_style_context().add_class('maps-popover');
- this.add(this._stack);
- this.hide();
- },
-
- _onRowActivated: function(widget, path, column) {
- let model = this._treeView.model;
- let iter_valid, iter;
-
- if (model === null)
- return;
-
- [iter_valid, iter] = model.get_iter(path);
- if (!iter_valid)
- return;
+ this._list.connect('row-activated', (function(list, row) {
+ if (row)
+ this.emit('selected', row.place);
+ }).bind(this));
- this.emit('selected', model.get_value(iter, Columns.PLACE));
+ this._scrolledWindow.min_content_height = numVisible * _ROW_HEIGHT;
},
showSpinner: function() {
@@ -105,12 +119,7 @@ const SearchPopup = new Lang.Class({
if (!this.get_visible())
this.show();
- this._treeView.grab_focus();
- },
-
- vfunc_show: function() {
- this._treeView.columns_autosize();
- this.parent();
+ this.grab_focus();
},
vfunc_hide: function() {
@@ -121,45 +130,18 @@ const SearchPopup = new Lang.Class({
},
updateResult: function(places, searchString) {
- let model = this._treeView.get_model();
-
- model.clear();
+ this._list.forall(function(row) {
+ row.destroy();
+ });
places.forEach((function(place) {
if (!place.location)
return;
-
- let iter = model.append();
- let location = place.get_location();
- let icon = place.icon;
-
- let description = GLib.markup_escape_text(location.description, -1);
- description = this._boldMatch(description, searchString);
-
- model.set(iter,
- [Columns.DESCRIPTION,
- Columns.PLACE],
- [description,
- place]);
-
- if (icon !== null) {
- Utils.load_icon(icon, _PLACE_ICON_SIZE, function(pixbuf) {
- model.set(iter, [Columns.ICON], [pixbuf]);
- });
- }
+ let row = new SearchPopupRow({ place: place,
+ searchString: searchString,
+ maxChars: this._maxChars,
+ can_focus: true });
+ this._list.add(row);
}).bind(this));
- },
-
- _boldMatch: function(description, searchString) {
- searchString = searchString.toLowerCase();
-
- let index = description.toLowerCase().indexOf(searchString);
-
- if (index !== -1) {
- let substring = description.substring(index,
- index + searchString.length);
- description = description.replace(substring, substring.bold());
- }
- return description;
}
});
diff --git a/src/sidebar.js b/src/sidebar.js
index 870a0a7..5434c53 100644
--- a/src/sidebar.js
+++ b/src/sidebar.js
@@ -171,7 +171,8 @@ const Sidebar = new Lang.Class({
hexpand: true,
receives_default: true,
mapView: this._mapView,
- parseOnFocusOut: true });
+ parseOnFocusOut: true,
+ maxChars: 15 });
},
_createViaRow: function(listbox, index) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]