~cairo-dock-team/cairo-dock-plug-ins/plug-ins

« back to all changes in this revision

Viewing changes to alsaMixer/src/metadata-widget.c

  • Committer: Matthieu Baerts
  • Date: 2014-10-19 00:26:10 UTC
  • Revision ID: matttbe@gmail.com-20141019002610-ulf26s9b4c4rw10r
We just switched from BZR to Git.
Follow us on Github: https://github.com/Cairo-Dock

Note: we will only use Github to manage our source code and all pull requests.
Please continue to report your bugs/ideas/messages on our forum or Launchpad! 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
Copyright 2010 Canonical Ltd.
3
 
 
4
 
Authors:
5
 
    Conor Curran <conor.curran@canonical.com>
6
 
    Mirco Müller <mirco.mueller@canonical.com>
7
 
 
8
 
This program is free software: you can redistribute it and/or modify it 
9
 
under the terms of the GNU General Public License version 3, as published 
10
 
by the Free Software Foundation.
11
 
 
12
 
This program is distributed in the hope that it will be useful, but 
13
 
WITHOUT ANY WARRANTY; without even the implied warranties of 
14
 
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
15
 
PURPOSE.  See the GNU General Public License for more details.
16
 
 
17
 
You should have received a copy of the GNU General Public License along 
18
 
with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 
*/
20
 
 
21
 
#ifdef HAVE_CONFIG_H
22
 
#include "config.h"
23
 
#endif
24
 
 
25
 
#include <cairo-dock.h>
26
 
#include <glib/gi18n.h>
27
 
#include "metadata-widget.h"
28
 
#include "common-defs.h"
29
 
#include <gtk/gtk.h>
30
 
#include <glib.h>
31
 
#include "transport-widget.h"
32
 
 
33
 
typedef struct _MetadataWidgetPrivate MetadataWidgetPrivate;
34
 
 
35
 
struct _MetadataWidgetPrivate
36
 
{
37
 
  gboolean   theme_change_occured;
38
 
  GtkWidget* meta_data_h_box;
39
 
  GtkWidget* meta_data_v_box;
40
 
  GtkWidget* album_art;
41
 
  GString*   image_path;
42
 
  GString*   old_image_path;
43
 
  GtkWidget* artist_label;
44
 
  GtkWidget* piece_label;
45
 
  GtkWidget* container_label;
46
 
  GtkWidget* player_label;
47
 
  GdkPixbuf* icon_buf;
48
 
  DbusmenuMenuitem* twin_item;
49
 
  gint           current_height;
50
 
};
51
 
 
52
 
#define METADATA_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), METADATA_WIDGET_TYPE, MetadataWidgetPrivate))
53
 
 
54
 
/* Prototypes */
55
 
static void metadata_widget_class_init    (MetadataWidgetClass *klass);
56
 
static void metadata_widget_init          (MetadataWidget *self);
57
 
static void metadata_widget_dispose       (GObject *object);
58
 
static void metadata_widget_finalize      (GObject *object);
59
 
static void metadata_widget_set_style     (GtkWidget* button, GtkStyle* style);
60
 
static void metadata_widget_set_twin_item (MetadataWidget* self,
61
 
                                           DbusmenuMenuitem* twin_item);
62
 
// keyevent consumers
63
 
static gboolean metadata_widget_button_release_event (GtkWidget *menuitem, 
64
 
                                                    GdkEventButton *event);
65
 
// Dbusmenuitem properties update callback
66
 
static void metadata_widget_property_update (DbusmenuMenuitem* item,
67
 
                                             gchar* property, 
68
 
                                             GVariant* value,
69
 
                                             gpointer userdata);
70
 
static void metadata_widget_style_labels ( MetadataWidget* self,
71
 
                                           GtkLabel* label);
72
 
static void metadata_widget_selection_received_event_callback( GtkWidget        *widget,
73
 
                                                                GtkSelectionData *data,
74
 
                                                                guint             time,
75
 
                                                                gpointer          user_data);
76
 
 
77
 
                                                                
78
 
 
79
 
static void metadata_widget_get_preferred_width (GtkWidget* self,
80
 
                                                 gint* minimum_width,
81
 
                                                 gint* natural_width);
82
 
static void draw_album_art_placeholder_gtk_3 (GtkWidget *metadata, cairo_t* cr);
83
 
 
84
 
static void draw_album_border_gtk_3 (GtkWidget *metadata, gboolean selected, cairo_t* cr);
85
 
 
86
 
