Merge lp:~victored/granite/mode-button-fixes into lp:~elementary-pantheon/granite/granite
- mode-button-fixes
- Merge into granite
Proposed by
Victor Martinez
Status: | Merged |
---|---|
Approved by: | xapantu |
Approved revision: | 165 |
Merged at revision: | 167 |
Proposed branch: | lp:~victored/granite/mode-button-fixes |
Merge into: | lp:~elementary-pantheon/granite/granite |
Diff against target: |
424 lines (+243/-111) 2 files modified
data/style/ModeButton.css (+0/-45) lib/Widgets/ModeButton.vala (+243/-66) |
To merge this branch: | bzr merge lp:~victored/granite/mode-button-fixes |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
xapantu | Pending | ||
Review via email: mp+89569@code.launchpad.net |
Commit message
Description of the change
[Granite.
New API functions.
Removed deprecated elements.
To post a comment you must log in.
- 165. By Victor Martinez
-
Make style_provider and widget_style internal
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === removed file 'data/style/ModeButton.css' |
2 | --- data/style/ModeButton.css 2011-09-17 22:51:19 +0000 |
3 | +++ data/style/ModeButton.css 1970-01-01 00:00:00 +0000 |
4 | @@ -1,45 +0,0 @@ |
5 | -/* |
6 | -* Copyright (C) 2011 Giulio Collura |
7 | -* |
8 | -* This program is free software: you can redistribute it and/or modify |
9 | -* it under the terms of the GNU General Public License as published by |
10 | -* the Free Software Foundation, either version 3 of the License, or |
11 | -* (at your option) any later version. |
12 | -* |
13 | -* This program is distributed in the hope that it will be useful, |
14 | -* but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | -* GNU General Public License for more details. |
17 | -* |
18 | -* You should have received a copy of the GNU General Public License |
19 | -* along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | -*/ |
21 | - |
22 | -.modebutton { |
23 | - -GtkToolbar-button-relief: normal; |
24 | - border-radius: 0 0 0 0; |
25 | - border-style: solid; |
26 | - border-width: 1 0 1 1; |
27 | - |
28 | - -unico-outer-stroke-width: 1 0 1 0; |
29 | - -unico-outer-stroke-radius: 0 0 0 0; |
30 | -} |
31 | - |
32 | -.modebutton:active, |
33 | -.modebutton:insensitive { |
34 | - -unico-outer-stroke-width: 1 0 1 0; |
35 | -} |
36 | - |
37 | -.modebutton:nth-child(first) { |
38 | - border-radius: 3 0 0 3; |
39 | - border-width: 1 0 1 1; |
40 | - |
41 | - -unico-outer-stroke-width: 1 0 1 1; |
42 | -} |
43 | - |
44 | -.modebutton:nth-child(last) { |
45 | - border-radius: 0 3 3 0; |
46 | - border-width: 1; |
47 | - |
48 | - -unico-outer-stroke-width: 1 1 1 0; |
49 | -} |
50 | |
51 | === modified file 'lib/Widgets/ModeButton.vala' |
52 | --- lib/Widgets/ModeButton.vala 2011-11-30 18:38:01 +0000 |
53 | +++ lib/Widgets/ModeButton.vala 2012-01-22 04:04:23 +0000 |
54 | @@ -1,34 +1,74 @@ |
55 | -// |
56 | +// |
57 | // Copyright (C) 2008 Christian Hergert <chris@dronelabs.com> |
58 | // Copyright (C) 2011 Giulio Collura |
59 | -// |
60 | +// |
61 | // This program is free software: you can redistribute it and/or modify |
62 | // it under the terms of the GNU General Public License as published by |
63 | // the Free Software Foundation, either version 3 of the License, or |
64 | // (at your option) any later version. |
65 | -// |
66 | +// |
67 | // This program is distributed in the hope that it will be useful, |
68 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
69 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
70 | // GNU General Public License for more details. |
71 | -// |
72 | +// |
73 | // You should have received a copy of the GNU General Public License |
74 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
75 | -// |
76 | +// |
77 | |
78 | using Gtk; |
79 | using Gdk; |
80 | |
81 | namespace Granite.Widgets { |
82 | - |
83 | - public class ModeButton : HBox { |
84 | - |
85 | + |
86 | + public class ModeButton : Gtk.Box { |
87 | + |
88 | public signal void mode_added (int index, Gtk.Widget widget); |
89 | public signal void mode_removed (int index, Gtk.Widget widget); |
90 | public signal void mode_changed (Gtk.Widget widget); |
91 | - static CssProvider style_provider; |
92 | - |
93 | + |
94 | + /* Style properties. Please note that style class names are for internal |
95 | + usage only. Theme developers should use GraniteWidgetsModeButton instead. |
96 | + */ |
97 | + |
98 | + internal static CssProvider style_provider; |
99 | + internal static StyleContext widget_style; |
100 | + |
101 | + private const int style_priority = Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION; |
102 | + |
103 | + private const string STYLESHEET = """ |
104 | + .GraniteModeButton .button { |
105 | + -GtkToolbar-button-relief: normal; |
106 | + border-radius: 0 0 0 0; |
107 | + border-style: solid; |
108 | + border-width: 1 0 1 1; |
109 | + |
110 | + -unico-outer-stroke-width: 1 0 1 0; |
111 | + -unico-outer-stroke-radius: 0 0 0 0; |
112 | + } |
113 | + |
114 | + .GraniteModeButton .button:active, |
115 | + .GraniteModeButton .button:insensitive { |
116 | + -unico-outer-stroke-width: 1 0 1 0; |
117 | + } |
118 | + |
119 | + .GraniteModeButton .button:first-child { |
120 | + border-radius: 3 0 0 3; |
121 | + border-width: 1 0 1 1; |
122 | + |
123 | + -unico-outer-stroke-width: 1 0 1 1; |
124 | + } |
125 | + |
126 | + .GraniteModeButton .button:last-child { |
127 | + border-radius: 0 3 3 0; |
128 | + border-width: 1; |
129 | + |
130 | + -unico-outer-stroke-width: 1 1 1 0; |
131 | + } |
132 | + """; |
133 | + |
134 | private int _selected = -1; |
135 | + |
136 | public int selected { |
137 | get { |
138 | return _selected; |
139 | @@ -37,86 +77,118 @@ |
140 | set_active(value); |
141 | } |
142 | } |
143 | - |
144 | + |
145 | + public uint n_items { |
146 | + get { |
147 | + return get_children().length(); |
148 | + } |
149 | + } |
150 | + |
151 | public ModeButton () { |
152 | - |
153 | - |
154 | - if(style_provider == null) |
155 | + |
156 | + if (style_provider == null) |
157 | { |
158 | style_provider = new CssProvider (); |
159 | try { |
160 | - style_provider.load_from_path (RESOURCES_DIR + "/style/ModeButton.css"); |
161 | + style_provider.load_from_data (STYLESHEET, -1); |
162 | } catch (Error e) { |
163 | - warning ("Could not add css provider. Some widgets will not look as intended. %s", e.message); |
164 | + warning ("GraniteModeButton: %s. The widget will not look as intended", e.message); |
165 | } |
166 | } |
167 | - |
168 | + |
169 | + widget_style = get_style_context (); |
170 | + widget_style.add_class ("GraniteModeButton"); |
171 | + |
172 | homogeneous = true; |
173 | spacing = 0; |
174 | - |
175 | app_paintable = true; |
176 | - set_visual (get_screen ().get_rgba_visual()); |
177 | - |
178 | + set_visual (get_screen().get_rgba_visual()); |
179 | + |
180 | can_focus = true; |
181 | - |
182 | - } |
183 | - |
184 | + } |
185 | + |
186 | + public void append_pixbuf (Gdk.Pixbuf? pixbuf) { |
187 | + if (pixbuf == null) |
188 | + return; |
189 | + |
190 | + var image = new Image.from_pixbuf (pixbuf); |
191 | + append (image); |
192 | + } |
193 | + |
194 | + public void append_text (string? text) { |
195 | + if (text == null) |
196 | + return; |
197 | + |
198 | + append (new Gtk.Label(text)); |
199 | + } |
200 | + |
201 | + /** |
202 | + * This is the recommended function for adding icons to the ModeButton widget. |
203 | + * If you pass the name of a symbolic icon, it will be properly themed for |
204 | + * every state of the widget. That is, it will match the foreground color |
205 | + * defined by the theme for each state (active, prelight, insensitive, etc.) |
206 | + */ |
207 | + public void append_icon (string icon_name, Gtk.IconSize size) { |
208 | + append_mode_button_item (null, icon_name, size); |
209 | + } |
210 | + |
211 | public void append (Gtk.Widget w) { |
212 | - |
213 | - var button = new ToggleButton (); |
214 | - button.add(w); |
215 | - //button.width_request = 30; |
216 | - button.can_focus = false; |
217 | - button.get_style_context ().add_class ("modebutton"); |
218 | - button.get_style_context ().add_class ("raised"); |
219 | - button.get_style_context ().add_provider (style_provider, 600); |
220 | - |
221 | - button.button_press_event.connect (() => { |
222 | - |
223 | - int select = get_children ().index (button); |
224 | - set_active (select); |
225 | - return true; |
226 | - |
227 | - }); |
228 | - |
229 | - add (button); |
230 | - button.show_all (); |
231 | - |
232 | - mode_added((int)get_children ().length (), w); |
233 | - |
234 | - } |
235 | - |
236 | - public void set_active (int new_active) { |
237 | - |
238 | - if (new_active >= get_children ().length () || _selected == new_active) |
239 | + append_mode_button_item (w, null, null); |
240 | + } |
241 | + |
242 | + /** |
243 | + * This function adds the foreground style properties of the given style |
244 | + * context to the widget's icons. This is useful when you want to make the widget |
245 | + * adapt its symbolic icon color to that of the parent in case the GTK+ |
246 | + * theme has not set them correctly. This function only affects the behavior |
247 | + * of icons added with append_icon(). |
248 | + */ |
249 | + public void set_icon_foreground_style (Gtk.StyleContext icon_style) { |
250 | + foreach (weak Widget button in get_children ()) { |
251 | + (button as ModeButtonItem).set_icon_foreground_style (icon_style); |
252 | + } |
253 | + } |
254 | + |
255 | + public void set_active (int new_active_index) { |
256 | + |
257 | + if (new_active_index >= get_children().length () || _selected == new_active_index) |
258 | return; |
259 | - |
260 | + |
261 | if (_selected >= 0) |
262 | - ((ToggleButton) get_children ().nth_data (_selected)).set_active (false); |
263 | - |
264 | - _selected = new_active; |
265 | - ((ToggleButton) get_children ().nth_data (_selected)).set_active (true); |
266 | - mode_changed(((ToggleButton) get_children ().nth_data (_selected)).get_child()); |
267 | - |
268 | - } |
269 | - |
270 | - public new void remove(int number) |
271 | + ((ToggleButton) get_children().nth_data(_selected)).set_active (false); |
272 | + |
273 | + _selected = new_active_index; |
274 | + ((ToggleButton) get_children().nth_data(_selected)).set_active (true); |
275 | + |
276 | + mode_changed(((ToggleButton) get_children().nth_data(_selected)).get_child()); |
277 | + } |
278 | + |
279 | + public void set_item_visible(int index, bool val) { |
280 | + var item = get_children().nth_data(index); |
281 | + if(item == null) |
282 | + return; |
283 | + |
284 | + item.set_no_show_all(!val); |
285 | + item.set_visible(val); |
286 | + } |
287 | + |
288 | + public new void remove(int index) |
289 | { |
290 | - mode_removed(number, (get_children ().nth_data (number) as Gtk.Bin).get_child ()); |
291 | - get_children ().nth_data (number).destroy(); |
292 | + mode_removed(index, (get_children().nth_data(index) as Gtk.Bin).get_child ()); |
293 | + get_children().nth_data(index).destroy(); |
294 | } |
295 | - |
296 | + |
297 | public void clear_children () { |
298 | - |
299 | + |
300 | foreach (weak Widget button in get_children ()) { |
301 | button.hide (); |
302 | if (button.get_parent () != null) |
303 | base.remove (button); |
304 | } |
305 | + |
306 | _selected = -1; |
307 | - |
308 | } |
309 | - |
310 | + |
311 | protected override bool scroll_event (EventScroll ev) { |
312 | if(ev.direction == Gdk.ScrollDirection.DOWN) { |
313 | selected ++; |
314 | @@ -127,6 +199,111 @@ |
315 | |
316 | return false; |
317 | } |
318 | + |
319 | + private void append_mode_button_item (Gtk.Widget? w, string? icon_name, Gtk.IconSize? size) { |
320 | + var button = new ModeButtonItem (); |
321 | + |
322 | + /* Modifying properties */ |
323 | + if (icon_name != null && size != null && w == null) { |
324 | + button.set_icon (icon_name, size); |
325 | + } else { |
326 | + button.add(w); |
327 | + } |
328 | + |
329 | + button.button_press_event.connect (() => { |
330 | + int selected = get_children().index (button); |
331 | + set_active (selected); |
332 | + return true; |
333 | + }); |
334 | + |
335 | + add(button); |
336 | + button.show_all (); |
337 | + |
338 | + mode_added((int)get_children().length(), w); |
339 | + } |
340 | + |
341 | + } |
342 | + |
343 | + private class ModeButtonItem : Gtk.ToggleButton { |
344 | + |
345 | + /* The main purpose of this class is handling icon theming */ |
346 | + |
347 | + private bool has_themed_icon; |
348 | + private StyleContext? icon_style; |
349 | + |
350 | + private string icon_name = ""; |
351 | + private Gtk.IconSize? icon_size = null; |
352 | + |
353 | + private const int style_priority = Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION; |
354 | + |
355 | + public ModeButtonItem () { |
356 | + can_focus = false; |
357 | + has_themed_icon = false; |
358 | + |
359 | + icon_style = null; |
360 | + |
361 | + get_style_context().add_class ("button"); |
362 | + get_style_context().add_class ("raised"); |
363 | + get_style_context().add_provider (ModeButton.style_provider, style_priority); |
364 | + |
365 | + /* We need to track state changes in order to modify the icon */ |
366 | + state_flags_changed.connect ( () => { |
367 | + if (has_themed_icon) |
368 | + load_icon (); |
369 | + }); |
370 | + } |
371 | + |
372 | + public void set_icon_foreground_style (StyleContext? icon_style) { |
373 | + this.icon_style = icon_style; |
374 | + } |
375 | + |
376 | + public new void set_icon (string name, Gtk.IconSize size) { |
377 | + icon_name = name; |
378 | + icon_size = size; |
379 | + |
380 | + has_themed_icon = true; |
381 | + |
382 | + load_icon (); |
383 | + } |
384 | + |
385 | + public new void set_image (Gtk.Image? image) { |
386 | + if (image == null) |
387 | + return; |
388 | + |
389 | + /* Remove previous images */ |
390 | + foreach (weak Widget _image in get_children ()) { |
391 | + if (this.get_parent () != null && _image is Gtk.Image) |
392 | + _image.destroy(); |
393 | + } |
394 | + |
395 | + /* Add new image */ |
396 | + add (image); |
397 | + |
398 | + show_all (); |
399 | + } |
400 | + |
401 | + private void load_icon () { |
402 | + set_image (new Image.from_pixbuf (render_themed_icon())); |
403 | + } |
404 | + |
405 | + private Gdk.Pixbuf? render_themed_icon () { |
406 | + Gdk.Pixbuf? rv = null; |
407 | + |
408 | + int width = 0, height = 0; |
409 | + icon_size_lookup (icon_size, out width, out height); |
410 | + |
411 | + try { |
412 | + var themed_icon = new GLib.ThemedIcon.with_default_fallbacks (icon_name); |
413 | + Gtk.IconInfo? icon_info = IconTheme.get_default().lookup_by_gicon (themed_icon as GLib.Icon, height, Gtk.IconLookupFlags.GENERIC_FALLBACK); |
414 | + if (icon_info != null) |
415 | + rv = icon_info.load_symbolic_for_context (icon_style ?? ModeButton.widget_style); |
416 | + } |
417 | + catch (Error err) { |
418 | + warning ("%s", err.message); |
419 | + } |
420 | + |
421 | + return rv; |
422 | + } |
423 | } |
424 | } |
425 |