Merge lp:~tintou/slingshot/gtk+-3.10 into lp:~elementary-pantheon/slingshot/trunk

Proposed by Corentin Noël
Status: Merged
Approved by: Cody Garver
Approved revision: 410
Merged at revision: 409
Proposed branch: lp:~tintou/slingshot/gtk+-3.10
Merge into: lp:~elementary-pantheon/slingshot/trunk
Diff against target: 1367 lines (+318/-452)
8 files modified
CMakeLists.txt (+3/-3)
src/Backend/AppSystem.vala (+6/-3)
src/SlingshotView.vala (+86/-188)
src/Widgets/AppEntry.vala (+1/-35)
src/Widgets/CategoryView.vala (+5/-99)
src/Widgets/Grid.vala (+93/-38)
src/Widgets/SearchView.vala (+20/-11)
src/Widgets/Switcher.vala (+104/-75)
To merge this branch: bzr merge lp:~tintou/slingshot/gtk+-3.10
Reviewer Review Type Date Requested Status
Rico Tzschichholz Needs Fixing
Review via email: mp+208011@code.launchpad.net

Commit message

Port forward to Gtk 3.10 for improved page switching and other benefits

Description of the change

Now using Gtk 3.10 !

To post a comment you must log in.
Revision history for this message
Cody Garver (codygarver) wrote :

It's like this all the time for me: http://i.imgur.com/NhJH5Mm.png

Revision history for this message
Rico Tzschichholz (ricotz) wrote :

Please don't make changes unrelated to using new Gtk wigets.
Meaning no codes-style-changes or refactoring.

If crashes or at least results in a hash-table critical here.

review: Needs Fixing
lp:~tintou/slingshot/gtk+-3.10 updated
410. By Corentin Noël

Removed code-style changes

Revision history for this message
Corentin Noël (tintou) wrote :

HashTable critical errors are also present into trunk

Revision history for this message
David Gomes (davidgomes) wrote :

I have the same problem as Cody.

Revision history for this message
David Gomes (davidgomes) wrote :