static gboolean metadata_widget_icon_triangle_draw_cb_gtk_3 (GtkWidget *image,
87
 
                                                                                                                         cairo_t* cr,
88
 
                                                                                                                         gpointer user_data);
89
 
static gboolean metadata_image_expose_gtk_3 (GtkWidget *image,
90
 
                                                                                         cairo_t* cr,
91
 
                                                                                         gpointer user_data);
92
 
 
93
 
static void metadata_widget_set_icon (MetadataWidget *self);
94
 
static void metadata_widget_handle_resizing (MetadataWidget* self);
95
 
 
96
 
 
97
 
G_DEFINE_TYPE (MetadataWidget, metadata_widget, GTK_TYPE_MENU_ITEM);
98
 
 
99
 
static void
100
 
metadata_widget_class_init (MetadataWidgetClass *klass)
101
 
{
102
 
  GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
103
 
  GtkWidgetClass    *widget_class = GTK_WIDGET_CLASS (klass);
104
 
 
105
 
  widget_class->button_release_event = metadata_widget_button_release_event;
106
 
  widget_class->get_preferred_width = metadata_widget_get_preferred_width;
107
 
  g_type_class_add_private (klass, sizeof (MetadataWidgetPrivate));
108
 
 
109
 
  gobject_class->dispose = metadata_widget_dispose;
110
 
  gobject_class->finalize = metadata_widget_finalize;
111
 
}
112
 
 
113
 
static void
114
 
metadata_widget_init (MetadataWidget *self)
115
 
{
116
 
  MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self);
117
 
  GtkWidget *hbox;
118
 
  GtkWidget *outer_v_box;
119
 
  priv->icon_buf = NULL;
120
 
    
121
 
  outer_v_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
122
 
  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
123
 
  
124
 
  priv->meta_data_h_box = hbox;
125
 
  priv->current_height = 1;
126
 
  
127
 
  // image
128
 
  priv->album_art = gtk_image_new();
129
 
  priv->image_path = g_string_new("");
130
 
  priv->old_image_path = g_string_new("");
131
 
 
132
 
  g_signal_connect(priv->album_art, "draw", 
133
 
                   G_CALLBACK(metadata_image_expose_gtk_3),
134
 
                   GTK_WIDGET(self));
135
 
 
136
 
  g_signal_connect_after (GTK_WIDGET(self), "draw", 
137
 
                          G_CALLBACK(metadata_widget_icon_triangle_draw_cb_gtk_3),
138
 
                          GTK_WIDGET(self));
139
 
  gtk_box_pack_start (GTK_BOX (priv->meta_data_h_box),
140
 
                      priv->album_art,
141
 
                      FALSE,
142
 
                      FALSE,
143
 
                      1); 
144
 
  priv->theme_change_occured = FALSE;
145
 
  GtkWidget* vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
146
 
  
147
 
  // artist
148
 
  GtkWidget* artist;
149
 
  artist = gtk_label_new("");
150
 
  gtk_misc_set_alignment(GTK_MISC(artist), (gfloat)0, (gfloat)0);
151
 
  gtk_misc_set_padding (GTK_MISC(artist), (gfloat)10, (gfloat)0);
152
 
  gtk_widget_set_size_request (artist, 140, 15);
153
 
 
154
 
  gtk_label_set_ellipsize(GTK_LABEL(artist), PANGO_ELLIPSIZE_MIDDLE); 
155
 
  metadata_widget_style_labels(self, GTK_LABEL(artist));
156
 
  priv->artist_label = artist;
157
 
  
158
 
  // title
159
 
  GtkWidget* piece;
160
 
  piece = gtk_label_new("");
161
 
  gtk_misc_set_alignment(GTK_MISC(piece), (gfloat)0, (gfloat)0);
162
 
  gtk_misc_set_padding (GTK_MISC(piece), (gfloat)10, (gfloat)-5);
163
 
  
164
 
  gtk_widget_set_size_request (piece, 140, 15);
165
 
  gtk_label_set_ellipsize(GTK_LABEL(piece), PANGO_ELLIPSIZE_MIDDLE);
166
 
  metadata_widget_style_labels(self, GTK_LABEL(piece));
167
 
  priv->piece_label =  piece;
168
 
 
169
 
  // container
170
 
  GtkWidget* container;
171
 
  container = gtk_label_new("");
172
 
  gtk_misc_set_alignment(GTK_MISC(container), (gfloat)0, (gfloat)0);
