Skip to content

Commit 55fcbf4

Browse files
authored
Gtk4Prep: Fuzzy search popover - use ListStore instead of Items array (#1785)
1 parent 1c0df31 commit 55fcbf4

1 file changed

Lines changed: 82 additions & 88 deletions

File tree

‎plugins/fuzzy-search/fuzzy-search-popover.vala‎

Lines changed: 82 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ public class Scratch.FuzzySearchPopover : Gtk.Popover {
1717
private Gtk.SearchEntry search_term_entry;
1818
private Services.FuzzyFinder fuzzy_finder;
1919
private Gtk.ListBox search_result_container;
20+
private ListStore search_list_store;
2021
private int preselected_index;
2122
private Gtk.ScrolledWindow scrolled;
22-
private Gee.ArrayList<FileItem> items;
2323
private Scratch.Services.FuzzySearchIndexer indexer;
2424
private int window_height;
2525
private int max_items;
@@ -49,12 +49,14 @@ public class Scratch.FuzzySearchPopover : Gtk.Popover {
4949
valign = START
5050
};
5151

52+
search_list_store = new ListStore (typeof (FileItem));
5253
search_result_container = new Gtk.ListBox () {
5354
selection_mode = NONE,
5455
activate_on_single_click = true,
5556
can_focus = false
5657
};
5758
search_result_container.get_style_context ().add_class ("fuzzy-list");
59+
search_result_container.bind_model (search_list_store, (obj) => (FileItem)obj);
5860

5961
var entry_layout = new Gtk.Box (VERTICAL, 0) {
6062
valign = START
@@ -80,7 +82,6 @@ public class Scratch.FuzzySearchPopover : Gtk.Popover {
8082

8183
fuzzy_finder = new Services.FuzzyFinder (search_indexer.project_paths);
8284
indexer = search_indexer;
83-
items = new Gee.ArrayList<FileItem> ();
8485
cancellables = new Gee.LinkedList<GLib.Cancellable> ();
8586

8687
search_result_container.row_activated.connect ((row) => {
@@ -89,37 +90,37 @@ public class Scratch.FuzzySearchPopover : Gtk.Popover {
8990
return;
9091
}
9192

92-
handle_item_selection (items.index_of (file_item));
93+
handle_item_selection (file_item);
9394
});
9495

9596
search_term_entry_key_controller = new Gtk.EventControllerKey (search_term_entry);
9697
search_term_entry_key_controller.key_pressed.connect ((keyval, keycode, state) => {
9798
// Handle key up/down to select other files found by fuzzy search
9899
switch (keyval) {
99100
case Gdk.Key.Down:
100-
if (items.size > 0) {
101+
if (search_list_store.n_items > 0) {
101102
var old_index = preselected_index;
102-
var item = items.get (preselected_index++);
103-
if (preselected_index >= items.size) {
103+
var item = search_list_store.get_item (preselected_index++);
104+
if (preselected_index >= search_list_store.n_items) {
104105
preselected_index = 0;
105106
}
106107

107-
var next_item = items.get (preselected_index);
108-
preselect_new_item (item, next_item);
108+
var next_item = search_list_store.get_item (preselected_index);
109+
preselect_new_item ((FileItem) item, (FileItem) next_item);
109110
calculate_scroll_offset (old_index, preselected_index);
110111
}
111112

112113
return true;
113114
case Gdk.Key.Up:
114-
if (items.size > 0) {
115+
if (search_list_store.n_items > 0) {
115116
var old_index = preselected_index;
116-
var item = items.get (preselected_index--);
117+
var item = search_list_store.get_item (preselected_index--);
117118
if (preselected_index < 0) {
118-
preselected_index = items.size - 1;
119+
preselected_index = (int) search_list_store.n_items - 1;
119120
}
120121

121-
var next_item = items.get (preselected_index);
122-
preselect_new_item (item, next_item);
122+
var next_item = search_list_store.get_item (preselected_index);
123+
preselect_new_item ((FileItem) item, (FileItem) next_item);
123124
calculate_scroll_offset (old_index, preselected_index);
124125
}
125126
return true;
@@ -135,8 +136,8 @@ public class Scratch.FuzzySearchPopover : Gtk.Popover {
135136
});
136137

137138
search_term_entry.activate.connect (() => {
138-
if (items.size > 0) {
139-
handle_item_selection (preselected_index);
139+
if (search_list_store.n_items > 0) {
140+
handle_item_selection ((FileItem) search_list_store.get_item (preselected_index));
140141
}
141142
});
142143

@@ -149,75 +150,68 @@ public class Scratch.FuzzySearchPopover : Gtk.Popover {
149150
}
150151

151152
Timeout.add (1, () => {
152-
// If the entry is empty or the text has changed
153-
// since searching, do nothing
154-
if (previous_text.length == 0 || previous_text != search_term_entry.text) {
155-
return Source.REMOVE;
156-
}
153+
// If the entry is empty or the text has changed
154+
// since searching, do nothing
155+
if (previous_text.length == 0 || previous_text != search_term_entry.text) {
156+
return Source.REMOVE;
157+
}
157158

158-
var next_cancellable = new GLib.Cancellable ();
159-
cancellables.add (next_cancellable);
159+
var next_cancellable = new GLib.Cancellable ();
160+
cancellables.add (next_cancellable);
160161

161-
var dir_length = 0, term = search_term_entry.text;
162-
var parts = term.split (Path.DIR_SEPARATOR_S, 0);
163-
var rev_parts = term.reverse ().split (Path.DIR_SEPARATOR_S, 2);
164-
if (rev_parts.length == 2) {
165-
dir_length = rev_parts[0].length + 1;
166-
}
167-
168-
fuzzy_finder.fuzzy_find_async.begin (term, dir_length,
169-
current_doc_project,
170-
next_cancellable,
171-
(obj, res) => {
172-
if (next_cancellable.is_cancelled ()) {
173-
cancellables.remove (next_cancellable);
174-
return;
175-
}
162+
var dir_length = 0, term = search_term_entry.text;
163+
var parts = term.split (Path.DIR_SEPARATOR_S, 0);
164+
var rev_parts = term.reverse ().split (Path.DIR_SEPARATOR_S, 2);
165+
if (rev_parts.length == 2) {
166+
dir_length = rev_parts[0].length + 1;
167+
}
176168

177-
var results = fuzzy_finder.fuzzy_find_async.end (res);
178-
if (results == null) {
179-
return;
180-
}
169+
fuzzy_finder.fuzzy_find_async.begin (
170+
term,
171+
dir_length,
172+
current_doc_project,
173+
next_cancellable,
174+
(obj, res) => {
175+
if (next_cancellable.is_cancelled ()) {
176+
cancellables.remove (next_cancellable);
177+
return;
178+
}
181179

182-
bool first = true;
180+
var results = fuzzy_finder.fuzzy_find_async.end (res);
181+
if (results == null) {
182+
return;
183+
}
183184

185+
bool first = true;
184186

187+
search_list_store.remove_all ();
185188

186-
foreach (var c in search_result_container.get_children ()) {
187-
search_result_container.remove (c);
188-
}
189+
foreach (var result in results) {
190+
var file_item = new FileItem (result, indexer.project_paths.size > 1);
191+
file_item.can_focus = false;
189192

190-
items.clear ();
193+
if (first) {
194+
first = false;
195+
file_item.get_style_context ().add_class ("preselect-fuzzy");
196+
preselected_index = 0;
197+
}
191198

192-
foreach (var result in results) {
193-
var file_item = new FileItem (result, indexer.project_paths.size > 1);
194-
file_item.can_focus = false;
195-
196-
if (first) {
197-
first = false;
198-
file_item.get_style_context ().add_class ("preselect-fuzzy");
199-
preselected_index = 0;
199+
search_list_store.insert_sorted (file_item, sort_func);
200200
}
201201

202-
search_result_container.add (file_item);
203-
items.add (file_item);
204-
}
205-
206-
scrolled.hide ();
207-
scrolled.show_all ();
202+
scrolled.hide ();
203+
scrolled.show_all ();
208204

209-
// Reset scrolling
210-
scrolled.vadjustment.value = 0;
211-
});
205+
// Reset scrolling
206+
scrolled.vadjustment.value = 0;
207+
}
208+
);
212209

213210
return Source.REMOVE;
214211
});
215212
} else {
216-
foreach (var c in search_result_container.get_children ()) {
217-
search_result_container.remove (c);
218-
}
213+
search_list_store.remove_all ();
219214

220-
items.clear ();
221215
scrolled.hide ();
222216
}
223217
});
@@ -236,37 +230,38 @@ public class Scratch.FuzzySearchPopover : Gtk.Popover {
236230
scrolled.set_max_content_height (45 /* height */ * max_items);
237231

238232
current_doc_project = get_current_project (); // This will not change while popover is showing
239-
search_result_container.set_sort_func ((a , b) => {
240-
var result_a = ((FileItem)a).result;
241-
var result_b = ((FileItem)b).result;
242-
var project_a_is_current = result_a.project == current_doc_project;
243-
var project_b_is_current = result_b.project == current_doc_project;
244-
if (project_a_is_current && !project_b_is_current) {
245-
return 1;
246-
} else if (project_b_is_current && !project_a_is_current) {
247-
return -1;
248-
} else if (result_a.score > result_b.score) {
249-
return -1;
250-
} else if (result_b.score > result_a.score) {
251-
return 1;
252-
} else {
253-
return strcmp (((FileItem)a).result.full_path, ((FileItem)b).result.full_path);
254-
}
255-
});
256233
});
257234
}
258235

236+
private int sort_func (Object a, Object b) {
237+
var result_a = ((FileItem)a).result;
238+
var result_b = ((FileItem)b).result;
239+
var project_a_is_current = result_a.project == current_doc_project;
240+
var project_b_is_current = result_b.project == current_doc_project;
241+
if (project_a_is_current && !project_b_is_current) {
242+
return 1;
243+
} else if (project_b_is_current && !project_a_is_current) {
244+
return -1;
245+
} else if (result_a.score > result_b.score) {
246+
return -1;
247+
} else if (result_b.score > result_a.score) {
248+
return 1;
249+
} else {
250+
return strcmp (((FileItem)a).result.full_path, ((FileItem)b).result.full_path);
251+
}
252+
}
253+
259254
private void calculate_scroll_offset (int old_position, int new_position) {
260255
// Shortcut if jumping from first to last or the other way round
261256
if (new_position == 0 && old_position > new_position) {
262257
scrolled.vadjustment.value = 0;
263258
return;
264-
} else if (old_position == 0 && new_position == items.size - 1) {
259+
} else if (old_position == 0 && new_position == search_list_store.n_items - 1) {
265260
scrolled.vadjustment.value = scrolled.vadjustment.get_upper ();
266261
return;
267262
}
268263

269-
var size_box = scrolled.vadjustment.get_upper () / items.size;
264+
var size_box = scrolled.vadjustment.get_upper () / search_list_store.n_items;
270265
var current_top = scrolled.vadjustment.value;
271266
var current_bottom = current_top + size_box * (max_items - 2);
272267
if (old_position < new_position) {
@@ -284,8 +279,7 @@ public class Scratch.FuzzySearchPopover : Gtk.Popover {
284279
}
285280
}
286281

287-
private void handle_item_selection (int index) {
288-
var item = items.get (index);
282+
private void handle_item_selection (FileItem item) {
289283
open_file (item.filepath.strip ());
290284
}
291285

0 commit comments

Comments
 (0)