Merge lp:~elementary-pantheon/switchboard/flowbox into lp:~elementary-pantheon/switchboard/switchboard

Proposed by Danielle Foré
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
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

To post a comment you must log in.
655. By Danielle Foré

update default size to fit default plugs

656. By Danielle Foré

fix copyright dates in new widgets

Revision history for this message
Adam Bieńkowski (donadigo) wrote :

It works & looks great for me, besides those issues that are pointed out in the description.

review: Approve (testing)
Revision history for this message
Zisu Andrei (matzipan) wrote :
Download full text (3.9 KiB)

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/glib2.0-t9oPgV/glib2.0-2.48.0/./glib/gsequence.c:1186
#1 0x0000000000411e48 in switchboard_category_has_child ()
#2 0x000000000040edd4 in switchboard_category_view_filter_plugs ()
#3 0x000000000040e793 in switchboard_category_view_add_plug ()
#4 0x000000000040e10b in __lambda11_ ()
#5 0x000000000040e15c in ___lambda11__gsource_func ()
#6 0x00007ffff5febfda in g_main_context_dispatch (context=0x666cb0)
    at /build/glib2.0-t9oPgV/glib2.0-2.48.0/./glib/gmain.c:3154
#7 0x00007ffff5febfda in g_main_context_dispatch (context=context@entry=0x666cb0)
    at /build/glib2.0-t9oPgV/glib2.0-2.48.0/./glib/gmain.c:3769
#8 0x00007ffff5fec380 in g_main_context_iterate (context=0x666cb0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at /build/glib2.0-t9oPgV/glib2.0-2.48.0/./glib/gmain.c:3840
#9 0x00007ffff5fec6a2 in g_main_loop_run (loop=0xc96f40)
    at /build/glib2.0-t9oPgV/glib2.0-2.48.0/./glib/gmain.c:4034
#10 0x00007ffff6a9f6f5 in gtk_main () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#11 0x0000000000407640 in _switchboard_switchboard_app_command_line ()
#12 0x0000000000406a62 in switchboard_switchboard_app_real_command_line ()
#13 0x00007ffff1c42e40 in ffi_call_unix64 () at /usr/lib/x86_64-linux-gnu/libffi.so.6
#14 0x00007ffff1c428ab in ffi_call () at /usr/lib/x86_64-linux-gnu/libffi.so.6
#15 0x00007ffff62c3cf5 in g_cclosure_marshal_generic_va (closure=0x70b480, return_value=0x7fffffffd9d0, instance=0xa8e150, args_list=<optimized out>, marshal_data=0x4069e4 <switchboard_switchboard_app_real_command_line>, n_params=1, param_types=0x70b4f0) at /build/glib2.0-t9oPgV/glib2.0-2.48.0/./gobject/gclosure.c:1604
#16 0x00007ffff62c31d4 in _g_closure_invoke_va (closure=closure@entry=0x70b480, return_value=return_value@entry=0x7fffffffd9d0, instance=instance@entry=0xa8e150, args=args@entry=0x7fffffffdaa0, n_params=<optimized out>, param_types=0x70b4f0) at /build/glib2.0-t9oPgV/glib2.0-2.48.0/./gobject/gclosure.c:867
#17 0x00007ffff62dd4b8 in g_signal_emit_valist (instance=0xa8e150, signal_id=<optimized out>, detail=0, var_args=var_args@entry=0x7fffffffdaa0) at /build/glib2.0-t9oPgV/glib2.0-2.48.0/./gobject/gsignal.c:3294
#18 0x00007ffff62de08f in g_signal_emit (instance=instance@entry=0xa8e150, signal_id=<optimized out>, detail=detail@entry=0) at /build/glib2.0-t9oPgV/glib2.0-2.48.0/./gobject/gsignal.c:3441
#19 0x00007ffff65b1a13 in g_application_call_command_line (application=0xa8e150 [SwitchboardSwitchboardApp], arguments=<optimized out>, options=<optimized out>, exit_status=0x7fffffffdcd4)
    at /build/glib2.0-t9oPgV/gl...

Read more...

Revision history for this message
Danielle Foré (danrabbit) wrote :

Hm so it looks like it's throwing a fit over this line:
"foreach (unowned Gtk.Widget child in flowbox.get_children ())"