173
 
  gtk_misc_set_padding (GTK_MISC(container), (gfloat)10, (gfloat)0);  
174
 
  gtk_widget_set_size_request (container, 140, 15);
175
 
 
176
 
  gtk_label_set_ellipsize(GTK_LABEL(container), PANGO_ELLIPSIZE_MIDDLE);  
177
 
  metadata_widget_style_labels(self, GTK_LABEL(container));
178
 
  priv->container_label = container;
179
 
 
180
 
  gtk_box_pack_start (GTK_BOX (vbox), priv->piece_label, FALSE, FALSE, 0);  
181
 
  gtk_box_pack_start (GTK_BOX (vbox), priv->artist_label, FALSE, FALSE, 0); 
182
 
  gtk_box_pack_start (GTK_BOX (vbox), priv->container_label, FALSE, FALSE, 0);  
183
 
  
184
 
  gtk_box_pack_start (GTK_BOX (priv->meta_data_h_box), vbox, FALSE, FALSE, 0); 
185
 
 
186
 
  g_signal_connect(self, "style-set", 
187
 
                   G_CALLBACK(metadata_widget_set_style), GTK_WIDGET(self));    
188
 
  g_signal_connect (self, "selection-received",
189
 
                   G_CALLBACK(metadata_widget_selection_received_event_callback),
190
 
                   GTK_WIDGET(self));   
191
 
 
192
 
  // player label
193
 
  GtkWidget* player_label;
194
 
  player_label = gtk_label_new("");
195
 
  gtk_misc_set_alignment(GTK_MISC(player_label), (gfloat)0, (gfloat)0);
196
 
  gtk_misc_set_padding (GTK_MISC(player_label), (gfloat)1, (gfloat)4);  
197
 
  gtk_widget_set_size_request (player_label, 150, 24);
198
 
  priv->player_label = player_label;
199
 
      
200
 
  gtk_box_pack_start (GTK_BOX(outer_v_box), priv->player_label, FALSE, FALSE, 0);
201
 
  
202
 
  gtk_box_pack_start (GTK_BOX(outer_v_box), priv->meta_data_h_box, FALSE, FALSE, 0);
203
 
    
204
 
  gtk_container_add (GTK_CONTAINER (self), outer_v_box);  
205
 
  
206
 
  gtk_widget_show_all (priv->meta_data_h_box);
207
 
  gtk_widget_set_no_show_all (priv->meta_data_h_box, TRUE);
208
 
  
209
 
  gtk_widget_hide (priv->meta_data_h_box);
210
 
}
211
 
 
212
 
static void
213
 
metadata_widget_dispose (GObject *object)
214
 
{
215
 
  MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(METADATA_WIDGET(object)); 
216
 
 
217
 
  if (priv->icon_buf != NULL){
218
 
    g_object_unref (priv->icon_buf);
219
 
    priv->icon_buf = NULL;
220
 
  }
221
 
  g_string_free (priv->image_path, TRUE);
222
 
  priv->image_path = NULL;
223
 
  g_string_free (priv->old_image_path, TRUE);
224
 
  priv->old_image_path = NULL;
225
 
  G_OBJECT_CLASS (metadata_widget_parent_class)->dispose (object);
226
 
}
227
 
 
228
 
static void
229
 
metadata_widget_finalize (GObject *object)
230
 
{
231
 
  G_OBJECT_CLASS (metadata_widget_parent_class)->finalize (object);
232
 
}
233
 
 
234
 
 
235
 
static void
236
 
metadata_widget_get_preferred_width (GtkWidget* self,
237
 
                                     gint* minimum_width,
238
 
                                     gint* natural_width)
239
 
{
240
 
  *minimum_width = *natural_width =  200;
241
 
}
242
 
 
243
 
static void
244
 
draw_album_border_gtk_3(GtkWidget *metadata, gboolean selected, cairo_t *cr)
245
 