Seems this was merged and I get a transparent Slingshot.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-02-23 19:56:35 +0000
3+++ CMakeLists.txt 2014-03-01 15:19:46 +0000
4@@ -55,14 +55,14 @@
5 endif ()
6
7 set (CORE_DEPS "gobject-2.0;glib-2.0;gio-2.0;gio-unix-2.0;gee-0.8;libgnome-menu-3.0;libwnck-3.0;gdk-x11-3.0;${UNITY_DEPS};")
8-set (UI_DEPS "gtk+-3.0>=3.2.0;granite;${ZEITGEIST_DEPS};")
9+set (UI_DEPS "gtk+-3.0>=3.10.0;granite;${ZEITGEIST_DEPS};")
10
11 find_package (PkgConfig)
12 pkg_check_modules (DEPS REQUIRED "${CORE_DEPS}${UI_DEPS}" gthread-2.0)
13
14 find_package (Vala REQUIRED)
15 include (ValaVersion)
16-ensure_vala_version ("0.18.0" MINIMUM)
17+ensure_vala_version ("0.22.0" MINIMUM)
18
19 include (ValaPrecompile)
20 vala_precompile (VALA_C ${APPNAME}
21@@ -114,4 +114,4 @@
22 add_schema ("org.pantheon.desktop.slingshot.gschema.xml")
23
24 # Translations
25-add_subdirectory (po)
26+add_subdirectory (po)
27\ No newline at end of file
28
29=== modified file 'src/Backend/AppSystem.vala'
30--- src/Backend/AppSystem.vala 2013-01-10 16:53:50 +0000
31+++ src/Backend/AppSystem.vala 2014-03-01 15:19:46 +0000
32@@ -51,8 +51,11 @@
33 #if HAVE_ZEITGEIST
34 rl_service.refresh_popularity ();
35 #endif
36-
37- apps_menu.load_sync ();
38+ try {
39+ apps_menu.load_sync ();
40+ } catch (Error e) {
41+ warning (e.message);
42+ }
43
44 update_categories_index ();
45 update_apps ();
46@@ -224,4 +227,4 @@
47
48 }
49
50-}
51+}
52\ No newline at end of file
53
54=== modified file 'src/SlingshotView.vala'
55--- src/SlingshotView.vala 2013-12-26 00:08:04 +0000
56+++ src/SlingshotView.vala 2014-03-01 15:19:46 +0000
57@@ -27,9 +27,8 @@
58 public class SlingshotView : Granite.Widgets.PopOver {
59
60 // Widgets
61- public Granite.Widgets.SearchBar searchbar;
62- public Gtk.Layout view_manager;
63- public Widgets.Switcher page_switcher;
64+ public Gtk.SearchEntry search_entry;
65+ public Gtk.Stack stack;
66 public Granite.Widgets.ModeButton view_selector;
67
68 // Views
69@@ -39,7 +38,6 @@
70
71 public Gtk.Grid top;
72 public Gtk.Grid center;
73- public Gtk.Grid bottom;
74 public Gtk.Grid container;
75 public Gtk.Box content_area;
76 private Gtk.EventBox event_box;
77@@ -156,56 +154,43 @@
78 else
79 view_selector.selected = 0;
80
81- searchbar = new Granite.Widgets.SearchBar (_("Search Apps…"));
82- searchbar.pause_delay = 200;
83- searchbar.width_request = 250;
84- searchbar.button_press_event.connect ((e) => {return e.button == 3;});
85+ search_entry = new Gtk.SearchEntry ();
86+ search_entry.placeholder_text = _("Search Apps…");
87+ search_entry.width_request = 250;
88+ search_entry.button_press_event.connect ((e) => {return e.button == 3;});
89
90 if (Slingshot.settings.show_category_filter) {
91 top.attach (view_selector, 0, 0, 1, 1);
92 }
93 top.attach (top_separator, 1, 0, 1, 1);
94- top.attach (searchbar, 2, 0, 1, 1);
95+ top.attach (search_entry, 2, 0, 1, 1);
96
97 center = new Gtk.Grid ();
98- // Create the layout which works like view_manager
99- view_manager = new Gtk.Layout (null, null);
100- view_manager.set_size_request (default_columns * 130, default_rows * 145);
101- center.attach (view_manager, 0, 0, 1, 1);
102+
103+ stack = new Gtk.Stack ();
104+ stack.set_size_request (default_columns * 130, default_rows * 145);
105+ center.attach (stack, 0, 0, 1, 1);
106
107 // Create the "NORMAL_VIEW"
108+ var scrolled_normal = new Gtk.ScrolledWindow (null, null);
109 grid_view = new Widgets.Grid (default_rows, default_columns);
110- view_manager.put (grid_view, 0, 0);
111+ scrolled_normal.add_with_viewport (grid_view);
112+ stack.add_named (scrolled_normal, "normal");
113
114 // Create the "SEARCH_VIEW"
115 search_view = new Widgets.SearchView (this);
116+
117 foreach (Gee.ArrayList<Backend.App> app_list in apps.values) {
118 search_view.add_apps (app_list);
119 }
120- view_manager.put (search_view, -columns * 130, 0);
121+ stack.add_named (search_view, "search");
122
123 // Create the "CATEGORY_VIEW"
124 category_view = new Widgets.CategoryView (this);
125- view_manager.put (category_view, -columns * 130, 0);
126-
127- // Create the page switcher
128- page_switcher = new Widgets.Switcher ();
129-
130- // A bottom widget to keep the page switcher center
131- bottom = new Gtk.Grid ();
132-
133-
134- var bottom_separator1 = new Gtk.Label (""); // A fake label
135- bottom_separator1.set_hexpand (true);
136- var bottom_separator2 = new Gtk.Label (""); // A fake label
137- bottom_separator2.set_hexpand (true);
138- bottom.attach (bottom_separator1, 0, 0, 1, 1); // A fake label
139- bottom.attach (page_switcher, 1, 0, 1, 1);
140- bottom.attach (bottom_separator2, 2, 0, 1, 1); // A fake label
141+ stack.add_named (category_view, "category");
142
143 container.attach (Utils.set_padding (top, 12, 12, 12, 12), 0, 0, 1, 1);
144 container.attach (Utils.set_padding (center, 0, 12, 12, 12), 0, 1, 1, 1);
145- container.attach (Utils.set_padding (bottom, 0, 24, 12, 24), 0, 2, 1, 1);
146
147 event_box = new Gtk.EventBox ();
148 event_box.add (container);
149@@ -277,17 +262,15 @@
150 private void connect_signals () {
151
152 this.focus_in_event.connect (() => {
153- searchbar.grab_focus ();
154+ search_entry.grab_focus ();
155 return false;
156 });
157
158- //view_manager.draw.connect (this.draw_background);
159-
160 event_box.key_press_event.connect (on_key_press);
161- searchbar.text_changed_pause.connect ((text) => this.search.begin (text));
162- searchbar.grab_focus ();
163+ search_entry.search_changed.connect (() => this.search.begin (search_entry.text));
164+ search_entry.grab_focus ();
165
166- searchbar.activate.connect (() => {
167+ search_entry.activate.connect (() => {
168 if (modality == Modality.SEARCH_VIEW) {
169 search_view.launch_selected ();
170 hide ();
171@@ -300,15 +283,8 @@
172 search_view.app_launched.connect (() => hide ());
173
174 // This function must be after creating the page switcher
175- grid_view.new_page.connect (page_switcher.append);
176 populate_grid_view ();
177
178- page_switcher.active_changed.connect (() => {
179-
180- move_page (page_switcher.active - page_switcher.old_active);
181- searchbar.grab_focus (); //avoid focus is not on current page
182- });
183-
184 view_selector.mode_changed.connect (() => {
185
186 set_modality ((Modality) view_selector.selected);
187@@ -383,7 +359,7 @@
188 when an input method is in use (Gtk3 bug?). Key press events are
189 captured by an Event Box and passed to this function instead.
190
191- Events not dealt with here are propagated to the searchbar by the
192+ Events not dealt with here are propagated to the search_entry by the
193 usual mechanism.
194 */
195 public bool on_key_press (Gdk.EventKey event) {
196@@ -408,8 +384,8 @@
197 break;
198
199 case "Escape":
200- if (searchbar.text.length > 0) {
201- searchbar.text = "";
202+ if (search_entry.text.length > 0) {
203+ search_entry.text = "";
204 } else {
205 hide ();
206 }
207@@ -443,25 +419,25 @@
208 case "7":
209 case "8":
210 case "9":
211- int page = int.parse (key) - 1;
212+ int page = int.parse (key);
213
214 if (event.state != Gdk.ModifierType.MOD1_MASK)
215 return false;
216
217 if (modality == Modality.NORMAL_VIEW) {
218- if (page < 0 || page == 8)
219- page_switcher.set_active (grid_view.get_n_pages () - 1);
220+ if (page < 0 || page == 9)
221+ grid_view.go_to_last ();
222 else
223- page_switcher.set_active (page);
224+ grid_view.go_to_number (page);
225 } else if (modality == Modality.CATEGORY_VIEW) {
226- if (page < 0 || page == 8)
227- category_view.switcher.set_active (category_view.switcher.size - 1);
228+ if (page < 0 || page == 9)
229+ category_view.app_view.go_to_last ();
230 else
231- category_view.switcher.set_active (page);
232+ category_view.app_view.go_to_number (page);
233 } else {
234 return false;
235 }
236- searchbar.grab_focus ();
237+ search_entry.grab_focus ();
238 break;
239
240 case "Tab":
241@@ -480,14 +456,15 @@
242
243 case "Left":
244 if (modality == Modality.NORMAL_VIEW) {
245- if (event.state == Gdk.ModifierType.SHIFT_MASK) // Shift + Left
246- page_switcher.set_active (page_switcher.active - 1);
247- else
248+ if (event.state == Gdk.ModifierType.SHIFT_MASK) {// Shift + Left
249+ grid_view.go_to_previous ();
250+ } else {
251 normal_move_focus (-1, 0);
252+ }
253 } else if (modality == Modality.CATEGORY_VIEW) {
254 if (event.state == Gdk.ModifierType.SHIFT_MASK) // Shift + Left
255- category_view.switcher.set_active (category_view.switcher.active - 1);
256- else if (!searchbar.has_focus) {//the user has already selected an AppEntry
257+ category_view.app_view.go_to_previous ();
258+ else if (!search_entry.has_focus) {//the user has already selected an AppEntry
259 category_move_focus (-1, 0);
260 }
261 } else
262@@ -497,13 +474,13 @@
263 case "Right":
264 if (modality == Modality.NORMAL_VIEW) {
265 if (event.state == Gdk.ModifierType.SHIFT_MASK) // Shift + Right
266- page_switcher.set_active (page_switcher.active + 1);
267+ grid_view.go_to_next ();
268 else
269 normal_move_focus (+1, 0);
270 } else if (modality == Modality.CATEGORY_VIEW) {
271 if (event.state == Gdk.ModifierType.SHIFT_MASK) // Shift + Right
272- category_view.switcher.set_active (category_view.switcher.active + 1);
273- else if (searchbar.has_focus) // there's no AppEntry selected, the user is switching category
274+ category_view.app_view.go_to_next ();
275+ else if (search_entry.has_focus) // there's no AppEntry selected, the user is switching category
276 top_left_focus ();
277 else //the user has already selected an AppEntry
278 category_move_focus (+1, 0);
279@@ -521,14 +498,13 @@
280 category_view.category_switcher.selected--;
281 top_left_focus ();
282 }
283- } else if (searchbar.has_focus) {
284+ } else if (search_entry.has_focus) {
285 category_view.category_switcher.selected--;
286 } else {
287 category_move_focus (0, -1);
288 }
289 } else if (modality == Modality.SEARCH_VIEW) {
290 search_view.selected--;
291- search_view_up ();
292 }
293 break;
294
295@@ -539,23 +515,19 @@
296 if (event.state == Gdk.ModifierType.SHIFT_MASK) { // Shift + Down
297 category_view.category_switcher.selected++;
298 top_left_focus ();
299- } else if (searchbar.has_focus) {
300+ } else if (search_entry.has_focus) {
301 category_view.category_switcher.selected++;
302 } else { // the user has already selected an AppEntry
303 category_move_focus (0, +1);
304 }
305 } else if (modality == Modality.SEARCH_VIEW) {
306 search_view.selected++;
307- if (search_view.selected > 7)
308- search_view_down ();
309 }
310 break;
311
312 case "Page_Up":
313 if (modality == Modality.NORMAL_VIEW) {
314- page_switcher.set_active (page_switcher.active - 1);
315- if (page_switcher.active != 0) // we don't wanna lose focus if we don't actually change page
316- searchbar.grab_focus (); // this is because otherwise focus isn't the current page
317+ grid_view.go_to_previous ();
318 } else if (modality == Modality.CATEGORY_VIEW) {
319 category_view.category_switcher.selected--;
320 top_left_focus ();
321@@ -564,9 +536,7 @@
322
323 case "Page_Down":
324 if (modality == Modality.NORMAL_VIEW) {
325- page_switcher.set_active (page_switcher.active + 1);
326- if (page_switcher.active != grid_view.get_n_pages () - 1) // we don't wanna lose focus if we don't actually change page
327- searchbar.grab_focus (); //this is because otherwise focus isn't the current page
328+ grid_view.go_to_next ();
329 } else if (modality == Modality.CATEGORY_VIEW) {
330 category_view.category_switcher.selected++;
331 top_left_focus ();
332@@ -575,23 +545,23 @@
333
334 case "BackSpace":
335 if (event.state == Gdk.ModifierType.SHIFT_MASK) { // Shift + Delete
336- searchbar.text = "";
337- } else if (searchbar.has_focus) {
338+ search_entry.text = "";
339+ } else if (search_entry.has_focus) {
340 return false;
341 } else {
342- searchbar.grab_focus ();
343- searchbar.move_cursor (Gtk.MovementStep.BUFFER_ENDS, 0, false);
344+ search_entry.grab_focus ();
345+ search_entry.move_cursor (Gtk.MovementStep.BUFFER_ENDS, 0, false);
346 return false;
347 }
348 break;
349
350 case "Home":
351- if (searchbar.text.length > 0) {
352+ if (search_entry.text.length > 0) {
353 return false;
354 }
355
356 if (modality == Modality.NORMAL_VIEW) {
357- page_switcher.set_active (0);
358+ grid_view.go_to_number (1);
359 } else if (modality == Modality.CATEGORY_VIEW) {
360 category_view.category_switcher.selected = 0;
361 top_left_focus ();
362@@ -599,12 +569,12 @@
363 break;
364
365 case "End":
366- if (searchbar.text.length > 0) {
367+ if (search_entry.text.length > 0) {
368 return false;
369 }
370
371 if (modality == Modality.NORMAL_VIEW) {
372- page_switcher.set_active (grid_view.get_n_pages () - 1);
373+ grid_view.go_to_last ();
374 } else if (modality == Modality.CATEGORY_VIEW) {
375 category_view.category_switcher.selected = category_view.category_switcher.cat_size - 1;
376 top_left_focus ();
377@@ -614,14 +584,14 @@
378 case "v":
379 case "V":
380 if ((event.state & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK)) != 0) {
381- searchbar.paste_clipboard ();
382+ search_entry.paste_clipboard ();
383 }
384 break;
385
386 default:
387- if (!searchbar.has_focus) {
388- searchbar.grab_focus ();
389- searchbar.move_cursor (Gtk.MovementStep.BUFFER_ENDS, 0, false);
390+ if (!search_entry.has_focus) {
391+ search_entry.grab_focus ();
392+ search_entry.move_cursor (Gtk.MovementStep.BUFFER_ENDS, 0, false);
393 }
394 return false;
395
396@@ -637,20 +607,16 @@
397 case "GDK_SCROLL_UP":
398 case "GDK_SCROLL_LEFT":
399 if (modality == Modality.NORMAL_VIEW)
400- page_switcher.set_active (page_switcher.active - 1);
401- else if (modality == Modality.SEARCH_VIEW)
402- search_view_up ();
403- else
404- category_view.switcher.set_active (category_view.switcher.active - 1);
405+ grid_view.go_to_previous ();
406+ else if (modality == Modality.CATEGORY_VIEW)
407+ category_view.app_view.go_to_previous ();
408 break;
409 case "GDK_SCROLL_DOWN":
410 case "GDK_SCROLL_RIGHT":
411 if (modality == Modality.NORMAL_VIEW)
412- page_switcher.set_active (page_switcher.active + 1);
413- else if (modality == Modality.SEARCH_VIEW)
414- search_view_down ();
415- else
416- category_view.switcher.set_active (category_view.switcher.active + 1);
417+ grid_view.go_to_next ();
418+ else if (modality == Modality.CATEGORY_VIEW)
419+ category_view.app_view.go_to_next ();
420 break;
421
422 }
423@@ -661,14 +627,14 @@
424
425 public void show_slingshot () {
426
427- searchbar.text = "";
428+ search_entry.text = "";
429
430 reposition ();
431 show_all ();
432 present ();
433
434 set_focus(null);
435- searchbar.grab_focus ();
436+ search_entry.grab_focus ();
437 set_modality ((Modality) view_selector.selected);
438
439 while (Gtk.events_pending ())
440@@ -681,56 +647,6 @@
441 w.activate (Gdk.x11_get_server_time (this.get_window ()));
442 }
443
444- private void move_page (int step) {
445-
446- debug ("Moving: step = " + step.to_string ());
447-
448- if (step == 0)
449- return;
450- if (step < 0 && current_position >= 0) //Left border
451- return;
452- if (step > 0 && (-current_position) >= ((grid_view.get_n_pages () - 1) * grid_view.get_page_columns () * 130)) //Right border
453- return;
454-
455- int count = 0;
456- int increment = -step * 130 * columns / 10;
457- Timeout.add (30 / columns, () => {
458-
459- if (count >= 10) {
460- current_position += -step * 130 * columns - 10 * increment; //We adjust to end of the page
461- view_manager.move (grid_view, current_position, 0);
462- return false;
463- }
464-
465- current_position += increment;
466- view_manager.move (grid_view, current_position, 0);
467- count++;
468- return true;
469-
470- }, Priority.DEFAULT_IDLE);
471- }
472-
473- private void search_view_down () {
474-
475- if (search_view.apps_showed < default_rows * 3)
476- return;
477-
478- if ((search_view_position) > -(search_view.apps_showed * 48)) {
479- view_manager.move (search_view, 0, search_view_position - 2 * 38);
480- search_view_position -= 2 * 38;
481- }
482-
483- }
484-
485- private void search_view_up () {
486-
487- if (search_view_position < 0) {
488- view_manager.move (search_view, 0, search_view_position + 2 * 38);
489- search_view_position += 2 * 38;
490- }
491-
492- }
493-
494 private void set_modality (Modality new_modality) {
495
496 modality = new_modality;
497@@ -740,57 +656,42 @@
498
499 if (Slingshot.settings.use_category)
500 Slingshot.settings.use_category = false;
501- bottom.show ();
502 view_selector.show_all ();
503- page_switcher.show_all ();
504- category_view.show_page_switcher (false);
505- view_manager.move (search_view, - 130 * columns, 0);
506- view_manager.move (category_view, 130 * columns, 0);
507- view_manager.move (grid_view, current_position, 0);
508+ stack.set_visible_child_name ("normal");
509
510 // change the paddings/margins back to normal
511 get_content_area ().set_margin_left (PADDINGS.left + SHADOW_SIZE + 5);
512 center.set_margin_left (12);
513 top.set_margin_left (12);
514- view_manager.set_size_request (default_columns * 130, default_rows * 145);
515+ stack.set_size_request (default_columns * 130, default_rows * 145);
516 break;
517
518 case Modality.CATEGORY_VIEW:
519
520 if (!Slingshot.settings.use_category)
521 Slingshot.settings.use_category = true;
522- bottom.show ();
523 view_selector.show_all ();
524- page_switcher.hide ();
525- category_view.show_page_switcher (true);
526- view_manager.move (grid_view, (columns + 1) * 130, 0); // plus 1 is needed because otherwise grid_view may appear in category view
527- view_manager.move (search_view, -columns * 130, 0);
528- view_manager.move (category_view, 0, 0);
529+ stack.set_visible_child_name ("category");
530
531 // remove the padding/margin on the left
532 get_content_area ().set_margin_left (PADDINGS.left + SHADOW_SIZE);
533 center.set_margin_left (0);
534 top.set_margin_left (17);
535- view_manager.set_size_request (default_columns * 130 + 17, default_rows * 145);
536+ stack.set_size_request (default_columns * 130 + 17, default_rows * 145);
537 break;
538
539 case Modality.SEARCH_VIEW:
540 view_selector.hide ();
541- bottom.hide (); // Hide the switcher
542- view_manager.move (grid_view, columns * 130, 0); // Move the grid_view away
543- view_manager.move (category_view, columns * 130, 0);
544- view_manager.move (search_view, 0, 0); // Show the searchview
545+ stack.set_visible_child_name ("search");
546
547 // change the paddings/margins back to normal
548 get_content_area ().set_margin_left (PADDINGS.left + SHADOW_SIZE + 5);
549 center.set_margin_left (12);
550 top.set_margin_left (12);
551- view_manager.set_size_request (default_columns * 130, default_rows * 145);
552+ stack.set_size_request (default_columns * 130, default_rows * 145);
553 break;
554
555 }
556- //searchbar.grab_focus ();
557-
558 }
559
560 private async void search (string text) {
561@@ -805,7 +706,6 @@
562 if (modality != Modality.SEARCH_VIEW)
563 set_modality (Modality.SEARCH_VIEW);
564 search_view_position = 0;
565- view_manager.move (search_view, 0, search_view_position);
566 search_view.hide_all ();
567
568 var filtered = yield app_system.search_results (stripped);
569@@ -820,12 +720,8 @@
570
571 public void populate_grid_view () {
572
573- page_switcher.clear_children ();
574 grid_view.clear ();
575
576- page_switcher.append ("1");
577- page_switcher.set_active (0);
578-
579 foreach (Backend.App app in app_system.get_apps_by_name ()) {
580
581 var app_entry = new Widgets.AppEntry (app);
582@@ -834,7 +730,7 @@
583 app_entry.show_all ();
584 }
585
586- view_manager.move (grid_view, 0, 0);
587+ stack.set_visible_child_name ("normal");
588 current_position = 0;
589
590 }
591@@ -861,7 +757,6 @@
592 height_request = default_rows * 145 + 180;
593
594 category_view.app_view.resize (default_rows, default_columns);
595- category_view.set_size_request (columns * 130 + 17, view_height);
596 category_view.show_filtered_apps (category_view.category_ids.get (category_view.category_switcher.selected));
597 }
598
599@@ -869,6 +764,8 @@
600
601 private void normal_move_focus (int delta_column, int delta_row) {
602 if (get_focus () as Widgets.AppEntry != null) { // we check if any AppEntry has focus. If it does, we move
603+ if (column_focus + delta_column < 0 || row_focus + delta_row < 0)
604+ return;
605 var new_focus = grid_view.get_child_at (column_focus + delta_column, row_focus + delta_row); // we check if the new widget exists
606 if (new_focus == null) {
607 if (delta_column <= 0)
608@@ -883,14 +780,15 @@
609 column_focus += delta_column;
610 row_focus += delta_row;
611 if (delta_column > 0 && column_focus % grid_view.get_page_columns () == 0 ) //check if we need to change page
612- page_switcher.set_active (page_switcher.active + 1);
613+ grid_view.go_to_next ();
614 else if (delta_column < 0 && (column_focus + 1) % grid_view.get_page_columns () == 0) //check if we need to change page
615- page_switcher.set_active (page_switcher.active - 1);
616+ grid_view.go_to_previous ();
617 new_focus.grab_focus ();
618 }
619 else { // we move to the first app in the top left corner of the current page
620- grid_view.get_child_at (page_switcher.active * grid_view.get_page_columns (), 0).grab_focus ();
621- column_focus = page_switcher.active * grid_view.get_page_columns ();
622+ column_focus = (grid_view.get_current_page ()-1) * grid_view.get_page_columns ();
623+ if (column_focus >= 0)
624+ grid_view.get_child_at (column_focus, 0).grab_focus ();
625 row_focus = 0;
626 }
627 }
628@@ -909,13 +807,13 @@
629 return;
630 }
631 else if (delta_column > 0 && (category_column_focus + delta_column) % category_view.app_view.get_page_columns () == 0
632- && category_view.switcher.active + 1 != category_view.app_view.get_n_pages ()) {
633- category_view.switcher.set_active (category_view.switcher.active + 1);
634+ && category_view.app_view.get_current_page ()+ 1 != category_view.app_view.get_n_pages ()) {
635+ category_view.app_view.go_to_next ();
636 top_left_focus ();
637 return;
638 }
639 else if (category_column_focus == 0 && delta_column < 0) {
640- searchbar.grab_focus ();
641+ search_entry.grab_focus ();
642 category_column_focus = 0;
643 category_row_focus = 0;
644 return;
645@@ -926,11 +824,11 @@
646 category_column_focus += delta_column;
647 category_row_focus += delta_row;
648 if (delta_column > 0 && category_column_focus % category_view.app_view.get_page_columns () == 0 ) { // check if we need to change page
649- category_view.switcher.set_active (category_view.switcher.active + 1);
650+ category_view.app_view.go_to_next ();
651 }
652 else if (delta_column < 0 && (category_column_focus + 1) % category_view.app_view.get_page_columns () == 0) {
653 // check if we need to change page
654- category_view.switcher.set_active (category_view.switcher.active - 1);
655+ category_view.app_view.go_to_previous ();
656 }
657 new_focus.grab_focus ();
658 }
659@@ -938,10 +836,10 @@
660 // this method moves focus to the first AppEntry in the top left corner of the current page. Works in CategoryView only
661 private void top_left_focus () {
662 // this is the first column of the current page
663- int first_column = category_view.switcher.active * category_view.app_view.get_page_columns ();
664+ int first_column = (grid_view.get_current_page ()-1) * category_view.app_view.get_page_columns ();
665 category_view.app_view.get_child_at (first_column, 0).grab_focus ();
666 category_column_focus = first_column;
667- category_row_focus = 0;
668+ category_row_focus = 1;
669 }
670
671 public void reset_category_focus () {
672
673=== modified file 'src/Widgets/AppEntry.vala'
674--- src/Widgets/AppEntry.vala 2013-12-26 00:08:04 +0000
675+++ src/Widgets/AppEntry.vala 2014-03-01 15:19:46 +0000
676@@ -104,42 +104,8 @@
677
678 }
679
680- public void fade_out () {
681-
682- Timeout.add (20, () => {
683-
684- if (alpha <= 0.3) {
685- queue_draw ();
686- return false;
687- }
688-
689- alpha -= 0.05;
690- queue_draw ();
691- return true;
692-
693- });
694-
695- }
696-
697- public void fade_in () {
698-
699- Timeout.add (20, () => {
700-
701- if (alpha == 1.0) {
702- queue_draw ();
703- return false;
704- }
705-
706- alpha += 0.05;
707- queue_draw ();
708- return true;
709-
710- });
711-
712- }
713-
714 public void launch_app () {
715 application.launch ();
716 app_launched ();
717 }
718-}
719+}
720\ No newline at end of file
721
722=== modified file 'src/Widgets/CategoryView.vala'
723--- src/Widgets/CategoryView.vala 2013-12-26 00:08:04 +0000
724+++ src/Widgets/CategoryView.vala 2014-03-01 15:19:46 +0000
725@@ -22,17 +22,13 @@
726 public Sidebar category_switcher;
727 public Gtk.Separator separator;
728 public Widgets.Grid app_view;
729- private Gtk.Layout layout;
730- public Switcher switcher;
731 private SlingshotView view;
732- private Gtk.Label empty_cat_label;
733
734 private Gtk.Grid page_switcher;
735
736 private const string ALL_APPLICATIONS = _("All Applications");
737 private const string NEW_FILTER = _("Create a new Filter");
738 private int current_position = 0;
739- private bool from_category = false;
740
741 public Gee.HashMap<int, string> category_ids = new Gee.HashMap<int, string> ();
742
743@@ -53,30 +49,11 @@
744 container = new Gtk.Grid ();
745 separator = new Gtk.Separator (Gtk.Orientation.VERTICAL);
746
747- layout = new Gtk.Layout (null, null);
748-
749 app_view = new Widgets.Grid (view.rows, view.columns - 1);
750- layout.put (app_view, 0, 0);
751- empty_cat_label = new Gtk.Label ("");
752- layout.put (empty_cat_label, view.columns*130, view.rows * 130 / 2);
753- layout.set_hexpand (true);
754- layout.set_vexpand (true);
755-
756- // Create the page switcher
757- switcher = new Switcher ();
758-
759- // A bottom widget to keep the page switcher center
760- page_switcher = new Gtk.Grid ();
761- var bottom_separator1 = new Gtk.Label (""); // A fake label
762- bottom_separator1.set_hexpand(true);
763- var bottom_separator2 = new Gtk.Label (""); // A fake label
764- bottom_separator2.set_hexpand(true);
765- page_switcher.attach (bottom_separator1, 0, 0, 1, 1);
766- page_switcher.attach (switcher, 1, 0, 1, 1);
767- page_switcher.attach (bottom_separator2, 2, 0, 1, 1);
768+ app_view.margin_left = 5;
769
770 container.attach (separator, 1, 0, 1, 2);
771- container.attach (layout, 2, 0, 1, 1);
772+ container.attach (app_view, 2, 0, 1, 1);
773
774 add (container);
775
776@@ -112,40 +89,6 @@
777
778 private void connect_events () {
779
780- layout.scroll_event.connect ((event) => {
781- switch (event.direction.to_string ()) {
782- case "GDK_SCROLL_UP":
783- case "GDK_SCROLL_LEFT":
784- switcher.set_active (switcher.active - 1);
785- break;
786- case "GDK_SCROLL_DOWN":
787- case "GDK_SCROLL_RIGHT":
788- switcher.set_active (switcher.active + 1);
789- break;
790- }
791- return false;
792- });
793-
794- app_view.new_page.connect ((page) => {
795-
796- if (switcher.size == 0)
797- switcher.append ("1");
798- switcher.append (page);
799-
800- /* Prevents pages from changing */
801- from_category = true;
802- });
803-
804- switcher.active_changed.connect (() => {
805- if (from_category || switcher.active - switcher.old_active == 0) {
806- from_category = false;
807- return;
808- }
809-
810- move_page (switcher.active - switcher.old_active);
811- view.searchbar.grab_focus (); // this is because otherwise focus isn't the current page
812- });
813-
814 category_switcher.selected = 0; //Must be after everything else
815 }
816
817@@ -154,55 +97,20 @@
818 var app_entry = new AppEntry (app);
819 app_entry.app_launched.connect (() => view.hide ());
820 app_view.append (app_entry);
821- app_entry.show_all ();
822+ app_view.show_all ();
823
824 }
825
826 public void show_filtered_apps (string category) {
827
828- switcher.clear_children ();
829 app_view.clear ();
830-
831- layout.move (empty_cat_label, view.columns*130, view.rows*130 / 2);
832 foreach (Backend.App app in view.apps[category])
833 add_app (app);
834
835- switcher.set_active (0);
836-
837- layout.move (app_view, 0, 0);
838 current_position = 0;
839
840 }
841
842- public void move_page (int step) {
843-
844- debug ("Moving: step = " + step.to_string ());
845-
846- if (step == 0)
847- return;
848- if (step < 0 && current_position >= 0) //Left border
849- return;
850- if (step > 0 && (-current_position) >= ((app_view.get_n_pages () - 1) * app_view.get_page_columns () * 130)) //Right border
851- return;
852-
853- int count = 0;
854- int increment = -step*130*(view.columns-1)/10;
855- Timeout.add (30/(view.columns-1), () => {
856-
857- if (count >= 10) {
858- current_position += -step*130*(view.columns-1) - 10*increment; //We adjust to end of the page
859- layout.move (app_view, current_position, 0);
860- return false;
861- }
862-
863- current_position += increment;
864- layout.move (app_view, current_position, 0);
865- count++;
866- return true;
867-
868- }, Priority.DEFAULT_IDLE);
869- }
870-
871 public void show_page_switcher (bool show) {
872
873 if (page_switcher.get_parent () == null)
874@@ -210,14 +118,12 @@
875
876 if (show) {
877 page_switcher.show_all ();
878- view.bottom.hide ();
879 }
880 else
881 page_switcher.hide ();
882
883- view.searchbar.grab_focus ();
884+ view.search_entry.grab_focus ();
885
886 }
887
888-}
889-
890+}
891\ No newline at end of file
892
893=== modified file 'src/Widgets/Grid.vala'
894--- src/Widgets/Grid.vala 2013-12-26 00:08:04 +0000
895+++ src/Widgets/Grid.vala 2014-03-01 15:19:46 +0000
896@@ -21,40 +21,70 @@
897 struct Page {
898 public uint rows;
899 public uint columns;
900- public uint number;
901+ public int number;
902 }
903
904- public class Grid : Gtk.Grid {
905-
906- public signal void new_page (string page_num);
907+ public class Grid : Gtk.Box {
908+ public int row_spacing = 20;
909+ public Widgets.Switcher page_switcher;
910+
911+ private Gtk.Stack stack;
912+ private Gtk.Grid current_grid;
913+ private Gee.HashMap<int, Gtk.Grid> grids;
914
915 private uint current_row = 0;
916 private uint current_col = 0;
917 private Page page;
918
919 public Grid (int rows, int columns) {
920-
921+ page.rows = rows;
922+ page.columns = columns;
923+ page.number = 1;
924+ var main_grid = new Gtk.Grid ();
925+ main_grid.orientation = Gtk.Orientation.VERTICAL;
926+ stack = new Gtk.Stack ();
927+ stack.transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT;
928+ page_switcher = new Widgets.Switcher ();
929+ page_switcher.set_stack (stack);
930+ var fake_grid = new Gtk.Grid ();
931+ fake_grid.hexpand = true;
932+ var stack_layout = new Gtk.Layout ();
933+ stack_layout.expand = true;
934+ stack_layout.add (stack);
935+
936+ main_grid.add (stack_layout);
937+ main_grid.add (fake_grid);
938+ main_grid.add (page_switcher);
939+ add (main_grid);
940+
941+ grids = new Gee.HashMap<int, Gtk.Grid> (null, null);
942+ create_new_grid ();
943+ go_to_number (1);
944+ }
945+
946+ private void create_new_grid () {
947 // Grid properties
948- row_homogeneous = true;
949- column_homogeneous = true;
950-
951- row_spacing = 20;
952- column_spacing = 0;
953-
954- page.rows = rows;
955- page.columns = columns;
956- page.number = 1;
957-
958+ current_grid = new Gtk.Grid ();
959+ current_grid.expand = true;
960+ current_grid.row_homogeneous = true;
961+ current_grid.column_homogeneous = true;
962+
963+ current_grid.row_spacing = row_spacing;
964+ current_grid.column_spacing = 0;
965+ grids.set (page.number, current_grid);
966+ stack.add_titled (current_grid, page.number.to_string (), page.number.to_string ());
967+
968+ // Fake grids in case there are not enough apps to fill the grid
969+ current_grid.attach (new Gtk.Grid (), 0, 0, (int)page.columns, (int)page.rows);
970 }
971
972 public void append (Gtk.Widget widget) {
973
974 update_position ();
975
976- var col = current_col + page.columns * (page.number - 1);
977-
978- this.attach (widget, (int)col, (int)current_row, 1, 1);
979+ current_grid.attach (widget, (int)current_col, (int)current_row, 1, 1);
980 current_col++;
981+ current_grid.show ();
982 }
983
984 private void update_position () {
985@@ -66,7 +96,7 @@
986
987 if (current_row == page.rows) {
988 page.number++;
989- new_page (page.number.to_string ());
990+ create_new_grid ();
991 current_row = 0;
992 }
993
994@@ -74,16 +104,27 @@
995
996 public void clear () {
997
998- foreach (Gtk.Widget widget in get_children ()) {
999- if (widget.get_parent () != null)
1000- remove (widget);
1001- widget.destroy ();
1002+ foreach (Gtk.Grid grid in grids.values) {
1003+ foreach (Gtk.Widget widget in grid.get_children ()) {
1004+ widget.destroy ();
1005+ }
1006+ grid.destroy ();
1007 }
1008+ grids.clear ();
1009
1010 current_row = 0;
1011 current_col = 0;
1012 page.number = 1;
1013-
1014+ create_new_grid ();
1015+ stack.set_visible_child (current_grid);
1016+
1017+ }
1018+
1019+ public Gtk.Widget get_child_at (int column, int row) {
1020+ var col = ((int)(column/page.columns))+1;
1021+
1022+ var grid = grids.get (col);
1023+ return grid.get_child_at (column - (int)page.columns*(col-1), row);
1024 }
1025
1026 public int get_page_columns () {
1027@@ -104,20 +145,34 @@
1028
1029 }
1030
1031- public void fade_all_out () {
1032-
1033- foreach (Gtk.Widget widget in get_children ()) {
1034- ((AppEntry) widget).fade_out ();
1035- }
1036-
1037- }
1038-
1039- public void fade_all_in () {
1040-
1041- foreach (Gtk.Widget widget in get_children ()) {
1042- ((AppEntry) widget).fade_in ();
1043- }
1044-
1045+ public int get_current_page () {
1046+ return int.parse (stack.get_visible_child_name ());
1047+ }
1048+
1049+ public void go_to_next () {
1050+ int page_number = get_current_page ()+1;
1051+ if (page_number <= get_n_pages ())
1052+ stack.set_visible_child_name ("%d".printf (page_number));
1053+
1054+ page_switcher.update_selected ();
1055+ }
1056+
1057+ public void go_to_previous () {
1058+ int page_number = get_current_page ()-1;
1059+ if (page_number > 0)
1060+ stack.set_visible_child_name ("%d".printf (page_number));
1061+
1062+ page_switcher.update_selected ();
1063+ }
1064+
1065+ public void go_to_last () {
1066+ stack.set_visible_child_name ("%d".printf (get_n_pages ()));
1067+ page_switcher.update_selected ();
1068+ }
1069+
1070+ public void go_to_number (int number) {
1071+ stack.set_visible_child_name ("%d".printf (number));
1072+ page_switcher.update_selected ();
1073 }
1074
1075 public void resize (int rows, int columns) {
1076
1077=== modified file 'src/Widgets/SearchView.vala'
1078--- src/Widgets/SearchView.vala 2013-12-26 00:08:04 +0000
1079+++ src/Widgets/SearchView.vala 2014-03-01 15:19:46 +0000
1080@@ -27,11 +27,12 @@
1081
1082 }
1083
1084- public class SearchView : Gtk.Box {
1085+ public class SearchView : Gtk.ScrolledWindow {
1086
1087 private Gee.HashMap<Backend.App, SearchItem> items;
1088 private SeparatorItem separator;
1089 private SearchItem selected_app = null;
1090+ private Gtk.Box main_box;
1091
1092 private int _selected = 0;
1093 public int selected {
1094@@ -63,17 +64,23 @@
1095 private SlingshotView view;
1096
1097 public SearchView (SlingshotView parent) {
1098- orientation = Gtk.Orientation.VERTICAL;
1099-
1100- can_focus = true;
1101- homogeneous = false;
1102+ main_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
1103+ main_box.can_focus = true;
1104+ main_box.homogeneous = false;
1105
1106 this.view = parent;
1107- width_request = view.columns * 130;
1108+ main_box. width_request = view.columns * 130;
1109
1110 items = new Gee.HashMap<Backend.App, SearchItem> ();
1111 separator = new SeparatorItem ();
1112
1113+ var expand_grid = new Gtk.Grid ();
1114+ expand_grid.expand = true;
1115+ var search_grid = new Gtk.Grid ();
1116+ search_grid.orientation = Gtk.Orientation.VERTICAL;
1117+ search_grid.add (main_box);
1118+ search_grid.add (expand_grid);
1119+ add_with_viewport (search_grid);
1120 }
1121
1122 public void add_apps (Gee.ArrayList<Backend.App> apps) {
1123@@ -111,7 +118,7 @@
1124 }
1125
1126 if (!(items[app].in_box)) {
1127- pack_start (items[app], true, true, 0);
1128+ main_box.pack_start (items[app], true, true, 0);
1129 items[app].in_box = true;
1130 items[app].icon_size = 48;
1131 items[app].queue_draw ();
1132@@ -143,10 +150,12 @@
1133 foreach (SearchItem app in items.values) {
1134 app.hide ();
1135 if (app.in_box) {
1136- remove (app);
1137+ main_box.remove (app);
1138 app.in_box = false;
1139 }
1140 }
1141+
1142+ vadjustment.value = vadjustment.lower;
1143 apps_showed = 0;
1144 }
1145
1146@@ -163,7 +172,7 @@
1147 private void show_separator () {
1148
1149 if (!(separator.in_box)) {
1150- pack_start (separator, true, true, 3);
1151+ main_box.pack_start (separator, true, true, 3);
1152 separator.in_box = true;
1153 }
1154 separator.show_all ();
1155@@ -174,7 +183,7 @@
1156
1157 separator.hide ();
1158 if (separator.in_box) {
1159- remove (separator);
1160+ main_box.remove (separator);
1161 separator.in_box = false;
1162 }
1163
1164@@ -185,7 +194,7 @@
1165 if (selected_app != null)
1166 selected_app.unset_state_flags (Gtk.StateFlags.PRELIGHT);
1167
1168- selected_app = (SearchItem) get_children ().nth_data (index);
1169+ selected_app = (SearchItem) main_box.get_children ().nth_data (index);
1170 selected_app.set_state_flags (Gtk.StateFlags.PRELIGHT, false);
1171
1172 }
1173
1174=== modified file 'src/Widgets/Switcher.vala'
1175--- src/Widgets/Switcher.vala 2013-03-10 12:58:37 +0000
1176+++ src/Widgets/Switcher.vala 2014-03-01 15:19:46 +0000
1177@@ -1,6 +1,7 @@
1178 // -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
1179 //
1180 // Copyright (C) 2011-2012 Giulio Collura
1181+// Copyright (C) 2014 Corentin Noël <tintou@mailoo.org>
1182 //
1183 // This program is free software: you can redistribute it and/or modify
1184 // it under the terms of the GNU General Public License as published by
1185@@ -16,78 +17,106 @@
1186 // along with this program. If not, see <http://www.gnu.org/licenses/>.
1187 //
1188
1189-using Gtk;
1190-
1191-namespace Slingshot.Widgets {
1192-
1193- public class Switcher : HBox {
1194-
1195- public signal void active_changed (int active);
1196-
1197- public int size {
1198- get {
1199- return (int) get_children ().length ();
1200- }
1201- }
1202-
1203- public int active = -1;
1204- public int old_active = -1;
1205-
1206- public Switcher (bool with_padding = true) {
1207-
1208- homogeneous = true;
1209- spacing = 2;
1210-
1211- can_focus = false;
1212-
1213- }
1214-
1215- public void append (string label) {
1216-
1217- var button = new ToggleButton.with_label (label);
1218- button.width_request = 30;
1219- button.can_focus = false;
1220- button.get_style_context ().add_class ("switcher");
1221-
1222- button.button_release_event.connect (() => {
1223-
1224- int select = get_children ().index (button);
1225- set_active (select);
1226- return true;
1227-
1228- });
1229-
1230- add (button);
1231- button.show_all ();
1232-
1233- }
1234-
1235- public void set_active (int new_active) {
1236-
1237- if (new_active >= get_children ().length ())
1238- return;
1239-
1240- if (active >= 0)
1241- ((ToggleButton) get_children ().nth_data (active)).set_active (false);
1242-
1243- old_active = active;
1244- active = new_active;
1245- active_changed (new_active);
1246- ((ToggleButton) get_children ().nth_data (active)).set_active (true);
1247-
1248- }
1249-
1250- public void clear_children () {
1251-
1252- foreach (weak Widget button in get_children ()) {
1253- button.hide ();
1254- if (button.get_parent () != null)
1255- remove (button);
1256- }
1257-
1258- old_active = 0;
1259- active = 0;
1260-
1261- }
1262- }
1263-}
1264+public class Slingshot.Widgets.Switcher : Gtk.Box {
1265+
1266+ public int size {
1267+ get {
1268+ return (int) buttons.size;
1269+ }
1270+ }
1271+
1272+ private Gtk.Stack stack;
1273+ private Gee.HashMap<Gtk.Widget, Gtk.ToggleButton> buttons;
1274+
1275+ public Switcher () {
1276+ orientation = Gtk.Orientation.HORIZONTAL;
1277+ spacing = 2;
1278+ can_focus = false;
1279+ buttons = new Gee.HashMap<Gtk.Widget, Gtk.ToggleButton> (null, null);
1280+ pack_start (new Gtk.Grid (), true, true, 0);
1281+ pack_end (new Gtk.Grid (), true, true, 0);
1282+ }
1283+
1284+ public void set_stack (Gtk.Stack stack) {
1285+ if (this.stack != null) {
1286+ clear_children ();
1287+ }
1288+ this.stack = stack;
1289+ populate_switcher ();
1290+ connect_stack_signals ();
1291+ update_selected ();
1292+ }
1293+
1294+ private void add_child (Gtk.Widget widget) {
1295+ var button = new Gtk.ToggleButton.with_label ((buttons.size +1).to_string ());
1296+ button.width_request = 30;
1297+ button.can_focus = false;
1298+ button.get_style_context ().add_class ("switcher");
1299+ button.button_release_event.connect (() => {
1300+ foreach (var entry in buttons.entries) {
1301+ if (entry.value == button)
1302+ on_button_clicked (entry.key);
1303+ entry.value.active = false;
1304+ }
1305+ button.active = true;
1306+ return true;
1307+ });
1308+
1309+ add (button);
1310+ buttons.set (widget, button);
1311+ if (buttons.size == 1)
1312+ button.active = true;
1313+ }
1314+
1315+ public override void show () {
1316+ base.show ();
1317+ if (buttons.size <= 1)
1318+ hide ();
1319+ }
1320+
1321+
1322+ public override void show_all () {
1323+ base.show_all ();
1324+ if (buttons.size <= 1)
1325+ hide ();
1326+ }
1327+
1328+ private void on_button_clicked (Gtk.Widget widget) {
1329+ stack.set_visible_child (widget);
1330+ }
1331+
1332+ private void populate_switcher () {
1333+ foreach (var child in stack.get_children ()) {
1334+ add_child (child);
1335+ }
1336+ }
1337+
1338+ private void on_stack_child_removed (Gtk.Widget widget) {
1339+ var button = buttons.get (widget);
1340+ remove (button);
1341+ buttons.unset (widget);
1342+ }
1343+
1344+ private void connect_stack_signals () {
1345+ stack.add.connect_after (add_child);
1346+ stack.remove.connect_after (on_stack_child_removed);
1347+ }
1348+
1349+ public void clear_children () {
1350+ foreach (weak Gtk.Widget button in get_children ()) {
1351+ button.hide ();
1352+ if (button.get_parent () != null)
1353+ remove (button);
1354+ }
1355+ }
1356+
1357+ public void update_selected () {
1358+ foreach (var entry in buttons.entries) {
1359+ if (entry.key == stack.get_visible_child ()) {
1360+ entry.value.active = true;
1361+ } else {
1362+ entry.value.active = false;
1363+ }
1364+ }
1365+ }
1366+}
1367\ No newline at end of file

Subscribers

People subscribed via source and target branches