Revision history for this message
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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'schemas/org.pantheon.switchboard.gschema.xml'
--- schemas/org.pantheon.switchboard.gschema.xml 2015-03-31 02:42:20 +0000
+++ schemas/org.pantheon.switchboard.gschema.xml 2016-05-12 18:08:48 +0000
@@ -11,12 +11,12 @@
11 <description>The saved state of the window.</description>11 <description>The saved state of the window.</description>
12 </key>12 </key>
13 <key name="window-width" type="i">13 <key name="window-width" type="i">
14 <default>920</default>14 <default>950</default>
15 <summary>The saved width of the window.</summary>15 <summary>The saved width of the window.</summary>
16 <description>The saved width of the window. Must be greater than 700, or it will not take effect.</description>16 <description>The saved width of the window. Must be greater than 700, or it will not take effect.</description>
17 </key>17 </key>
18 <key name="window-height" type="i">18 <key name="window-height" type="i">
19 <default>640</default>19 <default>670</default>
20 <summary>The saved height of the window.</summary>20 <summary>The saved height of the window.</summary>
21 <description>The saved height of the window. Must be greater than 400, or it will not take effect.</description>21 <description>The saved height of the window. Must be greater than 400, or it will not take effect.</description>
22 </key>22 </key>
2323
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2016-05-04 01:43:34 +0000
+++ src/CMakeLists.txt 2016-05-12 18:08:48 +0000
@@ -3,6 +3,8 @@
3 CategoryView.vala3 CategoryView.vala
4 PlugsSearch.vala4 PlugsSearch.vala
5 NavigationButton.vala5 NavigationButton.vala
6 Widgets/CategoryFlowBox.vala
7 Widgets/CategoryIcon.vala
6)8)
79
8vala_precompile (CLIENT_VALA_C ${CMAKE_PROJECT_NAME}10vala_precompile (CLIENT_VALA_C ${CMAKE_PROJECT_NAME}
911
=== modified file 'src/CategoryView.vala'
--- src/CategoryView.vala 2016-05-04 01:43:34 +0000
+++ src/CategoryView.vala 2016-05-12 18:08:48 +0000
@@ -1,172 +1,54 @@
1/***1/*
2BEGIN LICENSE2* Copyright (c) 2011-2016 elementary LLC (http://launchpad.net/switchboard)
3Copyright (C) 2011-2012 Avi Romanoff <aviromanoff@gmail.com>3*
4This program is free software: you can redistribute it and/or modify it4* This program is free software; you can redistribute it and/or
5under the terms of the GNU Lesser General Public License version 2.1, as published5* modify it under the terms of the GNU Lesser General Public
6by the Free Software Foundation.6* License as published by the Free Software Foundation; either
77* version 2.1 of the License, or (at your option) any later version.
8This program is distributed in the hope that it will be useful, but8*
9WITHOUT ANY WARRANTY; without even the implied warranties of9* This program is distributed in the hope that it will be useful,
10MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11PURPOSE. See the GNU General Public License for more details.11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1212* General Public License for more details.
13You should have received a copy of the GNU General Public License along13*
14with this program. If not, see <http://www.gnu.org/licenses/>.14* You should have received a copy of the GNU General Public
15END LICENSE15* License along with this program; if not, write to the
16***/16* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17* Boston, MA 02111-1307, USA.
18*
19* Authored by: Avi Romanoff <aviromanoff@gmail.com>
20*/
1721
18namespace Switchboard {22namespace Switchboard {
1923
20 public class CategoryView : Gtk.Grid {24 public class CategoryView : Gtk.Grid {
21
22 public enum Columns {
23 ICON,
24 TEXT,
25 DESCRIPTION,
26 VISIBLE,
27 PLUG,
28 N_COLUMNS
29 }
30
31 const int ITEM_WIDTH = 96;
32
33 public signal void plug_selected (Switchboard.Plug plug);25 public signal void plug_selected (Switchboard.Plug plug);
3426
35 Gtk.IconTheme theme = Gtk.IconTheme.get_default ();27 public Gee.ArrayList <SearchEntry?> plug_search_result;
36 Gtk.Grid personal_grid;28 public Switchboard.Category personal_category;
37 Gtk.Grid hardware_grid;29 public Switchboard.Category hardware_category;
38 Gtk.Grid network_grid;30 public Switchboard.Category network_category;
39 Gtk.Grid system_grid;31 public Switchboard.Category system_category;
40
41 public Gtk.IconView personal_iconview;
42 public Gtk.IconView hardware_iconview;
43 public Gtk.IconView network_iconview;
44 public Gtk.IconView system_iconview;
45 public Gee.ArrayList<SearchEntry?> plug_search_result;
4632
47 private string? plug_to_open = null;33 private string? plug_to_open = null;
48 private PlugsSearch plug_search;34 public PlugsSearch plug_search;
4935
50 public CategoryView (string? plug_to_open = null) {36 public CategoryView (string? plug = null) {
51 this.plug_to_open = plug_to_open;37 orientation = Gtk.Orientation.VERTICAL;
52 setup_category (Switchboard.Plug.Category.PERSONAL, 0);38 plug_to_open = plug;
53 setup_category (Switchboard.Plug.Category.HARDWARE, 1);39
54 setup_category (Switchboard.Plug.Category.NETWORK, 2);40 personal_category = new Switchboard.Category (Switchboard.Plug.Category.PERSONAL);
55 setup_category (Switchboard.Plug.Category.SYSTEM, 3);41 hardware_category = new Switchboard.Category (Switchboard.Plug.Category.HARDWARE);
42 network_category = new Switchboard.Category (Switchboard.Plug.Category.NETWORK);
43 system_category = new Switchboard.Category (Switchboard.Plug.Category.SYSTEM);
44
56 plug_search = new PlugsSearch ();45 plug_search = new PlugsSearch ();
57 plug_search_result = new Gee.ArrayList<SearchEntry?> ();46 plug_search_result = new Gee.ArrayList<SearchEntry?> ();
58 }47
5948 add (personal_category);
60 private void setup_category (Switchboard.Plug.Category category, int i) {49 add (hardware_category);
61 var category_label = new Gtk.Label (get_category_name (category));50 add (network_category);
62 category_label.get_style_context ().add_class ("category-label");51 add (system_category);
63 category_label.halign = Gtk.Align.START;
64
65 var category_plugs = setup_icon_view ();
66 category_plugs.get_style_context ().remove_class (Gtk.STYLE_CLASS_VIEW);
67
68 var grid = new Gtk.Grid ();
69 grid.margin_start = 12;
70 grid.margin_end = 12;
71 grid.column_spacing = 6;
72
73 // Always add a Seperator
74 var h_separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
75 h_separator.set_hexpand (true);
76 grid.attach (category_label, 0, 0, 1, 1);
77 grid.attach (h_separator, 1, 0, 1, 1);
78
79 grid.attach (category_plugs, 0, 1, 2, 1);
80 switch (category) {
81 case Switchboard.Plug.Category.PERSONAL:
82 personal_iconview = category_plugs;
83 personal_grid = grid;
84 break;
85 case Switchboard.Plug.Category.HARDWARE:
86 hardware_iconview = category_plugs;
87 hardware_grid = grid;
88 break;
89 case Switchboard.Plug.Category.NETWORK:
90 network_iconview = category_plugs;
91 network_grid = grid;
92 break;
93 case Switchboard.Plug.Category.SYSTEM:
94 system_iconview = category_plugs;
95 system_grid = grid;
96 break;
97 }
98
99 category_plugs.focus_out_event.connect ((e) => {
100 category_plugs.unselect_all ();
101
102 return false;
103 });
104
105 category_plugs.focus_in_event.connect ((e) => {
106 Gtk.TreePath path;
107
108 if (!category_plugs.get_cursor (out path, null)) {
109 path = new Gtk.TreePath.from_indices (0, -1);
110 }
111 category_plugs.select_path (path);
112
113 return false;
114 });
115
116 category_plugs.keynav_failed.connect ((direction) => {
117 Gtk.IconView new_view = null;
118 Gtk.TreePath path = null;
119 Gtk.TreePath selected_path = null;
120 int smallest_distance = 1000;
121 Gtk.TreeIter iter;
122 int distance;
123
124 if (direction == Gtk.DirectionType.UP) {
125 new_view = get_prev_icon_view (category);
126 if (new_view != null && category_plugs.get_cursor (out path, null)) {
127 var current_column = category_plugs.get_item_column (path);
128 var model = new_view.get_model ();
129
130 model.get_iter_first (out iter);
131 do {
132 path = model.get_path (iter);
133 var next_column = new_view.get_item_column (path);
134 distance = (next_column - current_column).abs ();
135 if (distance <= smallest_distance) {
136 selected_path = path;
137 smallest_distance = distance;
138 }
139 } while (model.iter_next (ref iter));
140 }
141 } else if (direction == Gtk.DirectionType.DOWN) {
142 new_view = get_next_icon_view (category);
143 if (new_view != null && category_plugs.get_cursor (out path, null)) {
144 var current_column = category_plugs.get_item_column (path);
145 var model = new_view.get_model ();
146
147 model.get_iter_first (out iter);
148 do {
149 path = model.get_path (iter);
150 var next_column = new_view.get_item_column (path);
151 distance = (next_column - current_column).abs ();
152 if (distance < smallest_distance) {
153 selected_path = path;
154 smallest_distance = distance;
155 }
156 } while (model.iter_next (ref iter));
157 }
158 }
159
160 if (new_view != null) {
161 new_view.set_cursor (selected_path, null, false);
162 new_view.grab_focus ();
163 return true;
164 }
165
166 return false;
167 });
168
169 attach (grid, 0, i, 1, 1);
170 }52 }
17153
172 public async void load_default_plugs () {54 public async void load_default_plugs () {
@@ -188,32 +70,6 @@
188 });70 });
189 }71 }
19072
191 private Gtk.IconView setup_icon_view () {
192 var store = new Gtk.ListStore (Columns.N_COLUMNS, typeof (Gdk.Pixbuf), typeof (string),
193 typeof(string), typeof(bool), typeof(Switchboard.Plug));
194 store.set_sort_column_id (1, Gtk.SortType.ASCENDING);
195 store.set_sort_column_id (1, Gtk.SortType.ASCENDING);
196
197 var filtered = new Gtk.TreeModelFilter (store, null);
198 filtered.set_visible_column (3);
199 filtered.refilter ();
200
201 var category_plugs = new Gtk.IconView.with_model (filtered);
202 category_plugs.set_item_width (ITEM_WIDTH);
203 category_plugs.set_text_column (Columns.TEXT);
204 category_plugs.set_pixbuf_column (Columns.ICON);
205 category_plugs.set_tooltip_column (Columns.DESCRIPTION);
206 category_plugs.set_hexpand (true);
207 category_plugs.set_selection_mode (Gtk.SelectionMode.SINGLE);
208 category_plugs.set_activate_on_single_click (true);
209
210 category_plugs.item_activated.connect (on_item_activated);
211 var cellrenderer = (Gtk.CellRendererText)category_plugs.get_cells ().nth_data (0);
212 cellrenderer.wrap_mode = Pango.WrapMode.WORD_CHAR;
213
214 return category_plugs;
215 }
216
217 private void plug_visibility_changed (Switchboard.Plug plug) {73 private void plug_visibility_changed (Switchboard.Plug plug) {
218 if (plug.can_show == true) {74 if (plug.can_show == true) {
219 add_plug (plug);75 add_plug (plug);
@@ -221,45 +77,29 @@
221 }77 }
22278
223 public void add_plug (Switchboard.Plug plug) {79 public void add_plug (Switchboard.Plug plug) {
224 if (plug.can_show == false)80 if (plug.can_show == false) {
225 return;81 return;
226 Gtk.TreeIter root;82 }
227 Gtk.TreeModelFilter model_filter;83
84 var icon = new Switchboard.CategoryIcon (plug);
22885
229 switch (plug.category) {86 switch (plug.category) {
230 case Switchboard.Plug.Category.PERSONAL:87 case Switchboard.Plug.Category.PERSONAL:
231 model_filter = (Gtk.TreeModelFilter)personal_iconview.get_model ();88 personal_category.add (icon);
232 personal_grid.show_all ();
233 break;89 break;
234 case Switchboard.Plug.Category.HARDWARE:90 case Switchboard.Plug.Category.HARDWARE:
235 model_filter = (Gtk.TreeModelFilter)hardware_iconview.get_model ();91 hardware_category.add (icon);
236 hardware_grid.show_all ();
237 break;92 break;
238 case Switchboard.Plug.Category.NETWORK:93 case Switchboard.Plug.Category.NETWORK:
239 model_filter = (Gtk.TreeModelFilter)network_iconview.get_model ();94 network_category.add (icon);
240 network_grid.show_all ();
241 break;95 break;
242 case Switchboard.Plug.Category.SYSTEM:96 case Switchboard.Plug.Category.SYSTEM:
243 model_filter = (Gtk.TreeModelFilter)system_iconview.get_model ();97 system_category.add (icon);
244 system_grid.show_all ();
245 break;98 break;
246 default:99 default:
247 return;100 return;
248 }101 }
249102
250 var store = model_filter.child_model as Gtk.ListStore;
251 Gdk.Pixbuf icon_pixbuf = null;
252 try {
253 // FIXME: if we get no icon, we probably dont want that one…
254 icon_pixbuf = theme.load_icon (plug.icon, 32, Gtk.IconLookupFlags.GENERIC_FALLBACK);
255 } catch {
256 critical ("Unable to load plug %s's icon: %s", plug.display_name, plug.icon);
257 return;
258 }
259
260 store.append (out root);
261 store.set (root, Columns.ICON, icon_pixbuf, Columns.TEXT, plug.display_name,
262 Columns.DESCRIPTION, plug.description, Columns.VISIBLE, true, Columns.PLUG, plug);
263 unowned SwitchboardApp app = (SwitchboardApp) GLib.Application.get_default ();103 unowned SwitchboardApp app = (SwitchboardApp) GLib.Application.get_default ();
264 app.search_box.sensitive = true;104 app.search_box.sensitive = true;
265 filter_plugs (app.search_box.get_text ());105 filter_plugs (app.search_box.get_text ());
@@ -274,63 +114,51 @@
274 }114 }
275 }115 }
276116
277
278 // focus to first visible item
279 public void grab_focus_first_icon_view () {117 public void grab_focus_first_icon_view () {
280 Gtk.TreePath first_path = null;118 if (personal_category.has_child ()) {
281119 personal_category.focus_first_child ();
282 if (get_first_visible_path (personal_iconview, out first_path)) {120 } else if (hardware_category.has_child ()) {
283 personal_iconview.grab_focus ();121 hardware_category.focus_first_child ();
284 } else if (get_first_visible_path (hardware_iconview, out first_path)) {122 } else if (network_category.has_child ()) {
285 hardware_iconview.grab_focus ();123 network_category.focus_first_child ();
286 } else if (get_first_visible_path (network_iconview, out first_path)) {124 } else if (system_category.has_child ()) {
287 network_iconview.grab_focus ();125 system_category.focus_first_child ();
288 } else if (get_first_visible_path (system_iconview, out first_path)) {126 }
289 system_iconview.grab_focus ();
290 }
291 }127 }
292128
293 // activate first visible item
294 public void activate_first_item () {129 public void activate_first_item () {
295 Gtk.TreePath first_path = null;130 if (personal_category.has_child ()) {
296131 personal_category.activate_first_child ();
297 if (get_first_visible_path (personal_iconview, out first_path)) {132 } else if (hardware_category.has_child ()) {
298 personal_iconview.item_activated (first_path);133 hardware_category.activate_first_child ();
299 } else if (get_first_visible_path (hardware_iconview, out first_path)){134 } else if (network_category.has_child ()) {
300 hardware_iconview.item_activated (first_path);135 network_category.activate_first_child ();
301 } else if (get_first_visible_path (network_iconview, out first_path)){136 } else if (system_category.has_child ()) {
302 network_iconview.item_activated (first_path);137 system_category.activate_first_child ();
303 } else if (get_first_visible_path (system_iconview, out first_path)){138 }
304 system_iconview.item_activated (first_path);
305 }
306 }
307
308 private bool get_first_visible_path (Gtk.IconView iv, out Gtk.TreePath path) {
309 Gtk.TreePath end;
310
311 return (iv.get_visible_range (out path, out end));
312 }139 }
313140
314 public void filter_plugs (string filter) {141 public void filter_plugs (string filter) {
315
316 var any_found = false;142 var any_found = false;
317 var model_filter = (Gtk.TreeModelFilter) personal_iconview.get_model ();143
318 if (search_by_category (filter, model_filter, personal_grid)) {144 personal_category.filter ();
319 any_found = true;145 hardware_category.filter ();
320 }146 network_category.filter ();
321147 system_category.filter ();
322 model_filter = (Gtk.TreeModelFilter) hardware_iconview.get_model ();148
323 if (search_by_category (filter, model_filter, hardware_grid)) {149 if (personal_category.has_child ()) {
324 any_found = true;150 any_found = true;
325 }151 }
326152
327 model_filter = (Gtk.TreeModelFilter) network_iconview.get_model ();153 if (hardware_category.has_child ()) {
328 if (search_by_category (filter, model_filter, network_grid)) {154 any_found = true;
329 any_found = true;155 }
330 }156
331157 if (network_category.has_child ()) {
332 model_filter = (Gtk.TreeModelFilter) system_iconview.get_model ();158 any_found = true;
333 if (search_by_category (filter, model_filter, system_grid)) {159 }
160
161 if (system_category.has_child ()) {
334 any_found = true;162 any_found = true;
335 }163 }
336164
@@ -342,78 +170,6 @@
342 }170 }
343 }171 }
344172
345 private void deep_search (string filter) {
346 if (plug_search.ready) {
347 plug_search_result.clear ();
348 foreach (var tmp in plug_search.search_entries) {
349 if (tmp.ui_elements.down ().contains (filter.down ())) {
350 plug_search_result.add (tmp);
351 }
352 }
353 }
354 }
355
356 private bool search_by_category (string filter, Gtk.TreeModelFilter model_filter, Gtk.Widget grid) {
357
358 deep_search (filter);
359 var store = model_filter.child_model as Gtk.ListStore;
360 int shown = 0;
361 store.foreach ((model, path, iter) => {
362 string title;
363
364 store.get (iter, Columns.TEXT, out title);
365 bool show_element = false;
366 foreach (var tmp in plug_search_result) {
367 if (tmp.plug_name.down () in title.down ()) {
368 store.set_value (iter, Columns.VISIBLE, true);
369 shown++;
370 show_element = true;
371 }
372 }
373
374 if (filter.down () in title.down ()) {
375 store.set_value (iter, Columns.VISIBLE, true);
376 shown++;
377 } else if (!show_element) {
378 store.set_value (iter, Columns.VISIBLE, false);
379 }
380
381 return false;
382 });
383
384 if (shown == 0) {
385 grid.hide ();
386 return false;
387 } else {
388 grid.show_all ();
389 return true;
390 }
391 }
392
393 public void recalculate_columns () {
394 int columns = personal_iconview.get_columns ();
395 columns = int.max (columns, hardware_iconview.get_columns ());
396 columns = int.max (columns, network_iconview.get_columns ());
397 columns = int.max (columns, system_iconview.get_columns ());
398 personal_iconview.set_columns (columns);
399 hardware_iconview.set_columns (columns);
400 network_iconview.set_columns (columns);
401 system_iconview.set_columns (columns);
402 }
403
404 private void on_item_activated (Gtk.IconView view, Gtk.TreePath path) {
405 GLib.Value plug;
406 Gtk.TreeIter selected_plug;
407 var store = view.get_model ();
408
409 store.get_iter (out selected_plug, path);
410 store.get_value (selected_plug, Columns.PLUG, out plug);
411
412 plug_selected ((Switchboard.Plug) plug.get_object ());
413
414 view.unselect_path (path);
415 }
416
417 public static string? get_category_name (Switchboard.Plug.Category category) {173 public static string? get_category_name (Switchboard.Plug.Category category) {
418 switch (category) {174 switch (category) {
419 case Plug.Category.PERSONAL:175 case Plug.Category.PERSONAL:
@@ -428,55 +184,5 @@
428184
429 return null;185 return null;
430 }186 }
431
432 private Gtk.IconView? get_next_icon_view (Switchboard.Plug.Category category) {
433 if (category == Plug.Category.PERSONAL) {
434 if (hardware_iconview.is_visible ())
435 return hardware_iconview;
436 else
437 category = Plug.Category.HARDWARE;
438 }
439
440 if (category == Plug.Category.HARDWARE) {
441 if (network_iconview.is_visible ())
442 return network_iconview;
443 else
444 category = Plug.Category.NETWORK;
445 }
446
447 if (category == Plug.Category.NETWORK) {
448 if (system_iconview.is_visible ())
449 return system_iconview;
450 else
451 category = Plug.Category.SYSTEM;
452 }
453
454 return null;
455 }
456
457 private Gtk.IconView? get_prev_icon_view (Switchboard.Plug.Category category) {
458 if (category == Plug.Category.SYSTEM) {
459 if (network_iconview.is_visible ())
460 return network_iconview;
461 else
462 category = Plug.Category.NETWORK;
463 }
464
465 if (category == Plug.Category.NETWORK) {
466 if (hardware_iconview.is_visible ())
467 return hardware_iconview;
468 else
469 category = Plug.Category.HARDWARE;
470 }
471
472 if (category == Plug.Category.HARDWARE) {
473 if (personal_iconview.is_visible ())
474 return personal_iconview;
475 else
476 category = Plug.Category.SYSTEM;
477 }
478
479 return null;
480 }
481 }187 }
482}188}
483189
=== modified file 'src/Switchboard.vala'
--- src/Switchboard.vala 2016-05-04 13:49:32 +0000
+++ src/Switchboard.vala 2016-05-12 18:08:48 +0000
@@ -39,7 +39,7 @@
39 private Granite.Widgets.AlertView alert_view;39 private Granite.Widgets.AlertView alert_view;
40 private Gtk.ScrolledWindow category_scrolled;40 private Gtk.ScrolledWindow category_scrolled;
41 private Switchboard.NavigationButton navigation_button;41 private Switchboard.NavigationButton navigation_button;
42 private Switchboard.CategoryView category_view;42 public Switchboard.CategoryView category_view;
4343
44 private Gee.LinkedList <string> loaded_plugs;44 private Gee.LinkedList <string> loaded_plugs;
45 private string all_settings_label = _("All Settings");45 private string all_settings_label = _("All Settings");
@@ -310,9 +310,9 @@
310 navigation_button.hide ();310 navigation_button.hide ();
311311
312 main_window.size_allocate.connect (() => {312 main_window.size_allocate.connect (() => {
313 if (opened_directly)313 if (opened_directly) {
314 search_box.sensitive = false;314 search_box.sensitive = false;
315 category_view.recalculate_columns ();315 }
316 });316 });
317317
318 if (Switchboard.PlugsManager.get_default ().has_plugs () == false) {318 if (Switchboard.PlugsManager.get_default ().has_plugs () == false) {
@@ -504,31 +504,27 @@
504 var category_item = new Dbusmenu.Menuitem ();504 var category_item = new Dbusmenu.Menuitem ();
505 category_item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, CategoryView.get_category_name (category));505 category_item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, CategoryView.get_category_name (category));
506506
507 Gtk.TreeModelFilter model_filter;507 var plugs = new Gee.ArrayList<Plug?> ();
508 switch (category) {508 switch (category) {
509 case Switchboard.Plug.Category.PERSONAL:509 case Switchboard.Plug.Category.PERSONAL:
510 model_filter = (Gtk.TreeModelFilter)category_view.personal_iconview.get_model ();510 plugs = category_view.personal_category.get_plugs ();
511 break;511 break;
512 case Switchboard.Plug.Category.HARDWARE:512 case Switchboard.Plug.Category.HARDWARE:
513 model_filter = (Gtk.TreeModelFilter)category_view.hardware_iconview.get_model ();513 plugs = category_view.hardware_category.get_plugs ();
514 break;514 break;
515 case Switchboard.Plug.Category.NETWORK:515 case Switchboard.Plug.Category.NETWORK:
516 model_filter = (Gtk.TreeModelFilter)category_view.network_iconview.get_model ();516 plugs = category_view.network_category.get_plugs ();
517 break;517 break;
518 case Switchboard.Plug.Category.SYSTEM:518 case Switchboard.Plug.Category.SYSTEM:
519 model_filter = (Gtk.TreeModelFilter)category_view.system_iconview.get_model ();519 plugs = category_view.system_category.get_plugs ();
520 break;520 break;
521 default:521 default:
522 return null;522 return null;
523 }523 }
524524
525 var category_store = model_filter.child_model as Gtk.ListStore;
526 bool empty = true;525 bool empty = true;
527526
528 category_store.foreach ((model, path, iter) => {527 foreach (var plug in plugs) {
529 Switchboard.Plug plug;
530 category_store.get (iter, CategoryView.Columns.PLUG, out plug);
531
532 var item = new Dbusmenu.Menuitem ();528 var item = new Dbusmenu.Menuitem ();
533 item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, plug.display_name);529 item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, plug.display_name);
534530
@@ -541,9 +537,7 @@
541 // Add item to correct category537 // Add item to correct category
542 category_item.child_append (item);538 category_item.child_append (item);
543 empty = false;539 empty = false;
544540 }
545 return false;
546 });
547541
548 return (empty ? null : category_item);542 return (empty ? null : category_item);
549 }543 }
550544
=== added directory 'src/Widgets'
=== added file 'src/Widgets/CategoryFlowBox.vala'
--- src/Widgets/CategoryFlowBox.vala 1970-01-01 00:00:00 +0000
+++ src/Widgets/CategoryFlowBox.vala 2016-05-12 18:08:48 +0000
@@ -0,0 +1,139 @@
1/*
2* Copyright (c) 2016 elementary LLC (http://launchpad.net/switchboard)
3*
4* This program is free software; you can redistribute it and/or
5* modify it under the terms of the GNU General Public
6* License as published by the Free Software Foundation; either
7* version 2 of the License, or (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12* General Public License for more details.
13*
14* You should have received a copy of the GNU General Public
15* License along with this program; if not, write to the
16* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17* Boston, MA 02111-1307, USA.
18*
19*/
20
21namespace Switchboard {
22
23 public class Category : Gtk.Grid {
24
25 private Gtk.FlowBox flowbox;
26
27 public Category (Switchboard.Plug.Category category) {
28 var category_label = new Gtk.Label (Switchboard.CategoryView.get_category_name (category));
29 category_label.get_style_context ().add_class ("category-label");
30 category_label.halign = Gtk.Align.START;
31
32 var h_separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
33 h_separator.set_hexpand (true);
34
35 flowbox = new Gtk.FlowBox ();
36 flowbox.activate_on_single_click = true;
37 flowbox.column_spacing = 12;
38 flowbox.row_spacing = 12;
39 flowbox.homogeneous = true;
40 flowbox.selection_mode = Gtk.SelectionMode.NONE;
41
42 margin_bottom = 12;
43 margin_start = 12;
44 margin_end = 12;
45
46 column_spacing = 3;
47 row_spacing = 6;
48
49 attach (category_label, 0, 0, 1, 1);
50 attach (h_separator, 1, 0, 1, 1);
51 attach (flowbox, 0, 1, 2, 1);
52
53 flowbox.child_activated.connect ((child) => {
54 Switchboard.SwitchboardApp.instance.load_plug (((CategoryIcon) child).plug);
55 });
56
57 flowbox.set_filter_func (plug_filter_func);
58 flowbox.set_sort_func (plug_sort_func);
59 }
60
61 public Gee.ArrayList get_plugs () {
62 var plugs = new Gee.ArrayList<Plug?> ();
63 foreach (unowned Gtk.Widget child in flowbox.get_children ()) {
64 plugs.add (((CategoryIcon) child).plug);
65 }
66 return plugs;
67 }
68
69 public new void add (Gtk.Widget widget) {
70 flowbox.add (widget);
71 }
72
73 public void activate_first_child () {
74 foreach (unowned Gtk.Widget child in flowbox.get_children ()) {
75 if (child.get_child_visible ()) {
76 child.activate ();
77 return;
78 }
79 }
80 }
81
82 public void filter () {
83 flowbox.invalidate_filter ();
84 }
85
86 public void focus_first_child () {
87 flowbox.get_child_at_index (0).grab_focus ();
88 }
89
90 public bool has_child () {
91 if (flowbox.get_child_at_index (0) != null) {
92 foreach (unowned Gtk.Widget child in flowbox.get_children ()) {
93 if (child.get_child_visible ()) {
94 show_all ();
95 return true;
96 }
97 }
98 }
99 hide ();
100 return false;
101 }
102
103 private bool plug_filter_func (Gtk.FlowBoxChild child) {
104 var filter = SwitchboardApp.instance.search_box.get_text ();
105 var plug_name = ((CategoryIcon) child).plug.display_name;
106 var plug_search = SwitchboardApp.instance.category_view.plug_search;
107 var plug_search_result = SwitchboardApp.instance.category_view.plug_search_result;
108
109 if (plug_search.ready) {
110 plug_search_result.clear ();
111
112 foreach (var tmp in plug_search.search_entries) {
113 if (tmp.ui_elements.down ().contains (filter.down ())) {
114 plug_search_result.add (tmp);
115 }
116 }
117
118 foreach (var tmp in plug_search_result) {
119 if (tmp.plug_name.down () in plug_name.down ()) {
120 return true;
121 }
122 }
123 }
124
125 if (filter.down () in plug_name.down ()) {
126 return true;
127 }
128
129 return false;
130 }
131
132 private int plug_sort_func (Gtk.FlowBoxChild child_a, Gtk.FlowBoxChild child_b) {
133 var plug_name_a = ((CategoryIcon) child_a).plug.display_name;
134 var plug_name_b = ((CategoryIcon) child_b).plug.display_name;
135
136 return strcmp (plug_name_a, plug_name_b);
137 }
138 }
139}
0140
=== added file 'src/Widgets/CategoryIcon.vala'
--- src/Widgets/CategoryIcon.vala 1970-01-01 00:00:00 +0000
+++ src/Widgets/CategoryIcon.vala 2016-05-12 18:08:48 +0000
@@ -0,0 +1,51 @@
1/*
2* Copyright (c) 2016 elementary LLC (http://launchpad.net/switchboard)
3*
4* This program is free software; you can redistribute it and/or
5* modify it under the terms of the GNU General Public
6* License as published by the Free Software Foundation; either
7* version 2 of the License, or (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12* General Public License for more details.
13*
14* You should have received a copy of the GNU General Public
15* License along with this program; if not, write to the
16* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17* Boston, MA 02111-1307, USA.
18*
19*/
20
21namespace Switchboard {
22
23 public class CategoryIcon : Gtk.FlowBoxChild {
24
25 public Switchboard.Plug plug;
26
27 public CategoryIcon (Switchboard.Plug plug_item) {
28 plug = plug_item;
29 width_request = 144;
30
31 var icon = new Gtk.Image.from_icon_name (plug.icon, Gtk.IconSize.DND);
32 icon.tooltip_text = plug.description;
33
34 var plug_name = new Gtk.Label (plug.display_name);
35 plug_name.justify = Gtk.Justification.CENTER;
36 plug_name.max_width_chars = 18;
37 plug_name.wrap = true;
38 plug_name.wrap_mode = Pango.WrapMode.WORD_CHAR;
39
40 var layout = new Gtk.Grid ();
41 layout.halign = Gtk.Align.CENTER;
42 layout.margin = 6;
43 layout.orientation = Gtk.Orientation.VERTICAL;
44
45 layout.add (icon);
46 layout.add (plug_name);
47
48 add (layout);
49 }
50 }
51}

Subscribers

People subscribed via source and target branches