{
246
 
  gtk_style_context_add_class (gtk_widget_get_style_context (metadata),
247
 
                               "menu");
248
 
  
249
 
  int x, y, width, height;
250
 
  x = 0;
251
 
  y = 0;
252
 
  width = gtk_widget_get_allocated_width (metadata);
253
 
  height = gtk_widget_get_allocated_height (metadata);
254
 
  
255
 
  gint offset = 1;
256
 
  
257
 
  width = width + (offset * 2);
258
 
  height = height + (offset * 2) - 7;
259
 
  x = x - offset;
260
 
  y = y - offset + 3;
261
 
 
262
 
  gint state = selected ? 5 : 0;
263
 
  CairoColorRGB bg_normal, fg_normal;
264
 
  GtkStyleContext *style = gtk_widget_get_style_context (metadata);
265
 
        gtk_style_context_get_background_color (style, 0, (GdkRGBA*)&bg_normal);
266
 
        gtk_style_context_get_color (style, state, (GdkRGBA*)&fg_normal);
267
 
 
268
 
  CairoColorRGB dark_top_color;
269
 
  CairoColorRGB light_bottom_color;
270
 
  CairoColorRGB background_color;
271
 
  
272
 
  _color_shade ( &bg_normal, 0.93, &background_color );
273
 
  _color_shade ( &bg_normal, 0.23, &dark_top_color );
274
 
  _color_shade ( &fg_normal, 0.55, &light_bottom_color );
275
 
  
276
 
  cairo_rectangle (cr,
277
 
                   x, y,
278
 
                   width, height);
279
 
 
280
 
  cairo_set_line_width (cr, 1.0);
281
 
  
282
 
  cairo_clip ( cr );  /// seems redundant here ...
283
 
 
284
 
  cairo_move_to (cr, x, y );
285
 
  cairo_line_to (cr, x + width,
286
 
                y );
287
 
  cairo_line_to ( cr, x + width,
288
 
                  y + height );
289
 
  cairo_line_to ( cr, x, y + height );
290
 
  cairo_line_to ( cr, x, y);
291
 
  cairo_close_path (cr);
292
 
 
293
 
  cairo_set_source_rgba ( cr,
294
 
                          background_color.r,
295
 
                          background_color.g,
296
 
                          background_color.b,
297
 
                          1.0 );
298
 
  
299
 
  cairo_fill ( cr );
300
 
  
301
 
  cairo_move_to (cr, x, y );
302
 
  cairo_line_to (cr, x + width,
303
 
                y );
304
 
 
305
 
  cairo_close_path (cr);
306
 
  cairo_set_source_rgba ( cr,
307
 
                          dark_top_color.r,
308
 
                          dark_top_color.g,
309
 
                          dark_top_color.b,
310
 
                          1.0 );
311
 
  
312
 
  cairo_stroke ( cr );
313
 
  
314
 
  cairo_move_to ( cr, x + width,
315
 
                  y + height );
316
 
  cairo_line_to ( cr, x, y + height );
317
 
 
318
 
  cairo_close_path (cr);
319
 
  cairo_set_source_rgba ( cr,
320
 
                         light_bottom_color.r,
321
 
                         light_bottom_color.g,
322
 
                         light_bottom_color.b,
323
 
                         1.0);
324
 
  
325
 
  cairo_stroke ( cr );
326
 
}
327
 
 
328
 
static void
329
 
draw_album_art_placeholder_gtk_3(GtkWidget *metadata, cairo_t *cr)
330
 
{       
331
 
  int x, y, width;
332
 
  x = 0;
333
 
  y = 0;
334
 
  width = gtk_widget_get_allocated_width (metadata);
335
 
 
336
 
  PangoLayout *layout;
337
 
  PangoFontDescription *desc;
338
 
  layout = pango_cairo_create_layout(cr);
339
 
  PangoContext* pcontext = pango_cairo_create_context(cr); 
340
 
  pango_cairo_context_set_resolution (pcontext, 96);
341
 
 
342
 
  GString* string = g_string_new("");
343
 
  gssize size = -1;
344
 
  gunichar code = g_utf8_get_char_validated("\342\231\253", size);  
345
 
  g_string_append_unichar (string, code);
346
 
  
347
 
  pango_layout_set_text(layout, string->str, -1);
348
 
  desc = pango_font_description_from_string("Sans Bold 30");
349
 
  pango_layout_set_font_description(layout, desc);
350
 
  pango_font_description_free(desc);
351
 
 
352
 
  CairoColorRGB fg_normal, light_bottom_color;
353
 
  GtkStyleContext *style = gtk_widget_get_style_context (metadata);
354
 
        gtk_style_context_get_color (style, 0, (GdkRGBA*)&fg_normal);
355
 
 
356
 
  _color_shade ( &fg_normal, 0.78, &light_bottom_color );
357
 
  
358
 
  cairo_set_source_rgba (cr,
359
 
                         light_bottom_color.r, 
360
 
                         light_bottom_color.g,
361
 
                         light_bottom_color.b,
362
 
                         1.0);
363
 
  
364
 
  pango_cairo_update_layout(cr, layout);
365
 
  cairo_move_to (cr, x + width/6, y + 3);  
366
 
  pango_cairo_show_layout(cr, layout);
367
 
 
368
 
  g_object_unref(layout); 
369
 
  g_object_unref(pcontext);
370
 
  g_string_free (string, TRUE);
371
 
}
372
 
 
373
 
