Merge lp:~elementary-pantheon/switchboard/flowbox into lp:~elementary-pantheon/switchboard/switchboard
- flowbox
- Merge into switchboard
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Danielle Foré | ||||||||||||
Approved revision: | 656 | ||||||||||||
Merged at revision: | 644 | ||||||||||||
Proposed branch: | lp:~elementary-pantheon/switchboard/flowbox | ||||||||||||
Merge into: | lp:~elementary-pantheon/switchboard/switchboard | ||||||||||||
Diff against target: |
847 lines (+290/-398) 6 files modified
schemas/org.pantheon.switchboard.gschema.xml (+2/-2) src/CMakeLists.txt (+2/-0) src/CategoryView.vala (+86/-380) src/Switchboard.vala (+10/-16) src/Widgets/CategoryFlowBox.vala (+139/-0) src/Widgets/CategoryIcon.vala (+51/-0) |
||||||||||||
To merge this branch: | bzr merge lp:~elementary-pantheon/switchboard/flowbox | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Adam Bieńkowski (community) | testing | Approve | |
Review via email: mp+294295@code.launchpad.net |
Commit message
CategoryView.vala:
* Rewrite the icon views as FlowBoxes
* Update copyright header
Switchboard.vala:
* Code Style
* Update calls to icon views to FlowBoxes
Schemas:
* Update default window size to fit default plug icons
Widgets:
* Add CategoryFlowBox and CategoryIcon widgets
Description of the change
I've been staring at this code long enough to probably not realize if I'm doing dumb things. I have noticed two regressions, but I'm not sure what's causing them:
* Pressing down from search entry skips personal category
* [GLib] g_sequence_get: assertion '!is_end (iter)' failed
- 655. By Danielle Foré
-
update default size to fit default plugs
- 656. By Danielle Foré
-
fix copyright dates in new widgets
Zisu Andrei (matzipan) wrote : | # |
I personally don't like how it splits the distance equally between icons, it leads to a huge gap between them. Furthermore, it seems that even if there is enough space, the Wacom tablet icon in the Hardware flexbox is still saying on a separate line.
It seems if you have two rows of icons in "Personal", it only skips the first row, so it goes to the first icon in the second row. Maybe there's some overlap?
Below is the log of a gdb session where you can see the stacktrace of where that g_sequence_get assert failure is happening:
(gdb) bt
#0 0x00007ffff60063c0 in g_sequence_get (iter=0xc0c4c0)
at /build/
#1 0x0000000000411e48 in switchboard_
#2 0x000000000040edd4 in switchboard_
#3 0x000000000040e793 in switchboard_
#4 0x000000000040e10b in __lambda11_ ()
#5 0x000000000040e15c in ___lambda11_
#6 0x00007ffff5febfda in g_main_
at /build/
#7 0x00007ffff5febfda in g_main_
at /build/
#8 0x00007ffff5fec380 in g_main_
#9 0x00007ffff5fec6a2 in g_main_loop_run (loop=0xc96f40)
at /build/
#10 0x00007ffff6a9f6f5 in gtk_main () at /usr/lib/
#11 0x0000000000407640 in _switchboard_
#12 0x0000000000406a62 in switchboard_
#13 0x00007ffff1c42e40 in ffi_call_unix64 () at /usr/lib/
#14 0x00007ffff1c428ab in ffi_call () at /usr/lib/
#15 0x00007ffff62c3cf5 in g_cclosure_
#16 0x00007ffff62c31d4 in _g_closure_
#17 0x00007ffff62dd4b8 in g_signal_
#18 0x00007ffff62de08f in g_signal_emit (instance=
#19 0x00007ffff65b1a13 in g_application_
at /build/
Danielle Foré (danrabbit) wrote : | # |
Hm so it looks like it's throwing a fit over this line:
"foreach (unowned Gtk.Widget child in flowbox.
Cassidy James Blaede (cassidyjames) wrote : | # |
Can confirm that this solves the HiDPI icon issues. Glorious, crispy icons. Under fairly normal window sizes, it appears to be working as I'd expect.
Preview Diff
1 | === modified file 'schemas/org.pantheon.switchboard.gschema.xml' |
2 | --- schemas/org.pantheon.switchboard.gschema.xml 2015-03-31 02:42:20 +0000 |
3 | +++ schemas/org.pantheon.switchboard.gschema.xml 2016-05-12 18:08:48 +0000 |
4 | @@ -11,12 +11,12 @@ |
5 | <description>The saved state of the window.</description> |
6 | </key> |
7 | <key name="window-width" type="i"> |
8 | - <default>920</default> |
9 | + <default>950</default> |
10 | <summary>The saved width of the window.</summary> |
11 | <description>The saved width of the window. Must be greater than 700, or it will not take effect.</description> |
12 | </key> |
13 | <key name="window-height" type="i"> |
14 | - <default>640</default> |
15 | + <default>670</default> |
16 | <summary>The saved height of the window.</summary> |
17 | <description>The saved height of the window. Must be greater than 400, or it will not take effect.</description> |
18 | </key> |
19 | |
20 | === modified file 'src/CMakeLists.txt' |
21 | --- src/CMakeLists.txt 2016-05-04 01:43:34 +0000 |
22 | +++ src/CMakeLists.txt 2016-05-12 18:08:48 +0000 |
23 | @@ -3,6 +3,8 @@ |
24 | CategoryView.vala |
25 | PlugsSearch.vala |
26 | NavigationButton.vala |
27 | + Widgets/CategoryFlowBox.vala |
28 | + Widgets/CategoryIcon.vala |
29 | ) |
30 | |
31 | vala_precompile (CLIENT_VALA_C ${CMAKE_PROJECT_NAME} |
32 | |
33 | === modified file 'src/CategoryView.vala' |
34 | --- src/CategoryView.vala 2016-05-04 01:43:34 +0000 |
35 | +++ src/CategoryView.vala 2016-05-12 18:08:48 +0000 |
36 | @@ -1,172 +1,54 @@ |
37 | -/*** |
38 | -BEGIN LICENSE |
39 | -Copyright (C) 2011-2012 Avi Romanoff <aviromanoff@gmail.com> |
40 | -This program is free software: you can redistribute it and/or modify it |
41 | -under the terms of the GNU Lesser General Public License version 2.1, as published |
42 | -by the Free Software Foundation. |
43 | - |
44 | -This program is distributed in the hope that it will be useful, but |
45 | -WITHOUT ANY WARRANTY; without even the implied warranties of |
46 | -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
47 | -PURPOSE. See the GNU General Public License for more details. |
48 | - |
49 | -You should have received a copy of the GNU General Public License along |
50 | -with this program. If not, see <http://www.gnu.org/licenses/>. |
51 | -END LICENSE |
52 | -***/ |
53 | +/* |
54 | +* Copyright (c) 2011-2016 elementary LLC (http://launchpad.net/switchboard) |
55 | +* |
56 | +* This program is free software; you can redistribute it and/or |
57 | +* modify it under the terms of the GNU Lesser General Public |
58 | +* License as published by the Free Software Foundation; either |
59 | +* version 2.1 of the License, or (at your option) any later version. |
60 | +* |
61 | +* This program is distributed in the hope that it will be useful, |
62 | +* but WITHOUT ANY WARRANTY; without even the implied warranty of |
63 | +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
64 | +* General Public License for more details. |
65 | +* |
66 | +* You should have received a copy of the GNU General Public |
67 | +* License along with this program; if not, write to the |
68 | +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
69 | +* Boston, MA 02111-1307, USA. |
70 | +* |
71 | +* Authored by: Avi Romanoff <aviromanoff@gmail.com> |
72 | +*/ |
73 | |
74 | namespace Switchboard { |
75 | |
76 | public class CategoryView : Gtk.Grid { |
77 | - |
78 | - public enum Columns { |
79 | - ICON, |
80 | - TEXT, |
81 | - DESCRIPTION, |
82 | - VISIBLE, |
83 | - PLUG, |
84 | - N_COLUMNS |
85 | - } |
86 | - |
87 | - const int ITEM_WIDTH = 96; |
88 | - |
89 | public signal void plug_selected (Switchboard.Plug plug); |
90 | |
91 | - Gtk.IconTheme theme = Gtk.IconTheme.get_default (); |
92 | - Gtk.Grid personal_grid; |
93 | - Gtk.Grid hardware_grid; |
94 | - Gtk.Grid network_grid; |
95 | - Gtk.Grid system_grid; |
96 | - |
97 | - public Gtk.IconView personal_iconview; |
98 | - public Gtk.IconView hardware_iconview; |
99 | - public Gtk.IconView network_iconview; |
100 | - public Gtk.IconView system_iconview; |
101 | - public Gee.ArrayList<SearchEntry?> plug_search_result; |
102 | + public Gee.ArrayList <SearchEntry?> plug_search_result; |
103 | + public Switchboard.Category personal_category; |
104 | + public Switchboard.Category hardware_category; |
105 | + public Switchboard.Category network_category; |
106 | + public Switchboard.Category system_category; |
107 | |
108 | private string? plug_to_open = null; |
109 | - private PlugsSearch plug_search; |
110 | - |
111 | - public CategoryView (string? plug_to_open = null) { |
112 | - this.plug_to_open = plug_to_open; |
113 | - setup_category (Switchboard.Plug.Category.PERSONAL, 0); |
114 | - setup_category (Switchboard.Plug.Category.HARDWARE, 1); |
115 | - setup_category (Switchboard.Plug.Category.NETWORK, 2); |
116 | - setup_category (Switchboard.Plug.Category.SYSTEM, 3); |
117 | + public PlugsSearch plug_search; |
118 | + |
119 | + public CategoryView (string? plug = null) { |
120 | + orientation = Gtk.Orientation.VERTICAL; |
121 | + plug_to_open = plug; |
122 | + |
123 | + personal_category = new Switchboard.Category (Switchboard.Plug.Category.PERSONAL); |
124 | + hardware_category = new Switchboard.Category (Switchboard.Plug.Category.HARDWARE); |
125 | + network_category = new Switchboard.Category (Switchboard.Plug.Category.NETWORK); |
126 | + system_category = new Switchboard.Category (Switchboard.Plug.Category.SYSTEM); |
127 | + |
128 | plug_search = new PlugsSearch (); |
129 | plug_search_result = new Gee.ArrayList<SearchEntry?> (); |
130 | - } |
131 | - |
132 | - private void setup_category (Switchboard.Plug.Category category, int i) { |
133 | - var category_label = new Gtk.Label (get_category_name (category)); |
134 | - category_label.get_style_context ().add_class ("category-label"); |
135 | - category_label.halign = Gtk.Align.START; |
136 | - |
137 | - var category_plugs = setup_icon_view (); |
138 | - category_plugs.get_style_context ().remove_class (Gtk.STYLE_CLASS_VIEW); |
139 | - |
140 | - var grid = new Gtk.Grid (); |
141 | - grid.margin_start = 12; |
142 | - grid.margin_end = 12; |
143 | - grid.column_spacing = 6; |
144 | - |
145 | - // Always add a Seperator |
146 | - var h_separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL); |
147 | - h_separator.set_hexpand (true); |
148 | - grid.attach (category_label, 0, 0, 1, 1); |
149 | - grid.attach (h_separator, 1, 0, 1, 1); |
150 | - |
151 | - grid.attach (category_plugs, 0, 1, 2, 1); |
152 | - switch (category) { |
153 | - case Switchboard.Plug.Category.PERSONAL: |
154 | - personal_iconview = category_plugs; |
155 | - personal_grid = grid; |
156 | - break; |
157 | - case Switchboard.Plug.Category.HARDWARE: |
158 | - hardware_iconview = category_plugs; |
159 | - hardware_grid = grid; |
160 | - break; |
161 | - case Switchboard.Plug.Category.NETWORK: |
162 | - network_iconview = category_plugs; |
163 | - network_grid = grid; |
164 | - break; |
165 | - case Switchboard.Plug.Category.SYSTEM: |
166 | - system_iconview = category_plugs; |
167 | - system_grid = grid; |
168 | - break; |
169 | - } |
170 | - |
171 | - category_plugs.focus_out_event.connect ((e) => { |
172 | - category_plugs.unselect_all (); |
173 | - |
174 | - return false; |
175 | - }); |
176 | - |
177 | - category_plugs.focus_in_event.connect ((e) => { |
178 | - Gtk.TreePath path; |
179 | - |
180 | - if (!category_plugs.get_cursor (out path, null)) { |
181 | - path = new Gtk.TreePath.from_indices (0, -1); |
182 | - } |
183 | - category_plugs.select_path (path); |
184 | - |
185 | - return false; |
186 | - }); |
187 | - |
188 | - category_plugs.keynav_failed.connect ((direction) => { |
189 | - Gtk.IconView new_view = null; |
190 | - Gtk.TreePath path = null; |
191 | - Gtk.TreePath selected_path = null; |
192 | - int smallest_distance = 1000; |
193 | - Gtk.TreeIter iter; |
194 | - int distance; |
195 | - |
196 | - if (direction == Gtk.DirectionType.UP) { |
197 | - new_view = get_prev_icon_view (category); |
198 | - if (new_view != null && category_plugs.get_cursor (out path, null)) { |
199 | - var current_column = category_plugs.get_item_column (path); |
200 | - var model = new_view.get_model (); |
201 | - |
202 | - model.get_iter_first (out iter); |
203 | - do { |
204 | - path = model.get_path (iter); |
205 | - var next_column = new_view.get_item_column (path); |
206 | - distance = (next_column - current_column).abs (); |
207 | - if (distance <= smallest_distance) { |
208 | - selected_path = path; |
209 | - smallest_distance = distance; |
210 | - } |
211 | - } while (model.iter_next (ref iter)); |
212 | - } |
213 | - } else if (direction == Gtk.DirectionType.DOWN) { |
214 | - new_view = get_next_icon_view (category); |
215 | - if (new_view != null && category_plugs.get_cursor (out path, null)) { |
216 | - var current_column = category_plugs.get_item_column (path); |
217 | - var model = new_view.get_model (); |
218 | - |
219 | - model.get_iter_first (out iter); |
220 | - do { |
221 | - path = model.get_path (iter); |
222 | - var next_column = new_view.get_item_column (path); |
223 | - distance = (next_column - current_column).abs (); |
224 | - if (distance < smallest_distance) { |
225 | - selected_path = path; |
226 | - smallest_distance = distance; |
227 | - } |
228 | - } while (model.iter_next (ref iter)); |
229 | - } |
230 | - } |
231 | - |
232 | - if (new_view != null) { |
233 | - new_view.set_cursor (selected_path, null, false); |
234 | - new_view.grab_focus (); |
235 | - return true; |
236 | - } |
237 | - |
238 | - return false; |
239 | - }); |
240 | - |
241 | - attach (grid, 0, i, 1, 1); |
242 | + |
243 | + add (personal_category); |
244 | + add (hardware_category); |
245 | + add (network_category); |
246 | + add (system_category); |
247 | } |
248 | |
249 | public async void load_default_plugs () { |
250 | @@ -188,32 +70,6 @@ |
251 | }); |
252 | } |
253 | |
254 | - private Gtk.IconView setup_icon_view () { |
255 | - var store = new Gtk.ListStore (Columns.N_COLUMNS, typeof (Gdk.Pixbuf), typeof (string), |
256 | - typeof(string), typeof(bool), typeof(Switchboard.Plug)); |
257 | - store.set_sort_column_id (1, Gtk.SortType.ASCENDING); |
258 | - store.set_sort_column_id (1, Gtk.SortType.ASCENDING); |
259 | - |
260 | - var filtered = new Gtk.TreeModelFilter (store, null); |
261 | - filtered.set_visible_column (3); |
262 | - filtered.refilter (); |
263 | - |
264 | - var category_plugs = new Gtk.IconView.with_model (filtered); |
265 | - category_plugs.set_item_width (ITEM_WIDTH); |
266 | - category_plugs.set_text_column (Columns.TEXT); |
267 | - category_plugs.set_pixbuf_column (Columns.ICON); |
268 | - category_plugs.set_tooltip_column (Columns.DESCRIPTION); |
269 | - category_plugs.set_hexpand (true); |
270 | - category_plugs.set_selection_mode (Gtk.SelectionMode.SINGLE); |
271 | - category_plugs.set_activate_on_single_click (true); |
272 | - |
273 | - category_plugs.item_activated.connect (on_item_activated); |
274 | - var cellrenderer = (Gtk.CellRendererText)category_plugs.get_cells ().nth_data (0); |
275 | - cellrenderer.wrap_mode = Pango.WrapMode.WORD_CHAR; |
276 | - |
277 | - return category_plugs; |
278 | - } |
279 | - |
280 | private void plug_visibility_changed (Switchboard.Plug plug) { |
281 | if (plug.can_show == true) { |
282 | add_plug (plug); |
283 | @@ -221,45 +77,29 @@ |
284 | } |
285 | |
286 | public void add_plug (Switchboard.Plug plug) { |
287 | - if (plug.can_show == false) |
288 | + if (plug.can_show == false) { |
289 | return; |
290 | - Gtk.TreeIter root; |
291 | - Gtk.TreeModelFilter model_filter; |
292 | + } |
293 | + |
294 | + var icon = new Switchboard.CategoryIcon (plug); |
295 | |
296 | switch (plug.category) { |
297 | case Switchboard.Plug.Category.PERSONAL: |
298 | - model_filter = (Gtk.TreeModelFilter)personal_iconview.get_model (); |
299 | - personal_grid.show_all (); |
300 | + personal_category.add (icon); |
301 | break; |
302 | case Switchboard.Plug.Category.HARDWARE: |
303 | - model_filter = (Gtk.TreeModelFilter)hardware_iconview.get_model (); |
304 | - hardware_grid.show_all (); |
305 | + hardware_category.add (icon); |
306 | break; |
307 | case Switchboard.Plug.Category.NETWORK: |
308 | - model_filter = (Gtk.TreeModelFilter)network_iconview.get_model (); |
309 | - network_grid.show_all (); |
310 | + network_category.add (icon); |
311 | break; |
312 | case Switchboard.Plug.Category.SYSTEM: |
313 | - model_filter = (Gtk.TreeModelFilter)system_iconview.get_model (); |
314 | - system_grid.show_all (); |
315 | + system_category.add (icon); |
316 | break; |
317 | default: |
318 | return; |
319 | } |
320 | |
321 | - var store = model_filter.child_model as Gtk.ListStore; |
322 | - Gdk.Pixbuf icon_pixbuf = null; |
323 | - try { |
324 | - // FIXME: if we get no icon, we probably dont want that one… |
325 | - icon_pixbuf = theme.load_icon (plug.icon, 32, Gtk.IconLookupFlags.GENERIC_FALLBACK); |
326 | - } catch { |
327 | - critical ("Unable to load plug %s's icon: %s", plug.display_name, plug.icon); |
328 | - return; |
329 | - } |
330 | - |
331 | - store.append (out root); |
332 | - store.set (root, Columns.ICON, icon_pixbuf, Columns.TEXT, plug.display_name, |
333 | - Columns.DESCRIPTION, plug.description, Columns.VISIBLE, true, Columns.PLUG, plug); |
334 | unowned SwitchboardApp app = (SwitchboardApp) GLib.Application.get_default (); |
335 | app.search_box.sensitive = true; |
336 | filter_plugs (app.search_box.get_text ()); |
337 | @@ -274,63 +114,51 @@ |
338 | } |
339 | } |
340 | |
341 | - |
342 | - // focus to first visible item |
343 | public void grab_focus_first_icon_view () { |
344 | - Gtk.TreePath first_path = null; |
345 | - |
346 | - if (get_first_visible_path (personal_iconview, out first_path)) { |
347 | - personal_iconview.grab_focus (); |
348 | - } else if (get_first_visible_path (hardware_iconview, out first_path)) { |
349 | - hardware_iconview.grab_focus (); |
350 | - } else if (get_first_visible_path (network_iconview, out first_path)) { |
351 | - network_iconview.grab_focus (); |
352 | - } else if (get_first_visible_path (system_iconview, out first_path)) { |
353 | - system_iconview.grab_focus (); |
354 | - } |
355 | + if (personal_category.has_child ()) { |
356 | + personal_category.focus_first_child (); |
357 | + } else if (hardware_category.has_child ()) { |
358 | + hardware_category.focus_first_child (); |
359 | + } else if (network_category.has_child ()) { |
360 | + network_category.focus_first_child (); |
361 | + } else if (system_category.has_child ()) { |
362 | + system_category.focus_first_child (); |
363 | + } |
364 | } |
365 | |
366 | - // activate first visible item |
367 | public void activate_first_item () { |
368 | - Gtk.TreePath first_path = null; |
369 | - |
370 | - if (get_first_visible_path (personal_iconview, out first_path)) { |
371 | - personal_iconview.item_activated (first_path); |
372 | - } else if (get_first_visible_path (hardware_iconview, out first_path)){ |
373 | - hardware_iconview.item_activated (first_path); |
374 | - } else if (get_first_visible_path (network_iconview, out first_path)){ |
375 | - network_iconview.item_activated (first_path); |
376 | - } else if (get_first_visible_path (system_iconview, out first_path)){ |
377 | - system_iconview.item_activated (first_path); |
378 | - } |
379 | - } |
380 | - |
381 | - private bool get_first_visible_path (Gtk.IconView iv, out Gtk.TreePath path) { |
382 | - Gtk.TreePath end; |
383 | - |
384 | - return (iv.get_visible_range (out path, out end)); |
385 | + if (personal_category.has_child ()) { |
386 | + personal_category.activate_first_child (); |
387 | + } else if (hardware_category.has_child ()) { |
388 | + hardware_category.activate_first_child (); |
389 | + } else if (network_category.has_child ()) { |
390 | + network_category.activate_first_child (); |
391 | + } else if (system_category.has_child ()) { |
392 | + system_category.activate_first_child (); |
393 | + } |
394 | } |
395 | |
396 | public void filter_plugs (string filter) { |
397 | - |
398 | var any_found = false; |
399 | - var model_filter = (Gtk.TreeModelFilter) personal_iconview.get_model (); |
400 | - if (search_by_category (filter, model_filter, personal_grid)) { |
401 | - any_found = true; |
402 | - } |
403 | - |
404 | - model_filter = (Gtk.TreeModelFilter) hardware_iconview.get_model (); |
405 | - if (search_by_category (filter, model_filter, hardware_grid)) { |
406 | - any_found = true; |
407 | - } |
408 | - |
409 | - model_filter = (Gtk.TreeModelFilter) network_iconview.get_model (); |
410 | - if (search_by_category (filter, model_filter, network_grid)) { |
411 | - any_found = true; |
412 | - } |
413 | - |
414 | - model_filter = (Gtk.TreeModelFilter) system_iconview.get_model (); |
415 | - if (search_by_category (filter, model_filter, system_grid)) { |
416 | + |
417 | + personal_category.filter (); |
418 | + hardware_category.filter (); |
419 | + network_category.filter (); |
420 | + system_category.filter (); |
421 | + |
422 | + if (personal_category.has_child ()) { |
423 | + any_found = true; |
424 | + } |
425 | + |
426 | + if (hardware_category.has_child ()) { |
427 | + any_found = true; |
428 | + } |
429 | + |
430 | + if (network_category.has_child ()) { |
431 | + any_found = true; |
432 | + } |
433 | + |
434 | + if (system_category.has_child ()) { |
435 | any_found = true; |
436 | } |
437 | |
438 | @@ -342,78 +170,6 @@ |
439 | } |
440 | } |
441 | |
442 | - private void deep_search (string filter) { |
443 | - if (plug_search.ready) { |
444 | - plug_search_result.clear (); |
445 | - foreach (var tmp in plug_search.search_entries) { |
446 | - if (tmp.ui_elements.down ().contains (filter.down ())) { |
447 | - plug_search_result.add (tmp); |
448 | - } |
449 | - } |
450 | - } |
451 | - } |
452 | - |
453 | - private bool search_by_category (string filter, Gtk.TreeModelFilter model_filter, Gtk.Widget grid) { |
454 | - |
455 | - deep_search (filter); |
456 | - var store = model_filter.child_model as Gtk.ListStore; |
457 | - int shown = 0; |
458 | - store.foreach ((model, path, iter) => { |
459 | - string title; |
460 | - |
461 | - store.get (iter, Columns.TEXT, out title); |
462 | - bool show_element = false; |
463 | - foreach (var tmp in plug_search_result) { |
464 | - if (tmp.plug_name.down () in title.down ()) { |
465 | - store.set_value (iter, Columns.VISIBLE, true); |
466 | - shown++; |
467 | - show_element = true; |
468 | - } |
469 | - } |
470 | - |
471 | - if (filter.down () in title.down ()) { |
472 | - store.set_value (iter, Columns.VISIBLE, true); |
473 | - shown++; |
474 | - } else if (!show_element) { |
475 | - store.set_value (iter, Columns.VISIBLE, false); |
476 | - } |
477 | - |
478 | - return false; |
479 | - }); |
480 | - |
481 | - if (shown == 0) { |
482 | - grid.hide (); |
483 | - return false; |
484 | - } else { |
485 | - grid.show_all (); |
486 | - return true; |
487 | - } |
488 | - } |
489 | - |
490 | - public void recalculate_columns () { |
491 | - int columns = personal_iconview.get_columns (); |
492 | - columns = int.max (columns, hardware_iconview.get_columns ()); |
493 | - columns = int.max (columns, network_iconview.get_columns ()); |
494 | - columns = int.max (columns, system_iconview.get_columns ()); |
495 | - personal_iconview.set_columns (columns); |
496 | - hardware_iconview.set_columns (columns); |
497 | - network_iconview.set_columns (columns); |
498 | - system_iconview.set_columns (columns); |
499 | - } |
500 | - |
501 | - private void on_item_activated (Gtk.IconView view, Gtk.TreePath path) { |
502 | - GLib.Value plug; |
503 | - Gtk.TreeIter selected_plug; |
504 | - var store = view.get_model (); |
505 | - |
506 | - store.get_iter (out selected_plug, path); |
507 | - store.get_value (selected_plug, Columns.PLUG, out plug); |
508 | - |
509 | - plug_selected ((Switchboard.Plug) plug.get_object ()); |
510 | - |
511 | - view.unselect_path (path); |
512 | - } |
513 | - |
514 | public static string? get_category_name (Switchboard.Plug.Category category) { |
515 | switch (category) { |
516 | case Plug.Category.PERSONAL: |
517 | @@ -428,55 +184,5 @@ |
518 | |
519 | return null; |
520 | } |
521 | - |
522 | - private Gtk.IconView? get_next_icon_view (Switchboard.Plug.Category category) { |
523 | - if (category == Plug.Category.PERSONAL) { |
524 | - if (hardware_iconview.is_visible ()) |
525 | - return hardware_iconview; |
526 | - else |
527 | - category = Plug.Category.HARDWARE; |
528 | - } |
529 | - |
530 | - if (category == Plug.Category.HARDWARE) { |
531 | - if (network_iconview.is_visible ()) |
532 | - return network_iconview; |
533 | - else |
534 | - category = Plug.Category.NETWORK; |
535 | - } |
536 | - |
537 | - if (category == Plug.Category.NETWORK) { |
538 | - if (system_iconview.is_visible ()) |
539 | - return system_iconview; |
540 | - else |
541 | - category = Plug.Category.SYSTEM; |
542 | - } |
543 | - |
544 | - return null; |
545 | - } |
546 | - |
547 | - private Gtk.IconView? get_prev_icon_view (Switchboard.Plug.Category category) { |
548 | - if (category == Plug.Category.SYSTEM) { |
549 | - if (network_iconview.is_visible ()) |
550 | - return network_iconview; |
551 | - else |
552 | - category = Plug.Category.NETWORK; |
553 | - } |
554 | - |
555 | - if (category == Plug.Category.NETWORK) { |
556 | - if (hardware_iconview.is_visible ()) |
557 | - return hardware_iconview; |
558 | - else |
559 | - category = Plug.Category.HARDWARE; |
560 | - } |
561 | - |
562 | - if (category == Plug.Category.HARDWARE) { |
563 | - if (personal_iconview.is_visible ()) |
564 | - return personal_iconview; |
565 | - else |
566 | - category = Plug.Category.SYSTEM; |
567 | - } |
568 | - |
569 | - return null; |
570 | - } |
571 | } |
572 | } |
573 | |
574 | === modified file 'src/Switchboard.vala' |
575 | --- src/Switchboard.vala 2016-05-04 13:49:32 +0000 |
576 | +++ src/Switchboard.vala 2016-05-12 18:08:48 +0000 |
577 | @@ -39,7 +39,7 @@ |
578 | private Granite.Widgets.AlertView alert_view; |
579 | private Gtk.ScrolledWindow category_scrolled; |
580 | private Switchboard.NavigationButton navigation_button; |
581 | - private Switchboard.CategoryView category_view; |
582 | + public Switchboard.CategoryView category_view; |
583 | |
584 | private Gee.LinkedList <string> loaded_plugs; |
585 | private string all_settings_label = _("All Settings"); |
586 | @@ -310,9 +310,9 @@ |
587 | navigation_button.hide (); |
588 | |
589 | main_window.size_allocate.connect (() => { |
590 | - if (opened_directly) |
591 | + if (opened_directly) { |
592 | search_box.sensitive = false; |
593 | - category_view.recalculate_columns (); |
594 | + } |
595 | }); |
596 | |
597 | if (Switchboard.PlugsManager.get_default ().has_plugs () == false) { |
598 | @@ -504,31 +504,27 @@ |
599 | var category_item = new Dbusmenu.Menuitem (); |
600 | category_item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, CategoryView.get_category_name (category)); |
601 | |
602 | - Gtk.TreeModelFilter model_filter; |
603 | + var plugs = new Gee.ArrayList<Plug?> (); |
604 | switch (category) { |
605 | case Switchboard.Plug.Category.PERSONAL: |
606 | - model_filter = (Gtk.TreeModelFilter)category_view.personal_iconview.get_model (); |
607 | + plugs = category_view.personal_category.get_plugs (); |
608 | break; |
609 | case Switchboard.Plug.Category.HARDWARE: |
610 | - model_filter = (Gtk.TreeModelFilter)category_view.hardware_iconview.get_model (); |
611 | + plugs = category_view.hardware_category.get_plugs (); |
612 | break; |
613 | case Switchboard.Plug.Category.NETWORK: |
614 | - model_filter = (Gtk.TreeModelFilter)category_view.network_iconview.get_model (); |
615 | + plugs = category_view.network_category.get_plugs (); |
616 | break; |
617 | case Switchboard.Plug.Category.SYSTEM: |
618 | - model_filter = (Gtk.TreeModelFilter)category_view.system_iconview.get_model (); |
619 | + plugs = category_view.system_category.get_plugs (); |
620 | break; |
621 | default: |
622 | return null; |
623 | } |
624 | |
625 | - var category_store = model_filter.child_model as Gtk.ListStore; |
626 | bool empty = true; |
627 | |
628 | - category_store.foreach ((model, path, iter) => { |
629 | - Switchboard.Plug plug; |
630 | - category_store.get (iter, CategoryView.Columns.PLUG, out plug); |
631 | - |
632 | + foreach (var plug in plugs) { |
633 | var item = new Dbusmenu.Menuitem (); |
634 | item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, plug.display_name); |
635 | |
636 | @@ -541,9 +537,7 @@ |
637 | // Add item to correct category |
638 | category_item.child_append (item); |
639 | empty = false; |
640 | - |
641 | - return false; |
642 | - }); |
643 | + } |
644 | |
645 | return (empty ? null : category_item); |
646 | } |
647 | |
648 | === added directory 'src/Widgets' |
649 | === added file 'src/Widgets/CategoryFlowBox.vala' |
650 | --- src/Widgets/CategoryFlowBox.vala 1970-01-01 00:00:00 +0000 |
651 | +++ src/Widgets/CategoryFlowBox.vala 2016-05-12 18:08:48 +0000 |
652 | @@ -0,0 +1,139 @@ |
653 | +/* |
654 | +* Copyright (c) 2016 elementary LLC (http://launchpad.net/switchboard) |
655 | +* |
656 | +* This program is free software; you can redistribute it and/or |
657 | +* modify it under the terms of the GNU General Public |
658 | +* License as published by the Free Software Foundation; either |
659 | +* version 2 of the License, or (at your option) any later version. |
660 | +* |
661 | +* This program is distributed in the hope that it will be useful, |
662 | +* but WITHOUT ANY WARRANTY; without even the implied warranty of |
663 | +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
664 | +* General Public License for more details. |
665 | +* |
666 | +* You should have received a copy of the GNU General Public |
667 | +* License along with this program; if not, write to the |
668 | +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
669 | +* Boston, MA 02111-1307, USA. |
670 | +* |
671 | +*/ |
672 | + |
673 | +namespace Switchboard { |
674 | + |
675 | + public class Category : Gtk.Grid { |
676 | + |
677 | + private Gtk.FlowBox flowbox; |
678 | + |
679 | + public Category (Switchboard.Plug.Category category) { |
680 | + var category_label = new Gtk.Label (Switchboard.CategoryView.get_category_name (category)); |
681 | + category_label.get_style_context ().add_class ("category-label"); |
682 | + category_label.halign = Gtk.Align.START; |
683 | + |
684 | + var h_separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL); |
685 | + h_separator.set_hexpand (true); |
686 | + |
687 | + flowbox = new Gtk.FlowBox (); |
688 | + flowbox.activate_on_single_click = true; |
689 | + flowbox.column_spacing = 12; |
690 | + flowbox.row_spacing = 12; |
691 | + flowbox.homogeneous = true; |
692 | + flowbox.selection_mode = Gtk.SelectionMode.NONE; |
693 | + |
694 | + margin_bottom = 12; |
695 | + margin_start = 12; |
696 | + margin_end = 12; |
697 | + |
698 | + column_spacing = 3; |
699 | + row_spacing = 6; |
700 | + |
701 | + attach (category_label, 0, 0, 1, 1); |
702 | + attach (h_separator, 1, 0, 1, 1); |
703 | + attach (flowbox, 0, 1, 2, 1); |
704 | + |
705 | + flowbox.child_activated.connect ((child) => { |
706 | + Switchboard.SwitchboardApp.instance.load_plug (((CategoryIcon) child).plug); |
707 | + }); |
708 | + |
709 | + flowbox.set_filter_func (plug_filter_func); |
710 | + flowbox.set_sort_func (plug_sort_func); |
711 | + } |
712 | + |
713 | + public Gee.ArrayList get_plugs () { |
714 | + var plugs = new Gee.ArrayList<Plug?> (); |
715 | + foreach (unowned Gtk.Widget child in flowbox.get_children ()) { |
716 | + plugs.add (((CategoryIcon) child).plug); |
717 | + } |
718 | + return plugs; |
719 | + } |
720 | + |
721 | + public new void add (Gtk.Widget widget) { |
722 | + flowbox.add (widget); |
723 | + } |
724 | + |
725 | + public void activate_first_child () { |
726 | + foreach (unowned Gtk.Widget child in flowbox.get_children ()) { |
727 | + if (child.get_child_visible ()) { |
728 | + child.activate (); |
729 | + return; |
730 | + } |
731 | + } |
732 | + } |
733 | + |
734 | + public void filter () { |
735 | + flowbox.invalidate_filter (); |
736 | + } |
737 | + |
738 | + public void focus_first_child () { |
739 | + flowbox.get_child_at_index (0).grab_focus (); |
740 | + } |
741 | + |
742 | + public bool has_child () { |
743 | + if (flowbox.get_child_at_index (0) != null) { |
744 | + foreach (unowned Gtk.Widget child in flowbox.get_children ()) { |
745 | + if (child.get_child_visible ()) { |
746 | + show_all (); |
747 | + return true; |
748 | + } |
749 | + } |
750 | + } |
751 | + hide (); |
752 | + return false; |
753 | + } |
754 | + |
755 | + private bool plug_filter_func (Gtk.FlowBoxChild child) { |
756 | + var filter = SwitchboardApp.instance.search_box.get_text (); |
757 | + var plug_name = ((CategoryIcon) child).plug.display_name; |
758 | + var plug_search = SwitchboardApp.instance.category_view.plug_search; |
759 | + var plug_search_result = SwitchboardApp.instance.category_view.plug_search_result; |
760 | + |
761 | + if (plug_search.ready) { |
762 | + plug_search_result.clear (); |
763 | + |
764 | + foreach (var tmp in plug_search.search_entries) { |
765 | + if (tmp.ui_elements.down ().contains (filter.down ())) { |
766 | + plug_search_result.add (tmp); |
767 | + } |
768 | + } |
769 | + |
770 | + foreach (var tmp in plug_search_result) { |
771 | + if (tmp.plug_name.down () in plug_name.down ()) { |
772 | + return true; |
773 | + } |
774 | + } |
775 | + } |
776 | + |
777 | + if (filter.down () in plug_name.down ()) { |
778 | + return true; |
779 | + } |
780 | + |
781 | + return false; |
782 | + } |
783 | + |
784 | + private int plug_sort_func (Gtk.FlowBoxChild child_a, Gtk.FlowBoxChild child_b) { |
785 | + var plug_name_a = ((CategoryIcon) child_a).plug.display_name; |
786 | + var plug_name_b = ((CategoryIcon) child_b).plug.display_name; |
787 | + |
788 | + return strcmp (plug_name_a, plug_name_b); |
789 | + } |
790 | + } |
791 | +} |
792 | |
793 | === added file 'src/Widgets/CategoryIcon.vala' |
794 | --- src/Widgets/CategoryIcon.vala 1970-01-01 00:00:00 +0000 |
795 | +++ src/Widgets/CategoryIcon.vala 2016-05-12 18:08:48 +0000 |
796 | @@ -0,0 +1,51 @@ |
797 | +/* |
798 | +* Copyright (c) 2016 elementary LLC (http://launchpad.net/switchboard) |
799 | +* |
800 | +* This program is free software; you can redistribute it and/or |
801 | +* modify it under the terms of the GNU General Public |
802 | +* License as published by the Free Software Foundation; either |
803 | +* version 2 of the License, or (at your option) any later version. |
804 | +* |
805 | +* This program is distributed in the hope that it will be useful, |
806 | +* but WITHOUT ANY WARRANTY; without even the implied warranty of |
807 | +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
808 | +* General Public License for more details. |
809 | +* |
810 | +* You should have received a copy of the GNU General Public |
811 | +* License along with this program; if not, write to the |
812 | +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
813 | +* Boston, MA 02111-1307, USA. |
814 | +* |
815 | +*/ |
816 | + |
817 | +namespace Switchboard { |
818 | + |
819 | + public class CategoryIcon : Gtk.FlowBoxChild { |
820 | + |
821 | + public Switchboard.Plug plug; |
822 | + |
823 | + public CategoryIcon (Switchboard.Plug plug_item) { |
824 | + plug = plug_item; |
825 | + width_request = 144; |
826 | + |
827 | + var icon = new Gtk.Image.from_icon_name (plug.icon, Gtk.IconSize.DND); |
828 | + icon.tooltip_text = plug.description; |
829 | + |
830 | + var plug_name = new Gtk.Label (plug.display_name); |
831 | + plug_name.justify = Gtk.Justification.CENTER; |
832 | + plug_name.max_width_chars = 18; |
833 | + plug_name.wrap = true; |
834 | + plug_name.wrap_mode = Pango.WrapMode.WORD_CHAR; |
835 | + |
836 | + var layout = new Gtk.Grid (); |
837 | + layout.halign = Gtk.Align.CENTER; |
838 | + layout.margin = 6; |
839 | + layout.orientation = Gtk.Orientation.VERTICAL; |
840 | + |
841 | + layout.add (icon); |
842 | + layout.add (plug_name); |
843 | + |
844 | + add (layout); |
845 | + } |
846 | + } |
847 | +} |
It works & looks great for me, besides those issues that are pointed out in the description.