/* -*- 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, see .
*
* Author: Jonas Danielsson
*/
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Application = imports.application;
const PlaceListRow = imports.placeListRow;
const PlaceStore = imports.placeStore;
const SearchPopover = imports.searchPopover;
const _PLACE_ICON_SIZE = 20;
const Mode = {
IDLE: 0, // Nothing going on
ACTIVATED: 1, // Just activated, ignore changes to text
COMPLETION: 2, // We are doing completion against placeStore
RESULT: 3 // We are displaying results
};
const PlacePopover = new Lang.Class({
Name: 'PlacePopover',
Extends: SearchPopover.SearchPopover,
Signals : {
'selected' : { param_types: [ GObject.TYPE_OBJECT ] }
},
Template: 'resource:///org/gnome/Maps/ui/place-popover.ui',
InternalChildren: [ 'hintRevealer',
'scrolledWindow',
'stack',
'spinner',
'list' ],
_init: function(props) {
let numVisible = props.num_visible;
delete props.num_visible;
this._maxChars = props.maxChars;
delete props.maxChars;
props.transitions_enabled = false;
this.parent(props);
this._entry = this.relative_to;
this._entry.connect('notify::place', (function() {
this._mode = Mode.ACTIVATED;
}).bind(this));
Application.routeService.route.connect('updated', (function() {
this._mode = Mode.ACTIVATED;
}).bind(this));
this._list.connect('row-activated', (function(list, row) {
if (row)
this.emit('selected', row.place);
}).bind(this));
// Make sure we clear all selected rows when the search string change
this._entry.connect('changed',
this._list.unselect_all.bind(this._list));
// Do not show 'press enter to search' when we have
// selected rows in completion mode.
this._list.connect('selected-rows-changed',
this._updateHint.bind(this));
this._list.set_header_func(function(row, before) {
let header = new Gtk.Separator();
if (before)
row.set_header(header);
else
row.set_header(null);
});
let rowHeight = PlaceListRow.ROW_HEIGHT;
this._scrolledWindow.min_content_height = numVisible * rowHeight + 6;
// This silents warning at Maps exit about this widget being
// visible but not mapped.
this.connect('unmap', function(popover) { popover.hide(); });
},
showSpinner: function() {
this._spinner.start();
this._stack.visible_child = this._spinner;
this._updateHint();
if (!this.visible)
this.show();
},
showResult: function() {
this._mode = Mode.RESULT;
if (this._spinner.active)
this._spinner.stop();
this._stack.visible_child = this._scrolledWindow;
let row = this._list.get_row_at_index(0);
if (row)
this._list.select_row(row);
if (!this.visible)
this.show();
},
showCompletion: function() {
if (this._mode === undefined || this._mode === Mode.ACTIVATED) {
this._mode = Mode.IDLE;
return;
}
this._mode = Mode.COMPLETION;
this._stack.visible_child = this._scrolledWindow;
this._updateHint();
if (!this.visible)
this.show();
},
vfunc_hide: function() {
this._hintRevealer.reveal_child = false;
this.parent();
},
updateResult: function(places, searchString) {
this._list.forall(function(row) {
row.destroy();
});
places.forEach((function(place) {
if (!place.location)
return;
this._addRow(place, null, searchString);
}).bind(this));
},
updateCompletion: function(filter, searchString) {
this._list.forall(function(row) {
row.destroy();
});
filter.foreach((function(model, path, iter) {
let place = model.get_value(iter, PlaceStore.Columns.PLACE);
let type = model.get_value(iter, PlaceStore.Columns.TYPE);
this._addRow(place, type, searchString);
}).bind(this));
},
_addRow: function(place, type, searchString) {
let row = new PlaceListRow.PlaceListRow({ place: place,
searchString: searchString,
type: type,
maxChars: this._maxChars,
can_focus: true });
this._list.add(row);
},
_updateHint: function() {
if (this._stack.visible_child === this._spinner) {
this._hintRevealer.reveal_child = false;
return;
}
if (this._list.get_selected_rows().length > 0)
this._hintRevealer.reveal_child = false;
else
this._hintRevealer.reveal_child = true;
}
});