/**
374
 
 * We override the expose method to enable primitive drawing of the 
375
 
 * empty album art image and rounded rectangles on the album art.
376
 
 */
377
 
static gboolean
378
 
metadata_image_expose_gtk_3 (GtkWidget *metadata,
379
 
                                                         cairo_t* cr,
380
 
                                                         gpointer user_data)
381
 
{
382
 
  g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE);
383
 
  MetadataWidget* widget = METADATA_WIDGET(user_data);
384
 
  MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widget);  
385
 
 
386
 
  if ( TRUE == dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM(priv->twin_item),
387
 
                                                    DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS))
388
 
  {
389
 
    return FALSE;
390
 
  }
391
 
 
392
 
  if(priv->image_path->len > 0){
393
 
    if(g_string_equal(priv->image_path, priv->old_image_path) == FALSE ||
394
 
       priv->theme_change_occured == TRUE){
395
 
      priv->theme_change_occured = FALSE;
396
 
      GdkPixbuf* pixbuf;
397
 
      pixbuf = gdk_pixbuf_new_from_file_at_size(priv->image_path->str, 60, 60, NULL);
398
 
 
399
 
      if(GDK_IS_PIXBUF(pixbuf) == FALSE){
400
 
        gtk_image_clear ( GTK_IMAGE(priv->album_art));          
401
 
        gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60);
402
 
          draw_album_border_gtk_3 (metadata, FALSE, cr);
403
 
        draw_album_art_placeholder_gtk_3(metadata, cr);
404
 
        return FALSE;
405
 
      }
406
 
 
407
 
      gtk_image_set_from_pixbuf(GTK_IMAGE(priv->album_art), pixbuf);
408
 
      gtk_widget_set_size_request(GTK_WIDGET(priv->album_art),
409
 
                                  gdk_pixbuf_get_width(pixbuf),
410
 
                                  gdk_pixbuf_get_height(pixbuf));
411
 
 
412
 
      draw_album_border_gtk_3 (metadata, FALSE, cr);
413
 
        g_string_erase (priv->old_image_path, 0, -1);
414
 
      g_string_overwrite (priv->old_image_path, 0, priv->image_path->str);
415
 
      g_object_unref(pixbuf);
416
 
    }
417
 
    return FALSE;       
418
 
  }
419
 
  gtk_image_clear (GTK_IMAGE(priv->album_art));  
420
 
  gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60);
421
 
  draw_album_border_gtk_3 (metadata, FALSE, cr);
422
 
  draw_album_art_placeholder_gtk_3(metadata, cr);
423
 
  return FALSE;
424
 
}
425
 
 
426
 
// Draw the triangle if the player is running ...
427
 
static gboolean
428
 
metadata_widget_icon_triangle_draw_cb_gtk_3 (GtkWidget *widget,
429
 
                                                                                         cairo_t* cr,
430
 
                                                                                         gpointer user_data)
431
 
{
432
 
g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE);
433
 
  MetadataWidget* meta = METADATA_WIDGET(user_data);
434
 
  MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(meta);  
435
 
 
436
 
  int x, y, height, arrow_width, arrow_height;
437
 
 
438
 
  arrow_width = 5; 
439
 
  arrow_height = 9;
440
 
  x = 0;
441
 
  y = 0;
442
 
  height = gtk_widget_get_allocated_height (widget);
443
 
  
444
 
  gint offset = (height - gdk_pixbuf_get_height (priv->icon_buf)) / 2;
445
 
 
446
 
  // Draw player icon  
447
 
  if (priv->icon_buf != NULL){  
448
 
    gdk_cairo_set_source_pixbuf (cr,
449
 
                                 priv->icon_buf,
450
 
                                 x + arrow_width + 1,
451
 
                                 y + offset);
452
 
    cairo_paint (cr);
453
 
  }
454
 
 
455
 
  // Draw triangle but only if the player is running.
