Merge lp:~ted/libdbusmenu/imageitem into lp:libdbusmenu/0.5
- imageitem
- Merge into trunk
Proposed by
Ted Gould
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~ted/libdbusmenu/imageitem |
Merge into: | lp:libdbusmenu/0.5 |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~ted/libdbusmenu/imageitem |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cody Russell (community) | Approve | ||
Review via email: mp+11141@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Ted Gould (ted) wrote : | # |
Revision history for this message
Cody Russell (bratsche) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2009-07-01 05:34:05 +0000 |
3 | +++ .bzrignore 2009-09-02 18:29:01 +0000 |
4 | @@ -41,3 +41,4 @@ |
5 | dbusmenu.py |
6 | mago.results |
7 | test-glib-simple-items |
8 | +libdbusmenu-gtk/libdbusmenu_gtk_la-menuitem.lo |
9 | |
10 | === modified file 'libdbusmenu-gtk/Makefile.am' |
11 | --- libdbusmenu-gtk/Makefile.am 2009-06-24 04:05:44 +0000 |
12 | +++ libdbusmenu-gtk/Makefile.am 2009-09-02 18:29:01 +0000 |
13 | @@ -9,13 +9,16 @@ |
14 | |
15 | libdbusmenu_gtkinclude_HEADERS = \ |
16 | client.h \ |
17 | - menu.h |
18 | + menu.h \ |
19 | + menuitem.h |
20 | |
21 | libdbusmenu_gtk_la_SOURCES = \ |
22 | client.h \ |
23 | client.c \ |
24 | menu.h \ |
25 | - menu.c |
26 | + menu.c \ |
27 | + menuitem.h \ |
28 | + menuitem.c |
29 | |
30 | libdbusmenu_gtk_la_LDFLAGS = \ |
31 | -version-info $(LIBDBUSMENU_CURRENT):$(LIBDBUSMENU_REVISION):$(LIBDBUSMENU_AGE) \ |
32 | |
33 | === modified file 'libdbusmenu-gtk/client.c' |
34 | --- libdbusmenu-gtk/client.c 2009-08-27 13:45:49 +0000 |
35 | +++ libdbusmenu-gtk/client.c 2009-09-03 17:12:18 +0000 |
36 | @@ -33,6 +33,7 @@ |
37 | #include <gtk/gtk.h> |
38 | |
39 | #include "client.h" |
40 | +#include "menuitem.h" |
41 | |
42 | /* Prototypes */ |
43 | static void dbusmenu_gtkclient_class_init (DbusmenuGtkClientClass *klass); |
44 | @@ -284,6 +285,8 @@ |
45 | return mi; |
46 | } |
47 | |
48 | +/* The base type handler that builds a plain ol' |
49 | + GtkMenuItem to represent, well, the GtkMenuItem */ |
50 | static gboolean |
51 | new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) |
52 | { |
53 | @@ -303,6 +306,8 @@ |
54 | return TRUE; |
55 | } |
56 | |
57 | +/* Type handler for the seperators where it builds |
58 | + a GtkSeparator to act as the GtkMenuItem */ |
59 | static gboolean |
60 | new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) |
61 | { |
62 | @@ -322,9 +327,124 @@ |
63 | return TRUE; |
64 | } |
65 | |
66 | +/* This handler looks at property changes for items that are |
67 | + image menu items. */ |
68 | +static void |
69 | +image_property_handle (DbusmenuMenuitem * item, const gchar * property, const gchar * value, gpointer userdata) |
70 | +{ |
71 | + /* We're only looking at these two properties here */ |
72 | + g_return_if_fail(!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON) || !g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON_DATA)); |
73 | + |
74 | + if (value == NULL || value[0] == '\0') { |
75 | + /* This means that we're unsetting a value. */ |
76 | + /* Try to use the other one */ |
77 | + if (g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON)) { |
78 | + property = DBUSMENU_MENUITEM_PROP_ICON_DATA; |
79 | + } else { |
80 | + property = DBUSMENU_MENUITEM_PROP_ICON; |
81 | + } |
82 | + } |
83 | + |
84 | + /* Grab the data of the items that we've got, so that |
85 | + we can know how things need to change. */ |
86 | + GtkMenuItem * gimi = dbusmenu_gtkclient_menuitem_get (DBUSMENU_GTKCLIENT(userdata), item); |
87 | + if (gimi == NULL) { |
88 | + g_warning("Oddly we're handling image properties on a menuitem that doesn't have any GTK structures associated with it."); |
89 | + return; |
90 | + } |
91 | + GtkWidget * gtkimage = gtk_image_menu_item_get_image(GTK_IMAGE_MENU_ITEM(gimi)); |
92 | + |
93 | + if (!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON_DATA)) { |
94 | + /* If we have an image already built from a name that is |
95 | + way better than a pixbuf. Keep it. */ |
96 | + if (gtk_image_get_storage_type(GTK_IMAGE(gtkimage)) == GTK_IMAGE_ICON_NAME) { |
97 | + return; |
98 | + } |
99 | + } |
100 | + |
101 | + /* Now figure out what to change */ |
102 | + if (!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON)) { |
103 | + const gchar * iconname = dbusmenu_menuitem_property_get(item, property); |
104 | + if (iconname == NULL) { |
105 | + /* If there is no name, by golly we want no |
106 | + icon either. */ |
107 | + gtkimage = NULL; |
108 | + } else { |
109 | + /* If we don't have an image, we need to build |
110 | + one so that we can set the name. Otherwise we |
111 | + can just convert it to this name. */ |
112 | + if (gtkimage == NULL) { |
113 | + gtkimage = gtk_image_new_from_icon_name(iconname, GTK_ICON_SIZE_MENU); |
114 | + } else { |
115 | + gtk_image_set_from_icon_name(GTK_IMAGE(gtkimage), iconname, GTK_ICON_SIZE_MENU); |
116 | + } |
117 | + } |
118 | + } else { |
119 | + GdkPixbuf * image = dbusmenu_menuitem_property_get_image(item, property); |
120 | + if (image == NULL) { |
121 | + /* If there is no pixbuf, by golly we want no |
122 | + icon either. */ |
123 | + gtkimage = NULL; |
124 | + } else { |
125 | + /* Resize the pixbuf */ |
126 | + gint width, height; |
127 | + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); |
128 | + if (gdk_pixbuf_get_width(image) > width || |
129 | + gdk_pixbuf_get_height(image) > height) { |
130 | + GdkPixbuf * newimage = gdk_pixbuf_scale_simple(image, |
131 | + width, |
132 | + height, |
133 | + GDK_INTERP_BILINEAR); |
134 | + g_object_unref(image); |
135 | + image = newimage; |
136 | + } |
137 | + |
138 | + /* If we don't have an image, we need to build |
139 | + one so that we can set the pixbuf. */ |
140 | + if (gtkimage == NULL) { |
141 | + gtkimage = gtk_image_new_from_pixbuf(image); |
142 | + } else { |
143 | + gtk_image_set_from_pixbuf(GTK_IMAGE(gtkimage), image); |
144 | + } |
145 | + } |
146 | + |
147 | + } |
148 | + |
149 | + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(gimi), gtkimage); |
150 | + |
151 | + return; |
152 | +} |
153 | + |
154 | +/* This is a type call back for the image type where |
155 | + it uses the GtkImageMenuitem to create the menu item. */ |
156 | static gboolean |
157 | new_item_image (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) |
158 | { |
159 | + g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); |
160 | + g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); |
161 | + /* Note: not checking parent, it's reasonable for it to be NULL */ |
162 | + |
163 | + GtkMenuItem * gmi; |
164 | + gmi = GTK_MENU_ITEM(gtk_image_menu_item_new_with_label(dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_LABEL))); |
165 | + |
166 | + if (gmi != NULL) { |
167 | + dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent); |
168 | + } else { |
169 | + return FALSE; |
170 | + } |
171 | + |
172 | + image_property_handle(newitem, |
173 | + DBUSMENU_MENUITEM_PROP_ICON, |
174 | + dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_ICON), |
175 | + client); |
176 | + image_property_handle(newitem, |
177 | + DBUSMENU_MENUITEM_PROP_ICON_DATA, |
178 | + dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_ICON_DATA), |
179 | + client); |
180 | + g_signal_connect(G_OBJECT(newitem), |
181 | + DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, |
182 | + G_CALLBACK(image_property_handle), |
183 | + client); |
184 | |
185 | return TRUE; |
186 | } |
187 | |
188 | === added file 'libdbusmenu-gtk/menuitem.c' |
189 | --- libdbusmenu-gtk/menuitem.c 1970-01-01 00:00:00 +0000 |
190 | +++ libdbusmenu-gtk/menuitem.c 2009-09-02 18:50:29 +0000 |
191 | @@ -0,0 +1,130 @@ |
192 | +/* |
193 | +A library to take the object model made consistent by libdbusmenu-glib |
194 | +and visualize it in GTK. |
195 | + |
196 | +Copyright 2009 Canonical Ltd. |
197 | + |
198 | +Authors: |
199 | + Ted Gould <ted@canonical.com> |
200 | + |
201 | +This program is free software: you can redistribute it and/or modify it |
202 | +under the terms of either or both of the following licenses: |
203 | + |
204 | +1) the GNU Lesser General Public License version 3, as published by the |
205 | +Free Software Foundation; and/or |
206 | +2) the GNU Lesser General Public License version 2.1, as published by |
207 | +the Free Software Foundation. |
208 | + |
209 | +This program is distributed in the hope that it will be useful, but |
210 | +WITHOUT ANY WARRANTY; without even the implied warranties of |
211 | +MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
212 | +PURPOSE. See the applicable version of the GNU Lesser General Public |
213 | +License for more details. |
214 | + |
215 | +You should have received a copy of both the GNU Lesser General Public |
216 | +License version 3 and version 2.1 along with this program. If not, see |
217 | +<http://www.gnu.org/licenses/> |
218 | +*/ |
219 | + |
220 | +#include "menuitem.h" |
221 | + |
222 | +/** |
223 | + dbusmenu_menuitem_property_set_image: |
224 | + @menuitem: The #DbusmenuMenuitem to set the property on. |
225 | + @property: Name of the property to set. |
226 | + @data: The image to place on the property. |
227 | + |
228 | + This function takes the pixbuf that is stored in @data and |
229 | + turns it into a base64 encoded PNG so that it can be placed |
230 | + onto a standard #DbusmenuMenuitem property. |
231 | + |
232 | + Return value: Whether the function was able to set the property |
233 | + or not. |
234 | +*/ |
235 | +gboolean |
236 | +dbusmenu_menuitem_property_set_image (DbusmenuMenuitem * menuitem, const gchar * property, const GdkPixbuf * data) |
237 | +{ |
238 | + g_return_val_if_fail(GDK_IS_PIXBUF(data), FALSE); |
239 | + g_return_val_if_fail(DBUSMENU_IS_MENUITEM(menuitem), FALSE); |
240 | + g_return_val_if_fail(property != NULL && property[0] != '\0', FALSE); |
241 | + |
242 | + GError * error = NULL; |
243 | + gchar * png_data; |
244 | + gsize png_data_len; |
245 | + |
246 | + if (!gdk_pixbuf_save_to_buffer((GdkPixbuf *)data, &png_data, &png_data_len, "png", &error, NULL)) { |
247 | + if (error == NULL) { |
248 | + g_warning("Unable to create pixbuf data stream: %d", png_data_len); |
249 | + } else { |
250 | + g_warning("Unable to create pixbuf data stream: %s", error->message); |
251 | + g_error_free(error); |
252 | + error = NULL; |
253 | + } |
254 | + |
255 | + return FALSE; |
256 | + } |
257 | + |
258 | + gchar * prop_str = g_base64_encode((guchar *)png_data, png_data_len); |
259 | + gboolean propreturn = FALSE; |
260 | + propreturn = dbusmenu_menuitem_property_set(menuitem, property, prop_str); |
261 | + |
262 | + g_free(prop_str); |
263 | + g_free(png_data); |
264 | + |
265 | + return propreturn; |
266 | +} |
267 | + |
268 | +/** |
269 | + dbusmenu_menuitem_property_get_image: |
270 | + @menuitem: The #DbusmenuMenuite to look for the property on |
271 | + @property: The name of the property to look for. |
272 | + |
273 | + This function looks on the menu item for a property by the |
274 | + name of @property. If one exists it tries to turn it into |
275 | + a #GdkPixbuf. It assumes that the property is a base64 encoded |
276 | + PNG file like the one created by #dbusmenu_menuite_property_set_image. |
277 | + |
278 | + Return value: A pixbuf or #NULL to signal error. |
279 | +*/ |
280 | +GdkPixbuf * |
281 | +dbusmenu_menuitem_property_get_image (DbusmenuMenuitem * menuitem, const gchar * property) |
282 | +{ |
283 | + g_return_val_if_fail(DBUSMENU_IS_MENUITEM(menuitem), NULL); |
284 | + g_return_val_if_fail(property != NULL && property[0] != '\0', NULL); |
285 | + |
286 | + const gchar * value = dbusmenu_menuitem_property_get(menuitem, property); |
287 | + |
288 | + /* There is no icon */ |
289 | + if (value == NULL || value[0] == '\0') { |
290 | + return NULL; |
291 | + } |
292 | + |
293 | + gsize length = 0; |
294 | + guchar * icondata = g_base64_decode(value, &length); |
295 | + |
296 | + GInputStream * input = g_memory_input_stream_new_from_data(icondata, length, NULL); |
297 | + if (input == NULL) { |
298 | + g_warning("Cound not create input stream from icon property data"); |
299 | + g_free(icondata); |
300 | + return NULL; |
301 | + } |
302 | + |
303 | + GError * error = NULL; |
304 | + GdkPixbuf * icon = gdk_pixbuf_new_from_stream(input, NULL, &error); |
305 | + |
306 | + if (error != NULL) { |
307 | + g_warning("Unable to build Pixbuf from icon data: %s", error->message); |
308 | + g_error_free(error); |
309 | + } |
310 | + |
311 | + error = NULL; |
312 | + g_input_stream_close(input, NULL, &error); |
313 | + if (error != NULL) { |
314 | + g_warning("Unable to close input stream: %s", error->message); |
315 | + g_error_free(error); |
316 | + } |
317 | + g_free(icondata); |
318 | + |
319 | + return icon; |
320 | +} |
321 | + |
322 | |
323 | === added file 'libdbusmenu-gtk/menuitem.h' |
324 | --- libdbusmenu-gtk/menuitem.h 1970-01-01 00:00:00 +0000 |
325 | +++ libdbusmenu-gtk/menuitem.h 2009-09-02 18:29:01 +0000 |
326 | @@ -0,0 +1,39 @@ |
327 | +/* |
328 | +A library to take the object model made consistent by libdbusmenu-glib |
329 | +and visualize it in GTK. |
330 | + |
331 | +Copyright 2009 Canonical Ltd. |
332 | + |
333 | +Authors: |
334 | + Ted Gould <ted@canonical.com> |
335 | + |
336 | +This program is free software: you can redistribute it and/or modify it |
337 | +under the terms of either or both of the following licenses: |
338 | + |
339 | +1) the GNU Lesser General Public License version 3, as published by the |
340 | +Free Software Foundation; and/or |
341 | +2) the GNU Lesser General Public License version 2.1, as published by |
342 | +the Free Software Foundation. |
343 | + |
344 | +This program is distributed in the hope that it will be useful, but |
345 | +WITHOUT ANY WARRANTY; without even the implied warranties of |
346 | +MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
347 | +PURPOSE. See the applicable version of the GNU Lesser General Public |
348 | +License for more details. |
349 | + |
350 | +You should have received a copy of both the GNU Lesser General Public |
351 | +License version 3 and version 2.1 along with this program. If not, see |
352 | +<http://www.gnu.org/licenses/> |
353 | +*/ |
354 | + |
355 | +#ifndef __DBUSMENU_GTKMENUITEM_H__ |
356 | +#define __DBUSMENU_GTKMENUITEM_H__ 1 |
357 | + |
358 | +#include <glib.h> |
359 | +#include <gdk-pixbuf/gdk-pixbuf.h> |
360 | +#include <libdbusmenu-glib/menuitem.h> |
361 | + |
362 | +gboolean dbusmenu_menuitem_property_set_image (DbusmenuMenuitem * menuitem, const gchar * property, const GdkPixbuf * data); |
363 | +GdkPixbuf * dbusmenu_menuitem_property_get_image (DbusmenuMenuitem * menuitem, const gchar * property); |
364 | + |
365 | +#endif |
366 | |
367 | === modified file 'tests/test-gtk-label-server.c' |
368 | --- tests/test-gtk-label-server.c 2009-07-20 21:04:00 +0000 |
369 | +++ tests/test-gtk-label-server.c 2009-09-02 20:13:15 +0000 |
370 | @@ -156,7 +156,7 @@ |
371 | server = dbusmenu_server_new("/org/test"); |
372 | |
373 | timer_func(NULL); |
374 | - g_timeout_add_seconds(15, timer_func, NULL); |
375 | + g_timeout_add_seconds(5, timer_func, NULL); |
376 | |
377 | mainloop = g_main_loop_new(NULL, FALSE); |
378 | g_main_loop_run(mainloop); |
379 | |
380 | === modified file 'tests/test-gtk-label.json' |
381 | --- tests/test-gtk-label.json 2009-08-26 20:32:37 +0000 |
382 | +++ tests/test-gtk-label.json 2009-09-03 17:33:32 +0000 |
383 | @@ -154,5 +154,123 @@ |
384 | ] |
385 | }, |
386 | ] |
387 | - } |
388 | + }, |
389 | + {"id": 8, "type": "menuitem", |
390 | + "label": "value1", |
391 | + "submenu": [ |
392 | + {"id": 80, |
393 | + "type": "imageitem", |
394 | + "icon": "face-angel", |
395 | + "label": "angel"}, |
396 | + {"id": 81, |
397 | + "type": "imageitem", |
398 | + "icon": "face-angry", |
399 | + "label": "angry"}, |
400 | + {"id": 82, |
401 | + "type": "imageitem", |
402 | + "icon": "face-cool", |
403 | + "label": "cool"}, |
404 | + {"id": 83, |
405 | + "type":"imageitem", |
406 | + "icon": "face-devilish", |
407 | + "label": "devilish"}, |
408 | + {"id": 84, |
409 | + "type": "imageitem", |
410 | + "icon": "face-embarrassed", |
411 | + "label": "embarrassed"}, |
412 | + {"id": 85, |
413 | + "type": "imageitem", |
414 | + "icon": "face-kiss", |
415 | + "label": "kiss"}, |
416 | + {"id": 86, |
417 | + "type": "imageitem", |
418 | + "icon": "face-laugh", |
419 | + "label": "laugh"}, |
420 | + {"id": 87, |
421 | + "type": "imageitem", |
422 | + "icon": "face-monkey", |
423 | + "label": "monkey"}, |
424 | + {"id": 88, |
425 | + "type": "imageitem", |
426 | + "icon": "face-sad", |
427 | + "label": "sad"}, |
428 | + {"id": 89, |
429 | + "type": "imageitem", |
430 | + "icon": "face-sick", |
431 | + "label": "sick"} |
432 | + ] |
433 | + }, |
434 | + {"id": 9, "type": "menuitem", |
435 | + "label": "value1", |
436 | + "submenu": [ |
437 | + {"id": 90, |
438 | + "type": "imageitem", |
439 | + "icon-data": |
440 | +"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACPUlEQVR4nGJgoBAAAAAA///Ch1gW |
441 | +BzK0LQ5iaGNgYGDBpQgAAAD//8KpeY4/Q9+DCV7/H/S4/p8byDABlyEAAAAA///CqnluAMOEx5O8 |
442 | +/3/f0/P/+47m/4967P7PC2GYysDAwIquGAAAAP//YkLXPC+AodfNyStfRMuegenvdwamP98ZhJWM |
443 | +GJzNzLIWhGMaAgAAAP//YkLT3Odq75InomrBwPT7CwPDr68M//98Y2D+951BREadwdFAL3VxJMNM |
444 | +ZEMAAAAA//9ihPs5gKHPzdo2V0TNkoGZ4T/D//9/GRj+/WJg+PeT4f/vHwwMf78z/P31jeHN89sM |
445 | ++6/dXpS4lCGFgYHhNwAAAP//ghkguDqC4Z0CNwMDLwsDgxAHAwOfdQrD/1+fGP5/e83w/9tbhq/P |
446 | +LjG8+8PA8PkPA8PDbwwMIXMYhBkYGN4BAAAA//80zDEOQDAAAMBLZ2MnITEafEziK2YfM/QBLDoX |
447 | +g4jJPeD+IGJAgypNlrbuvNfBcxLYb/rZiIINK/IHAAD//zTRoRHAIBAAsMAU3X8iZCUSy5W7R0EN |
448 | +rJDcmoEXFU8sVq/ko5SIDQoaJj74AQAA//+CGfADKoEIGZhmZiQ+RM0D5FgAAAAA//9Cj0aEKNRm |
449 | +uGZmrCoZAAAAAP//wm4AskZkg7AAAAAAAP//wpo8n/6A2siEoJ/+wG4AAAAA///CZq4EAwODAZRG |
450 | +Bi8YEIEIBwAAAAD//8JmAAcDA4MAlEYGPxgYGD5AaTgAAAAA//8DAD6xjTP5Y+A7AAAAAElFTkSu |
451 | +QmCC", |
452 | + "label": "up"}, |
453 | + {"id": 91, |
454 | + "type": "imageitem", |
455 | + "icon-data": |
456 | +"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACl0lEQVR4nGJgoBAAAAAA//9ixCLG |
457 | +sSWS4bs0B1QWip/+YGDwWcLAycDA8ANZMQAAAP//YsFigIA0JwODdvIsBob/fxgY/vxk+P/7OwPD |
458 | +6ioGBgYGAQYGhhfIigEAAAD//8JmAAcDEwMDw5/vDAz/fjP8//uLgeHvDwYGJqgcGgAAAAD//8Jm |
459 | +AAMDIwPD/99fGBj+/WVg+PeLgeHvTwYGZqwqGQAAAAD//8JuADMDA8PPLwwMDH8Z/v//AzGACbsB |
460 | +AAAAAP//wmoAJwsDw/8/XxgY/v9l+P/rM8P/ry8ZONmwGwAAAAD//4LFAsfqaIbvCtwMDLxsDAxC |
461 | +7AwMPMqWDP+/Pmf4//01w//fXxm+/2NgePebgeHLHwaGR98ZGIKmQ2IEAAAA//80zisSQFAAAMAd |
462 | +wczzKRSvCIqrO4XqGoIkGTOv+SV7gv1j1XqY2jiI/agoSve2eM7VeyUyQk5X0gT2ZEYNHwAAAP// |
463 | +gnnhb+lWhuk//90TD1dncBThYGBgYWGA+JsRQv9lYGB4/5uBYcdDhotZSxhaGRgY/jEwMDAAAAAA |
464 | +//+CueALAwPDnZrtDK3r7jIcefuHgeEvI5JmRgaG938YGHY9YriatYShkoGB4TYDA8MnBgYGBgAA |
465 | +AAD//4IZ8JuBgeE1AwPDjfLNDE2b7jGcfPsLYutfRgaGD78ZGPY+ZrievpChjIGB4SoDA8NLqB4G |
466 | +AAAAAP//QkesDAwMMgwMDG6TwxnO3q5i+H+nhuH/nESGawwMDF4MDAzyDAwMKPEBAAAA///CZYgs |
467 | +AwODR18kw4UJ0QyX8WkGAAAA///ClpkYoAolGBgYFKBqHjAwMDxnYGD4ha4QAAAA///CZQDMEG4o |
468 | ++ys2zQwMDAwAAAAA//8DAAF5nhyE7tENAAAAAElFTkSuQmCC", |
469 | + "label": "down"}, |
470 | + {"id": 92, |
471 | + "type": "imageitem", |
472 | + "icon": "up", |
473 | + "icon-data": |
474 | +"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACl0lEQVR4nGJgoBAAAAAA//9ixCLG |
475 | +sSWS4bs0B1QWip/+YGDwWcLAycDA8ANZMQAAAP//YsFigIA0JwODdvIsBob/fxgY/vxk+P/7OwPD |
476 | +6ioGBgYGAQYGhhfIigEAAAD//8JmAAcDEwMDw5/vDAz/fjP8//uLgeHvDwYGJqgcGgAAAAD//8Jm |
477 | +AAMDIwPD/99fGBj+/WVg+PeLgeHvTwYGZqwqGQAAAAD//8JuADMDA8PPLwwMDH8Z/v//AzGACbsB |
478 | +AAAAAP//wmoAJwsDw/8/XxgY/v9l+P/rM8P/ry8ZONmwGwAAAAD//4LFAsfqaIbvCtwMDLxsDAxC |
479 | +7AwMPMqWDP+/Pmf4//01w//fXxm+/2NgePebgeHLHwaGR98ZGIKmQ2IEAAAA//80zisSQFAAAMAd |
480 | +wczzKRSvCIqrO4XqGoIkGTOv+SV7gv1j1XqY2jiI/agoSve2eM7VeyUyQk5X0gT2ZEYNHwAAAP// |
481 | +gnnhb+lWhuk//90TD1dncBThYGBgYWGA+JsRQv9lYGB4/5uBYcdDhotZSxhaGRgY/jEwMDAAAAAA |
482 | +//+CueALAwPDnZrtDK3r7jIcefuHgeEvI5JmRgaG938YGHY9YriatYShkoGB4TYDA8MnBgYGBgAA |
483 | +AAD//4IZ8JuBgeE1AwPDjfLNDE2b7jGcfPsLYutfRgaGD78ZGPY+ZrievpChjIGB4SoDA8NLqB4G |
484 | +AAAAAP//QkesDAwMMgwMDG6TwxnO3q5i+H+nhuH/nESGawwMDF4MDAzyDAwMKPEBAAAA///CZYgs |
485 | +AwODR18kw4UJ0QyX8WkGAAAA///ClpkYoAolGBgYFKBqHjAwMDxnYGD4ha4QAAAA///CZQDMEG4o |
486 | ++ys2zQwMDAwAAAAA//8DAAF5nhyE7tENAAAAAElFTkSuQmCC", |
487 | + "label": "up"}, |
488 | + {"id": 93, |
489 | + "type": "imageitem", |
490 | + "icon": "down", |
491 | + "icon-data": |
492 | +"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACPUlEQVR4nGJgoBAAAAAA///Ch1gW |
493 | +BzK0LQ5iaGNgYGDBpQgAAAD//8KpeY4/Q9+DCV7/H/S4/p8byDABlyEAAAAA///CqnluAMOEx5O8 |
494 | +/3/f0/P/+47m/4967P7PC2GYysDAwIquGAAAAP//YkLXPC+AodfNyStfRMuegenvdwamP98ZhJWM |
495 | +GJzNzLIWhGMaAgAAAP//YkLT3Odq75InomrBwPT7CwPDr68M//98Y2D+951BREadwdFAL3VxJMNM |
496 | +ZEMAAAAA//9ihPs5gKHPzdo2V0TNkoGZ4T/D//9/GRj+/WJg+PeT4f/vHwwMf78z/P31jeHN89sM |
497 | ++6/dXpS4lCGFgYHhNwAAAP//ghkguDqC4Z0CNwMDLwsDgxAHAwOfdQrD/1+fGP5/e83w/9tbhq/P |
498 | +LjG8+8PA8PkPA8PDbwwMIXMYhBkYGN4BAAAA//80zDEOQDAAAMBLZ2MnITEafEziK2YfM/QBLDoX |
499 | +g4jJPeD+IGJAgypNlrbuvNfBcxLYb/rZiIINK/IHAAD//zTRoRHAIBAAsMAU3X8iZCUSy5W7R0EN |
500 | +rJDcmoEXFU8sVq/ko5SIDQoaJj74AQAA//+CGfADKoEIGZhmZiQ+RM0D5FgAAAAA//9Cj0aEKNRm |
501 | +uGZmrCoZAAAAAP//wm4AskZkg7AAAAAAAP//wpo8n/6A2siEoJ/+wG4AAAAA///CZq4EAwODAZRG |
502 | +Bi8YEIEIBwAAAAD//8JmAAcDA4MAlEYGPxgYGD5AaTgAAAAA//8DAD6xjTP5Y+A7AAAAAElFTkSu |
503 | +QmCC", |
504 | + "label": "down"} |
505 | + ] |
506 | + }, |
507 | ] |
Adds support for image menu items. They're fun!