Merge lp:~bratsche/indicator-sound/icon-placement into lp:indicator-sound/sound-menu-v2

Proposed by Conor Curran
Status: Merged
Merge reported by: Conor Curran
Merged at revision: not available
Proposed branch: lp:~bratsche/indicator-sound/icon-placement
Merge into: lp:indicator-sound/sound-menu-v2
Diff against target: 703 lines (+210/-100) (has conflicts)
10 files modified
src/common-defs.h (+1/-0)
src/indicator-sound.c (+32/-27)
src/mpris2-controller.vala (+11/-11)
src/player-controller.vala (+6/-0)
src/sound-service.c (+6/-0)
src/title-menu-item.vala (+6/-1)
src/title-widget.c (+131/-54)
src/title-widget.h (+7/-5)
src/transport-menu-item.vala (+9/-2)
vapi/common-defs.vapi (+1/-0)
Text conflict in src/sound-service.c
To merge this branch: bzr merge lp:~bratsche/indicator-sound/icon-placement
Reviewer Review Type Date Requested Status
Conor Curran (community) Approve
Review via email: mp+34798@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Conor Curran (cjcurran) wrote :

+1

review: Approve
Revision history for this message
Conor Curran (cjcurran) wrote :

Manually merged.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/common-defs.h'
2--- src/common-defs.h 2010-09-03 13:06:00 +0000
3+++ src/common-defs.h 2010-09-07 20:31:00 +0000
4@@ -41,6 +41,7 @@
5
6 #define DBUSMENU_TITLE_MENUITEM_TYPE "x-canonical-sound-menu-player-title-type"
7 #define DBUSMENU_TITLE_MENUITEM_NAME "x-canonical-sound-menu-player-title-name"
8+#define DBUSMENU_TITLE_MENUITEM_RUNNING "x-canonical-sound-menu-player-title-running"
9
10 #define DBUSMENU_SCRUB_MENUITEM_TYPE "x-canonical-sound-menu-player-scrub-type"
11 #define DBUSMENU_SCRUB_MENUITEM_DURATION "x-canonical-sound-menu-player-scrub-mpris:length"
12
13=== modified file 'src/indicator-sound.c'
14--- src/indicator-sound.c 2010-09-06 17:07:15 +0000
15+++ src/indicator-sound.c 2010-09-07 20:31:00 +0000
16@@ -133,7 +133,7 @@
17 IndicatorObjectClass *io_class = INDICATOR_OBJECT_CLASS(klass);
18
19 g_type_class_add_private (klass, sizeof (IndicatorSoundPrivate));
20-
21+
22 io_class->get_label = get_label;
23 io_class->get_image = get_icon;
24 io_class->get_menu = get_menu;
25@@ -154,7 +154,7 @@
26 blocked_id = 0;
27 initial_mute = FALSE;
28 device_available = TRUE;
29-
30+
31 IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self);
32 priv->volume_widget = NULL;
33
34@@ -196,8 +196,10 @@
35 static GtkImage *
36 get_icon (IndicatorObject * io)
37 {
38- gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state));
39- g_debug("At start-up attempting to set the image to %s", current_name);
40+ gchar* current_name = g_hash_table_lookup(volume_states,
41+ GINT_TO_POINTER(current_state));
42+ g_debug("At start-up attempting to set the image to %s",
43+ current_name);
44 speaker_image = indicator_image_helper(current_name);
45 gtk_widget_show(GTK_WIDGET(speaker_image));
46 return speaker_image;
47@@ -209,18 +211,19 @@
48 static GtkMenu *
49 get_menu (IndicatorObject * io)
50 {
51- DbusmenuGtkMenu *menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT);
52+ DbusmenuGtkMenu* menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT);
53+
54 DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu);
55 g_object_set_data (G_OBJECT (client), "indicator", io);
56 dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_VOLUME_MENUITEM_TYPE, new_volume_slider_widget);
57 dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_TRANSPORT_MENUITEM_TYPE, new_transport_widget);
58 dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_METADATA_MENUITEM_TYPE, new_metadata_widget);
59 dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_TITLE_MENUITEM_TYPE, new_title_widget);
60- dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SCRUB_MENUITEM_TYPE, new_scrub_bar_widget);
61-
62+ dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SCRUB_MENUITEM_TYPE, new_scrub_bar_widget);
63 // register Key-press listening on the menu widget as the slider does not allow this.
64 g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), io);
65- return GTK_MENU(menu);
66+
67+ return GTK_MENU(menu);
68 }
69
70 static void
71@@ -275,19 +278,21 @@
72 new_title_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
73 {
74 g_debug("indicator-sound: new_title_widget");
75+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
76+ g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
77+
78+ g_debug ("%s (\"%s\")", __func__, dbusmenu_menuitem_property_get(newitem, DBUSMENU_TITLE_MENUITEM_NAME));
79
80 GtkWidget* title = NULL;
81
82- g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
83- g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
84-
85 title = title_widget_new (newitem);
86 GtkMenuItem *menu_title_widget = GTK_MENU_ITEM(title);
87
88 gtk_widget_show_all(title);
89
90- dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_title_widget, parent);
91-
92+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client),
93+ newitem,
94+ menu_title_widget, parent);
95 return TRUE;
96 }
97
98@@ -322,29 +327,29 @@
99 g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
100 g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
101
102- volume_widget = volume_widget_new (newitem);
103+ volume_widget = volume_widget_new (newitem);
104 io = g_object_get_data (G_OBJECT (client), "indicator");
105 IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io));
106 priv->volume_widget = volume_widget;
107
108 GtkWidget* ido_slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
109
110- g_signal_connect(ido_slider_widget, "style-set", G_CALLBACK(style_changed_cb), NULL);
111+ g_signal_connect(ido_slider_widget, "style-set", G_CALLBACK(style_changed_cb), NULL);
112 gtk_widget_set_sensitive(ido_slider_widget,
113 !initial_mute);
114 gtk_widget_show_all(ido_slider_widget);
115
116-
117+
118 GtkMenuItem *menu_volume_item = GTK_MENU_ITEM(ido_slider_widget);
119 dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client),
120 newitem,
121 menu_volume_item,
122 parent);
123-
124+
125 fetch_mute_value_from_dbus();
126 fetch_sink_availability_from_dbus(INDICATOR_SOUND (io));
127-
128- return TRUE;
129+
130+ return TRUE;
131 }
132
133
134@@ -376,7 +381,7 @@
135 dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_CALLBACK(catch_signal_sink_availability_update), NULL, NULL);
136
137 g_return_if_fail(IS_INDICATOR_SOUND(userdata));
138-
139+
140 }
141 }
142 return;
143@@ -536,7 +541,7 @@
144 fetch_sink_availability_from_dbus(IndicatorSound* self)
145 {
146 g_return_if_fail(IS_INDICATOR_SOUND(self));
147-
148+
149 GError * error = NULL;
150 gboolean * available_input;
151 available_input = g_new0(gboolean, 1);
152@@ -547,7 +552,7 @@
153 g_free(available_input);
154 return;
155 }
156-
157+
158 device_available = *available_input;
159 if (device_available == FALSE) {
160 update_state(STATE_SINKS_NONE);
161@@ -555,7 +560,7 @@
162 }
163
164 IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self);
165- GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
166+ GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
167 gtk_widget_set_sensitive(slider_widget, device_available);
168
169 g_free(available_input);
170@@ -600,7 +605,7 @@
171 /*
172 We can be sure the service won't send a mute signal unless it has changed !
173 UNMUTE's force a volume update therefore icon is updated appropriately => no need for unmute handling here.
174-*/
175+*/
176 static void
177 catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer userdata)
178 {
179@@ -617,7 +622,7 @@
180 if(priv->volume_widget == NULL){
181 return;
182 }
183- GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
184+ GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
185 gtk_widget_set_sensitive(slider_widget, !mute_value);
186 }
187
188@@ -652,8 +657,8 @@
189 if(priv->volume_widget == NULL){
190 return FALSE;
191 }
192-
193- GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
194+
195+ GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
196 GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)slider_widget);
197 GtkRange* range = (GtkRange*)slider;
198 gdouble current_value = gtk_range_get_value(range);
199
200=== modified file 'src/mpris2-controller.vala'
201--- src/mpris2-controller.vala 2010-09-06 20:14:15 +0000
202+++ src/mpris2-controller.vala 2010-09-07 20:31:00 +0000
203@@ -105,7 +105,7 @@
204 if(play_v != null){
205 string state = play_v.get_string();
206 debug("new playback state = %s", state);
207- int p = this.determine_play_state(state);
208+ TransportMenuitem.state p = (TransportMenuitem.state)this.determine_play_state(state);
209 (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p);
210 }
211
212@@ -143,29 +143,29 @@
213 }
214
215
216- private int determine_play_state(string status){
217+ private TransportMenuitem.state determine_play_state(string status){
218 if(status == null)
219- return 1;
220+ return TransportMenuitem.state.PAUSED;
221
222 if(status != null && status == "Playing"){
223 debug("determine play state - state = %s", status);
224- return 0;
225+ return TransportMenuitem.state.PLAYING;
226 }
227- return 1;
228+ return TransportMenuitem.state.PAUSED;
229 }
230
231 public void initial_update()
232 {
233- int32 status;
234+ TransportMenuitem.state update;
235 if(this.player.PlaybackStatus == null){
236- status = 1;
237+ update = TransportMenuitem.state.PAUSED;
238 }
239 else{
240- status = determine_play_state(this.player.PlaybackStatus);
241+ update = determine_play_state(this.player.PlaybackStatus);
242 }
243- debug("initial update - play state %i", status);
244+ debug("initial update - play state %i", (int)update);
245
246- (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(status);
247+ (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(update);
248 GLib.HashTable<string, Value?> cleaned_metadata = this.clean_metadata();
249 this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata,
250 MetadataMenuitem.attributes_format());
251@@ -260,7 +260,7 @@
252 this.mpris2_root.Raise();
253 }
254 catch(DBus.Error e){
255- error("Exception thrown while calling root function Raise - %s", e.message);
256+ error("Exception thrown while calling function Raise - %s", e.message);
257 }
258 }
259 }
260
261=== modified file 'src/player-controller.vala'
262--- src/player-controller.vala 2010-08-27 11:25:47 +0000
263+++ src/player-controller.vala 2010-09-07 20:31:00 +0000
264@@ -116,6 +116,8 @@
265 update_state(PlayerController.state.OFFLINE);
266 this.custom_items[widget_order.TRANSPORT].reset(TransportMenuitem.attributes_format());
267 this.custom_items[widget_order.METADATA].reset(MetadataMenuitem.attributes_format());
268+ TitleMenuitem title = this.custom_items[widget_order.TITLE] as TitleMenuitem;
269+ title.toggle_active_triangle(false);
270 }
271
272 public void update_layout()
273@@ -172,6 +174,10 @@
274 {
275 if(this.mpris_bridge.connected() == true){
276 this.update_state(state.CONNECTED);
277+ TitleMenuitem title = this.custom_items[widget_order.TITLE] as TitleMenuitem;
278+ title.toggle_active_triangle(true);
279+ TransportMenuitem transport = this.custom_items[widget_order.TRANSPORT] as TransportMenuitem;
280+ transport.change_play_state(TransportMenuitem.state.PAUSED);
281 }
282 else{
283 this.update_state(state.DISCONNECTED);
284
285=== modified file 'src/sound-service.c'
286--- src/sound-service.c 2010-09-07 16:57:49 +0000
287+++ src/sound-service.c 2010-09-07 20:31:00 +0000
288@@ -40,9 +40,15 @@
289 {
290 if (mainloop != NULL) {
291 g_debug("Service shutdown !");
292+<<<<<<< TREE
293 //TODO: uncomment for release !!
294 //close_pulse_activites();
295 //g_main_loop_quit(mainloop);
296+=======
297+ // TODO: uncomment for release !!
298+ //close_pulse_activites();
299+ //g_main_loop_quit(mainloop);
300+>>>>>>> MERGE-SOURCE
301 }
302 return;
303 }
304
305=== modified file 'src/title-menu-item.vala'
306--- src/title-menu-item.vala 2010-08-17 16:26:47 +0000
307+++ src/title-menu-item.vala 2010-09-07 20:31:00 +0000
308@@ -27,6 +27,7 @@
309 {
310 Object(item_type: MENUITEM_TYPE, owner: parent);
311 this.property_set(MENUITEM_NAME, parent.name);
312+ this.property_set_bool(MENUITEM_RUNNING, false);
313 }
314
315 public override void handle_event(string name, GLib.Value input_value, uint timestamp)
316@@ -39,7 +40,11 @@
317 this.owner.mpris_bridge.expose();
318 }
319 }
320-
321+
322+ public void toggle_active_triangle(bool update)
323+ {
324+ this.property_set_bool(MENUITEM_RUNNING, update);
325+ }
326
327 public static HashSet<string> attributes_format()
328 {
329
330=== modified file 'src/title-widget.c'
331--- src/title-widget.c 2010-08-25 17:15:56 +0000
332+++ src/title-widget.c 2010-09-07 20:31:00 +0000
333@@ -4,16 +4,16 @@
334 Authors:
335 Conor Curran <conor.curran@canonical.com>
336
337-This program is free software: you can redistribute it and/or modify it
338-under the terms of the GNU General Public License version 3, as published
339+This program is free software: you can redistribute it and/or modify it
340+under the terms of the GNU General Public License version 3, as published
341 by the Free Software Foundation.
342
343-This program is distributed in the hope that it will be useful, but
344-WITHOUT ANY WARRANTY; without even the implied warranties of
345-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
346+This program is distributed in the hope that it will be useful, but
347+WITHOUT ANY WARRANTY; without even the implied warranties of
348+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
349 PURPOSE. See the GNU General Public License for more details.
350
351-You should have received a copy of the GNU General Public License along
352+You should have received a copy of the GNU General Public License along
353 with this program. If not, see <http://www.gnu.org/licenses/>.
354 */
355
356@@ -27,15 +27,12 @@
357 #include <gtk/gtk.h>
358 #include <libindicator/indicator-image-helper.h>
359
360-
361-typedef struct _TitleWidgetPrivate TitleWidgetPrivate;
362-
363 struct _TitleWidgetPrivate
364 {
365 GtkWidget* hbox;
366 GtkWidget* name;
367- GtkWidget* player_icon;
368- DbusmenuMenuitem* twin_item;
369+ GtkWidget* icon;
370+ DbusmenuMenuitem* twin_item;
371 };
372
373 #define TITLE_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TITLE_WIDGET_TYPE, TitleWidgetPrivate))
374@@ -47,17 +44,21 @@
375 static void title_widget_finalize (GObject *object);
376
377 // keyevent consumers
378-static gboolean title_widget_button_press_event (GtkWidget *menuitem,
379+static gboolean title_widget_button_press_event (GtkWidget *menuitem,
380 GdkEventButton *event);
381
382 // Dbusmenuitem properties update callback
383-static void title_widget_property_update(DbusmenuMenuitem* item, gchar* property,
384+static void title_widget_property_update(DbusmenuMenuitem* item, gchar* property,
385 GValue* value, gpointer userdata);
386 static void title_widget_set_twin_item( TitleWidget* self,
387- DbusmenuMenuitem* twin_item);
388+ DbusmenuMenuitem* twin_item);
389 static void title_widget_style_name_text(TitleWidget* self);
390
391-G_DEFINE_TYPE (TitleWidget, title_widget, GTK_TYPE_MENU_ITEM);
392+static gboolean title_widget_triangle_draw_cb (GtkWidget *widget,
393+ GdkEventExpose *event,
394+ gpointer data);
395+
396+G_DEFINE_TYPE (TitleWidget, title_widget, GTK_TYPE_IMAGE_MENU_ITEM);
397
398
399
400@@ -65,15 +66,14 @@
401 title_widget_class_init (TitleWidgetClass *klass)
402 {
403 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
404- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
405+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
406
407 widget_class->button_press_event = title_widget_button_press_event;
408-
409+
410 g_type_class_add_private (klass, sizeof (TitleWidgetPrivate));
411
412 gobject_class->dispose = title_widget_dispose;
413 gobject_class->finalize = title_widget_finalize;
414-
415 }
416
417 static void
418@@ -81,15 +81,25 @@
419 {
420 g_debug("TitleWidget::title_widget_init");
421
422- TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(self);
423-
424- GtkWidget *hbox;
425-
426- hbox = gtk_hbox_new(FALSE, 0);
427- priv->hbox = hbox;
428-
429- priv->player_icon = indicator_image_helper("sound_icon");
430- gtk_box_pack_start(GTK_BOX (priv->hbox), priv->player_icon, FALSE, FALSE, 0);
431+ TitleWidgetPrivate *priv = self->priv = TITLE_WIDGET_GET_PRIVATE (self);
432+
433+ gint padding = 4;
434+ gtk_widget_style_get(GTK_WIDGET(self), "horizontal-padding", &padding, NULL);
435+
436+ gint width, height;
437+ gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
438+
439+ GtkWidget * icon = gtk_image_new_from_icon_name("sound_icon", GTK_ICON_SIZE_MENU);
440+
441+ gtk_widget_set_size_request(icon, width
442+ + 5 /* ref triangle is 5x9 pixels */
443+ + 2 /* padding */,
444+ height);
445+ gtk_misc_set_alignment(GTK_MISC(icon), 1.0 /* right aligned */, 0.5);
446+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(self), GTK_WIDGET(icon));
447+ gtk_widget_show(icon);
448+
449+ priv->icon = icon;
450 }
451
452 static void
453@@ -106,30 +116,30 @@
454
455 /* Suppress/consume keyevents */
456 static gboolean
457-title_widget_button_press_event (GtkWidget *menuitem,
458+title_widget_button_press_event (GtkWidget *menuitem,
459 GdkEventButton *event)
460 {
461 g_debug("TitleWidget::menu_press_event");
462 TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(menuitem);
463-
464+
465 GValue value = {0};
466- g_value_init(&value, G_TYPE_BOOLEAN);
467+ g_value_init(&value, G_TYPE_BOOLEAN);
468
469- g_value_set_boolean(&value, TRUE);
470+ g_value_set_boolean(&value, TRUE);
471 dbusmenu_menuitem_handle_event (priv->twin_item, "Title menu event", &value, 0);
472-
473+
474 return FALSE;
475 }
476
477-static void
478-title_widget_property_update(DbusmenuMenuitem* item, gchar* property,
479+static void
480+title_widget_property_update(DbusmenuMenuitem* item, gchar* property,
481 GValue* value, gpointer userdata)
482 {
483- g_return_if_fail (IS_TITLE_WIDGET (userdata));
484+ g_return_if_fail (IS_TITLE_WIDGET (userdata));
485 TitleWidget* mitem = TITLE_WIDGET(userdata);
486 TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(mitem);
487-
488- if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_NAME, property) == 0){
489+
490+ if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_NAME, property) == 0){
491 gtk_label_set_text(GTK_LABEL(priv->name), g_value_get_string(value));
492 title_widget_style_name_text(mitem);
493 }
494@@ -139,42 +149,109 @@
495 title_widget_set_twin_item(TitleWidget* self,
496 DbusmenuMenuitem* twin_item)
497 {
498- TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(self);
499- priv->twin_item = twin_item;
500- g_signal_connect(G_OBJECT(twin_item), "property-changed",
501- G_CALLBACK(title_widget_property_update), self);
502- priv->name = gtk_label_new(dbusmenu_menuitem_property_get(priv->twin_item,
503- DBUSMENU_TITLE_MENUITEM_NAME));
504- gtk_misc_set_padding(GTK_MISC(priv->name), 10, 0);
505- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->name, FALSE, FALSE, 0);
506-
507- title_widget_style_name_text(self);
508-
509- gtk_widget_show_all (priv->hbox);
510- gtk_container_add (GTK_CONTAINER (self), priv->hbox);
511+ TitleWidgetPrivate *priv = self->priv;
512+
513+ priv->twin_item = twin_item;
514+
515+ g_signal_connect (G_OBJECT (twin_item),
516+ "property-changed",
517+ G_CALLBACK (title_widget_property_update),
518+ self);
519+ g_signal_connect_after (G_OBJECT (self),
520+ "expose_event",
521+ G_CALLBACK (title_widget_triangle_draw_cb),
522+ twin_item);
523+
524+ gint padding = 4;
525+ gtk_widget_style_get(GTK_WIDGET(self), "horizontal-padding", &padding, NULL);
526+
527+ // Add the application name
528+ priv->hbox = gtk_hbox_new (FALSE, 0);
529+
530+ priv->name = gtk_label_new(dbusmenu_menuitem_property_get(priv->twin_item,
531+ DBUSMENU_TITLE_MENUITEM_NAME));
532+ gtk_misc_set_alignment (GTK_MISC (priv->name), 0.0, 0.5);
533+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->name, FALSE, FALSE, padding);
534+ gtk_widget_show (priv->name);
535+
536+ title_widget_style_name_text(self);
537+
538+ gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (priv->hbox));
539+ gtk_widget_show (priv->hbox);
540 }
541-
542+
543 static void
544 title_widget_style_name_text(TitleWidget* self)
545 {
546 TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(self);
547
548 char* markup;
549+
550 markup = g_markup_printf_escaped ("<span size=\"medium\">%s</span>",
551 gtk_label_get_text(GTK_LABEL(priv->name)));
552 gtk_label_set_markup (GTK_LABEL (priv->name), markup);
553 g_free(markup);
554 }
555-
556+
557+static gboolean
558+title_widget_triangle_draw_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data)
559+{
560+ GtkStyle *style;
561+ cairo_t *cr;
562+ int x, y, arrow_width, arrow_height;
563+
564+ if (!GTK_IS_WIDGET (widget)) return FALSE;
565+ if (!DBUSMENU_IS_MENUITEM (data)) return FALSE;
566+
567+ /* render the triangle indicator only if the application is running */
568+ if (! dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM(data),
569+ DBUSMENU_TITLE_MENUITEM_RUNNING)){
570+ return FALSE;
571+ }
572+
573+ /* get style */
574+ style = gtk_widget_get_style (widget);
575+
576+ /* set arrow position / dimensions */
577+ arrow_width = 5; /* the pixel-based reference triangle is 5x9 */
578+ arrow_height = 9;
579+ x = widget->allocation.x;
580+ y = widget->allocation.y + widget->allocation.height/2.0 - (double)arrow_height/2.0;
581+
582+ /* initialize cairo drawing area */
583+ cr = (cairo_t*) gdk_cairo_create (widget->window);
584+
585+ /* set line width */
586+ cairo_set_line_width (cr, 1.0);
587+
588+ /* cairo drawing code */
589+ cairo_move_to (cr, x, y);
590+ cairo_line_to (cr, x, y + arrow_height);
591+ cairo_line_to (cr, x + arrow_width, y + (double)arrow_height/2.0);
592+ cairo_close_path (cr);
593+ cairo_set_source_rgb (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0,
594+ style->fg[gtk_widget_get_state(widget)].green/65535.0,
595+ style->fg[gtk_widget_get_state(widget)].blue/65535.0);
596+ cairo_fill (cr);
597+
598+ /* remember to destroy cairo context to avoid leaks */
599+ cairo_destroy (cr);
600+
601+ return FALSE;
602+}
603+
604 /**
605 * transport_new:
606 * @returns: a new #TitleWidget.
607 **/
608-GtkWidget*
609+GtkWidget*
610 title_widget_new(DbusmenuMenuitem *item)
611 {
612- GtkWidget* widget = g_object_new(TITLE_WIDGET_TYPE, NULL);
613+ GtkWidget* widget = g_object_new (TITLE_WIDGET_TYPE,
614+ NULL);
615+ gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (widget), TRUE);
616 title_widget_set_twin_item((TitleWidget*)widget, item);
617+
618 return widget;
619 }
620
621
622=== modified file 'src/title-widget.h'
623--- src/title-widget.h 2010-08-06 12:20:03 +0000
624+++ src/title-widget.h 2010-09-07 20:31:00 +0000
625@@ -19,7 +19,7 @@
626 #ifndef __TITLE_WIDGET_H__
627 #define __TITLE_WIDGET_H__
628
629-#include <gtk/gtkmenuitem.h>
630+#include <gtk/gtkimagemenuitem.h>
631 #include <libdbusmenu-gtk/menuitem.h>
632
633 G_BEGIN_DECLS
634@@ -31,15 +31,17 @@
635 #define IS_TITLE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TITLE_WIDGET_TYPE))
636 #define TITLE_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TITLE_WIDGET_TYPE, TitleWidgetClass))
637
638-typedef struct _TitleWidget TitleWidget;
639-typedef struct _TitleWidgetClass TitleWidgetClass;
640+typedef struct _TitleWidget TitleWidget;
641+typedef struct _TitleWidgetClass TitleWidgetClass;
642+typedef struct _TitleWidgetPrivate TitleWidgetPrivate;
643
644 struct _TitleWidgetClass {
645- GtkMenuItemClass parent_class;
646+ GtkImageMenuItemClass parent_class;
647 };
648
649 struct _TitleWidget {
650- GtkMenuItem parent;
651+ GtkImageMenuItem parent;
652+ TitleWidgetPrivate *priv;
653 };
654
655 GType title_widget_get_type (void);
656
657=== modified file 'src/transport-menu-item.vala'
658--- src/transport-menu-item.vala 2010-08-12 12:21:57 +0000
659+++ src/transport-menu-item.vala 2010-09-07 20:31:00 +0000
660@@ -28,6 +28,11 @@
661 PLAY_PAUSE,
662 NEXT
663 }
664+
665+ public enum state{
666+ PLAYING,
667+ PAUSED
668+ }
669
670 public TransportMenuitem(PlayerController parent)
671 {
672@@ -35,9 +40,9 @@
673 this.property_set_int(MENUITEM_PLAY_STATE, 1);
674 }
675
676- public void change_play_state(int state)
677+ public void change_play_state(state update)
678 {
679- this.property_set_int(MENUITEM_PLAY_STATE, state);
680+ this.property_set_int(MENUITEM_PLAY_STATE, update);
681 }
682
683 public override void handle_event(string name, GLib.Value input_value, uint timestamp)
684@@ -54,4 +59,6 @@
685 attrs.add(MENUITEM_PLAY_STATE);
686 return attrs;
687 }
688+
689+
690 }
691\ No newline at end of file
692
693=== modified file 'vapi/common-defs.vapi'
694--- vapi/common-defs.vapi 2010-09-03 13:06:00 +0000
695+++ vapi/common-defs.vapi 2010-09-07 20:31:00 +0000
696@@ -36,6 +36,7 @@
697 namespace DbusmenuTitle{
698 public const string MENUITEM_TYPE;
699 public const string MENUITEM_NAME;
700+ public const string MENUITEM_RUNNING;
701 }
702
703 [CCode (cheader_filename = "common-defs.h")]

Subscribers

People subscribed via source and target branches