456
 
  if (dbusmenu_menuitem_property_get_bool (priv->twin_item,
457
 
                                             DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING)){
458
 
    y += height/2.0 - (double)arrow_height/2.0;
459
 
    cairo_set_line_width (cr, 1.0);
460
 
 
461
 
    cairo_move_to (cr, x, y);
462
 
    cairo_line_to (cr, x, y + arrow_height);
463
 
    cairo_line_to (cr, x + arrow_width, y + (double)arrow_height/2.0);
464
 
    cairo_close_path (cr);
465
 
    
466
 
    CairoColorRGB fg_normal;
467
 
    GtkStyleContext *style = gtk_widget_get_style_context (widget);
468
 
        gtk_style_context_get_color (style, gtk_widget_get_state(widget), (GdkRGBA*)&fg_normal);
469
 
    
470
 
    cairo_set_source_rgb (cr, fg_normal.r,
471
 
                              fg_normal.g,
472
 
                              fg_normal.b);
473
 
    cairo_fill (cr);
474
 
  }
475
 
  
476
 
  return FALSE;
477
 
}
478
 
 
479
 
 
480
 
static void
481
 
metadata_widget_selection_received_event_callback (  GtkWidget        *widget,
482
 
                                                     GtkSelectionData *data,
483
 
                                                     guint             time,
484
 
                                                     gpointer          user_data )
485
 
 
486
 
{
487
 
        cairo_t *cr = (cairo_t*) gdk_cairo_create (gtk_widget_get_window (widget));
488
 
        /// TODO: need to translate at the widget's position ...
489
 
        draw_album_border_gtk_3(widget, TRUE, cr);
490
 
        cairo_destroy (cr);
491
 
}
492
 
 
493
 
/* Suppress/consume keyevents */
494
 
static gboolean
495
 
metadata_widget_button_release_event (GtkWidget *menuitem, 
496
 
                                      GdkEventButton *event)
497
 
{
498
 
  g_return_val_if_fail (IS_METADATA_WIDGET (menuitem), FALSE);
499
 
  MetadataWidgetPrivate* priv = METADATA_WIDGET_GET_PRIVATE(METADATA_WIDGET(menuitem));
500
 
  // For the left raise/launch the player
501
 
  if (event->button == 1){
502
 
    GVariant* new_title_event = g_variant_new_boolean(TRUE);
503
 
    dbusmenu_menuitem_handle_event (priv->twin_item,
504
 
                                    "Title menu event",
505
 
                                    new_title_event,
506
 
                                    0);
507
 
  }
508
 
  // For the right copy track details to clipboard only if the player is running
509
 
  // and there is something there
510
 
  else if (event->button == 3){
511
 
    gboolean running = dbusmenu_menuitem_property_get_bool (priv->twin_item,
512
 
                                                            DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING);
513
 
    gboolean hidden = dbusmenu_menuitem_property_get_bool (priv->twin_item,
514
 
                                                           DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS);
515
 
    g_return_val_if_fail ( running, FALSE );
516
 
 
517
 
    g_return_val_if_fail ( !hidden, FALSE );
518
 
    
519
 
    GtkClipboard* board = gtk_clipboard_get (GDK_NONE); 
520
 
    gchar* contents = g_strdup_printf("artist: %s \ntitle: %s \nalbum: %s",
521
 
                                      dbusmenu_menuitem_property_get(priv->twin_item,
522
 
                                                          DBUSMENU_METADATA_MENUITEM_ARTIST),
523
 
                                      dbusmenu_menuitem_property_get(priv->twin_item,
524
 
                                                          DBUSMENU_METADATA_MENUITEM_TITLE),
525
 
                                      dbusmenu_menuitem_property_get(priv->twin_item,
526
 
                                                          DBUSMENU_METADATA_MENUITEM_ALBUM));
527
 
    gtk_clipboard_set_text (board, contents, -1);
528
 
    gtk_clipboard_store (board);
529
 
    g_free(contents);
530
 
  }
531
 
  return FALSE;
532
 
}
533
 
 
534
 
static void 
535
 
metadata_widget_property_update(DbusmenuMenuitem* item, gchar* property, 
536
 
                                       GVariant* value, gpointer userdata)
537
 
{
538
 
  g_return_if_fail (IS_METADATA_WIDGET (userdata)); 
539
 
 
540
 
  if(g_variant_is_of_type(value, G_VARIANT_TYPE_INT32) == TRUE && 
541
 
     g_variant_get_int32(value) == DBUSMENU_PROPERTY_EMPTY){
542
 
    GVariant* new_value = g_variant_new_string ("");
543
 
    value = new_value;
544
 
  }
545
 
  
546
 
  MetadataWidget* mitem = METADATA_WIDGET(userdata);
547
 
  MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(mitem);
548
 
  
549
 
  if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTIST, property) == 0){  
550
 
    gtk_label_set_text(GTK_LABEL(priv->artist_label), g_variant_get_string(value, NULL));
551
 
    metadata_widget_style_labels(mitem, GTK_LABEL(priv->artist_label));
552
 
  }
