1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const BOX_WIDTH_CHARS = 25;
const CELL_PADDING_X = 15;
const CELL_PADDING_Y = 8;
/**
* Class: SearchBox
*
* This is a Search Box with autocompletion functionality.
*
*/
const SearchBox = new Lang.Class({
Name: 'SearchBox',
GTypeName: 'EosSearchBox',
Extends: Gtk.Entry,
Signals: {
/**
* Event: menu-item-selected
*
* This event is triggered when an item is selected from the autocomplete menu.
*/
'menu-item-selected': {
param_types: [GObject.TYPE_STRING]
},
/**
* Event: text-changed
*
* This event is triggered when the text in the search entry is changed by the user.
*/
'text-changed': {
param_types: [GObject.TYPE_STRING]
}
},
_init: function(props) {
this.parent(props);
this.primary_icon_name = 'edit-find-symbolic';
this.set_width_chars(BOX_WIDTH_CHARS);
this._auto_complete = new Gtk.EntryCompletion();
this._list_store = new Gtk.ListStore();
this._list_store.set_column_types([GObject.TYPE_STRING]);
this._auto_complete.set_model(this._list_store);
this._auto_complete.set_text_column(0);
let cells = this._auto_complete.get_cells();
cells[0].xpad = CELL_PADDING_X;
cells[0].ypad = CELL_PADDING_Y;
this.completion = this._auto_complete;
this.connect('icon-press', Lang.bind(this, function () {
this.emit('activate');
}));
this.completion.connect('match-selected', this._onMatchSelected.bind(this));
this.connect('changed', Lang.bind(this, function () {
if (!this._entry_changed_by_widget) {
// If there is entry text, need to add the 'go' icon
this.secondary_icon_name = (this.text.length > 0)? 'go-next-symbolic' : null;
this.emit('text-changed', this.text);
}
this._entry_changed_by_widget = false;
}));
this.get_style_context().add_class('endless-search-box');
},
_onMatchSelected: function (widget, model, iter) {
let index = model.get_path(iter).get_indices();
this.emit('menu-item-selected', this._items[index]['id']);
},
/* Set the menu items by providing an array of item objects:
[
{
'title': 'Frango',
'id': 'http://www.myfrango.com'
}
]
'title' must be a string but 'id' can be any type and is used to
identify the data that was selected.
*/
set_menu_items: function (items) {
this._items = items;
let model = this._auto_complete.get_model();
model.clear();
for (let i = 0; i < this._items.length; i++) {
model.set(model.append(), [0], [this._items[i]['title']]);
}
this._entry_changed_by_widget = true;
this.emit('changed');
}
});
|