553
 
  else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_TITLE, property) == 0){  
554
 
    gtk_label_set_text(GTK_LABEL(priv->piece_label), g_variant_get_string(value, NULL));    
555
 
    metadata_widget_style_labels(mitem, GTK_LABEL(priv->piece_label));
556
 
  } 
557
 
  else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ALBUM, property) == 0){  
558
 
    gtk_label_set_text(GTK_LABEL(priv->container_label), g_variant_get_string(value, NULL));
559
 
    metadata_widget_style_labels(mitem, GTK_LABEL(priv->container_label));
560
 
  } 
561
 
  else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTURL, property) == 0){
562
 
    g_string_erase(priv->image_path, 0, -1);
563
 
    g_string_overwrite(priv->image_path, 0, g_variant_get_string (value, NULL));
564
 
    gtk_widget_queue_draw(GTK_WIDGET(mitem));
565
 
  }
566
 
  else if (g_ascii_strcasecmp (DBUSMENU_METADATA_MENUITEM_PLAYER_NAME, property) == 0){
567
 
    gtk_label_set_label (GTK_LABEL (priv->player_label),
568
 
                         g_variant_get_string(value, NULL));
569
 
  }
570
 
  else if (g_ascii_strcasecmp (DBUSMENU_METADATA_MENUITEM_PLAYER_ICON, property) == 0){
571
 
    metadata_widget_set_icon (mitem);
572
 
  }
573
 
  else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS, property) == 0){
574
 
    metadata_widget_handle_resizing (mitem);
575
 
  }
576
 
}
577
 
 
578
 
static void 
579
 
metadata_widget_handle_resizing (MetadataWidget* self)
580
 
{
581
 
  MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self);
582
 
    
583
 
  if (dbusmenu_menuitem_property_get_bool (priv->twin_item,
584
 
                                           DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS) == TRUE){
585
 
    gtk_widget_hide (priv->meta_data_h_box);
586
 
  }
587
 
  else{
588
 
    gtk_widget_show (priv->meta_data_h_box);     
589
 
  }
590
 
  gtk_widget_queue_draw(GTK_WIDGET(self));      
591
 
}
592
 
 
593
 
static void
594
 
metadata_widget_style_labels(MetadataWidget* self, GtkLabel* label)
595
 
{
596
 
  char* markup;
597
 
  markup = g_markup_printf_escaped ("<span size=\"smaller\">%s</span>",
598
 
                                    gtk_label_get_text(GTK_LABEL(label)));
599
 
  gtk_label_set_markup (GTK_LABEL (label), markup);
600
 
  g_free(markup); 
601
 
}
602
 
 
603
 
static void
604
 
metadata_widget_set_style(GtkWidget* metadata, GtkStyle* style)
605
 
{
606
 
  g_return_if_fail(IS_METADATA_WIDGET(metadata));
607
 
  MetadataWidget* widg = METADATA_WIDGET(metadata);
608
 
  MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widg); 
609
 
  priv->theme_change_occured = TRUE;    
610
 
  gtk_widget_queue_draw(GTK_WIDGET(metadata));  
611
 
}
612
 
 
613
 
static void 
614
 
metadata_widget_set_icon (MetadataWidget *self)
615
 
{
616
 
  MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); 
617
 
 
618
 
  if (priv->icon_buf != NULL){
619
 
    g_object_unref (priv->icon_buf);
620
 
    priv->icon_buf = NULL;    
621
 
  }
622
 
  
623
 
  gint padding = 0;
624
 
  gtk_widget_style_get(GTK_WIDGET(self), "horizontal-padding", &padding, NULL);
625
 
  gint width, height;
626
 
  gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height);
627
 
  
628
 
  GString* banshee_string = g_string_new ( "banshee" );
629
 
  gchar * tmp = g_utf8_strdown (dbusmenu_menuitem_property_get(priv->twin_item, DBUSMENU_METADATA_MENUITEM_PLAYER_NAME), -1);
630
 
  GString* app_panel = g_string_new (tmp);
631
 
  g_free (tmp);
632
 
  
633
 
  GdkPixbuf* icon_buf;
634
 
  
635
 
  // Banshee Special case!  
636
 
  // Not ideal but apparently we want the banshee icon to be the greyscale one
637
 
  // and any others to be the icon from the desktop file => colour.
638
 
  if ( g_string_equal ( banshee_string, app_panel ) == TRUE &&
639
 
      gtk_icon_theme_has_icon ( gtk_icon_theme_get_default(), app_panel->str ) ){
640
 
    g_string_append ( app_panel, "-panel" );
641
 
  }
642
 
  else{
643
 
    // Otherwise use what is stored in the props
644
 
    g_string_erase (app_panel, 0, -1);
645
 
    g_string_overwrite (app_panel,
646
 
                        0,
647
 
                        dbusmenu_menuitem_property_get ( priv->twin_item,
648
 
                                                         DBUSMENU_METADATA_MENUITEM_PLAYER_ICON ));  
649
 
  }
650
 
  icon_buf = gtk_icon_theme_load_icon ( gtk_icon_theme_get_default(),
651
 
                                        app_panel->str,
652
 
                                        (width > height) ? width : height,
653
 
                                        GTK_ICON_LOOKUP_GENERIC_FALLBACK, 
654
 
                                        NULL );  
655
 
  priv->icon_buf = icon_buf;
656
 
  g_string_free ( app_panel, TRUE);
657
 
  g_string_free ( banshee_string, TRUE);
658
 
}
659
 
 
660
 
static void
661
 
metadata_widget_set_twin_item (MetadataWidget* self,
662
 
                               DbusmenuMenuitem* twin_item)
663
 
{
664
 
  MetadataWidgetPrivate* priv = METADATA_WIDGET_GET_PRIVATE(self);
665
 
  priv->twin_item = twin_item;
666
 
  g_signal_connect( G_OBJECT(priv->twin_item), "property-changed", 
667
 
                            G_CALLBACK(metadata_widget_property_update), self);
668
 
  gtk_label_set_text( GTK_LABEL(priv->container_label), 
669
 
                      dbusmenu_menuitem_property_get( priv->twin_item,
670
 
                                                      DBUSMENU_METADATA_MENUITEM_ALBUM));
671
 
  metadata_widget_style_labels( self, GTK_LABEL(priv->container_label));
672
 
 
673
 
  gtk_label_set_text( GTK_LABEL(priv->piece_label), 
674
 
                      dbusmenu_menuitem_property_get( priv->twin_item,
675
 
                                                      DBUSMENU_METADATA_MENUITEM_TITLE));
676
 
  metadata_widget_style_labels( self, GTK_LABEL(priv->piece_label));
677
 
  gtk_label_set_text( GTK_LABEL(priv->artist_label), 
678
 
                      dbusmenu_menuitem_property_get( priv->twin_item,
679
 
                                                      DBUSMENU_METADATA_MENUITEM_ARTIST));
680
 
  metadata_widget_style_labels( self, GTK_LABEL(priv->artist_label));
681
 
 
682
 
  g_string_erase(priv->image_path, 0, -1);
683
 
  const gchar *arturl = dbusmenu_menuitem_property_get( priv->twin_item,
684
 
                                                        DBUSMENU_METADATA_MENUITEM_ARTURL );
685
 
  
686
 
  gtk_label_set_label (GTK_LABEL(priv->player_label),
687
 
                       dbusmenu_menuitem_property_get(priv->twin_item,
688
 
                                                      DBUSMENU_METADATA_MENUITEM_PLAYER_NAME));
689
 
  
690
 
  metadata_widget_set_icon(self);
691
 
  
692
 
  if (arturl != NULL){
693
 
    g_string_overwrite( priv->image_path,
694
 
                        0,
695
 
                        arturl);
696
 
    // if its a remote image queue a redraw incase the download took too long
697
 
    if (g_str_has_prefix (arturl, g_get_user_cache_dir())){
698
 
      gtk_widget_queue_draw(GTK_WIDGET(self));                                                          
699
 
    }
700
 
  }
701
 
  metadata_widget_handle_resizing (self);  
702
 
}
703
 
 
704
 
 /**
705
 
 * transport_new:
706
 
 * @returns: a new #MetadataWidget.
707
 
 **/
708
 
GtkWidget* 
709
 
metadata_widget_new(DbusmenuMenuitem *item)
710
 
{
711
 
  GtkWidget* widget =  g_object_new(METADATA_WIDGET_TYPE, NULL);
712
 
  metadata_widget_set_twin_item ( METADATA_WIDGET(widget),
713
 
                                  item );
714
 
  return widget;                  
715
 
}
716