diff options
author | Conor Curran <conor.curran@canonical.com> | 2011-06-15 08:48:54 +0200 |
---|---|---|
committer | Conor Curran <conor.curran@canonical.com> | 2011-06-15 08:48:54 +0200 |
commit | 1677228ec606dd8d2e7eadccfff77a1703fdb727 (patch) | |
tree | 09e435494c9fd603bf502f3f88e26d25a667cbd3 /src/metadata-widget.c | |
parent | bf2c6d9d1f7ac8897c76b8917f4feaeff54816d6 (diff) | |
parent | d72fb000fdf8c8a65abb214d1e6e67c7d31b4dbb (diff) | |
download | ayatana-indicator-sound-1677228ec606dd8d2e7eadccfff77a1703fdb727.tar.gz ayatana-indicator-sound-1677228ec606dd8d2e7eadccfff77a1703fdb727.tar.bz2 ayatana-indicator-sound-1677228ec606dd8d2e7eadccfff77a1703fdb727.zip |
merge metadata widget and title widget
Diffstat (limited to 'src/metadata-widget.c')
-rw-r--r-- | src/metadata-widget.c | 298 |
1 files changed, 244 insertions, 54 deletions
diff --git a/src/metadata-widget.c b/src/metadata-widget.c index 38ed529..bc998fa 100644 --- a/src/metadata-widget.c +++ b/src/metadata-widget.c @@ -28,19 +28,22 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <gtk/gtk.h> #include <glib.h> #include "transport-widget.h" +#include <libindicator/indicator-image-helper.h> typedef struct _MetadataWidgetPrivate MetadataWidgetPrivate; struct _MetadataWidgetPrivate { gboolean theme_change_occured; - GtkWidget* hbox; + GtkWidget* meta_data_h_box; + GtkWidget* meta_data_v_box; GtkWidget* album_art; GString* image_path; GString* old_image_path; GtkWidget* artist_label; GtkWidget* piece_label; GtkWidget* container_label; + GtkWidget* player_label; DbusmenuMenuitem* twin_item; }; @@ -51,12 +54,15 @@ static void metadata_widget_class_init (MetadataWidgetClass *klass); static void metadata_widget_init (MetadataWidget *self); static void metadata_widget_dispose (GObject *object); static void metadata_widget_finalize (GObject *object); -static gboolean metadata_image_expose (GtkWidget *image, GdkEventExpose *event, gpointer user_data); +static gboolean metadata_image_expose (GtkWidget *image, + GdkEventExpose *event, + gpointer user_data); static void metadata_widget_set_style (GtkWidget* button, GtkStyle* style); -static void metadata_widget_set_twin_item (MetadataWidget* self, DbusmenuMenuitem* twin_item); +static void metadata_widget_set_twin_item (MetadataWidget* self, + DbusmenuMenuitem* twin_item); // keyevent consumers -static gboolean metadata_widget_button_press_event (GtkWidget *menuitem, +static gboolean metadata_widget_button_release_event (GtkWidget *menuitem, GdkEventButton *event); // Dbusmenuitem properties update callback static void metadata_widget_property_update (DbusmenuMenuitem* item, @@ -71,8 +77,15 @@ static void metadata_widget_selection_received_event_callback( GtkWidget GtkSelectionData *data, guint time, gpointer user_data); -G_DEFINE_TYPE (MetadataWidget, metadata_widget, GTK_TYPE_MENU_ITEM); +static gboolean metadata_widget_triangle_draw_cb ( GtkWidget *image, + GdkEventExpose *event, + gpointer user_data); +static void metadata_widget_set_icon (MetadataWidget *self); +static void metadata_widget_handle_resizing (MetadataWidget* self); + + +G_DEFINE_TYPE (MetadataWidget, metadata_widget, GTK_TYPE_IMAGE_MENU_ITEM); static void metadata_widget_class_init (MetadataWidgetClass *klass) @@ -80,7 +93,7 @@ metadata_widget_class_init (MetadataWidgetClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - widget_class->button_press_event = metadata_widget_button_press_event; + widget_class->button_release_event = metadata_widget_button_release_event; g_type_class_add_private (klass, sizeof (MetadataWidgetPrivate)); @@ -88,16 +101,19 @@ metadata_widget_class_init (MetadataWidgetClass *klass) gobject_class->finalize = metadata_widget_finalize; } + + static void metadata_widget_init (MetadataWidget *self) { - //g_debug("MetadataWidget::metadata_widget_init"); - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); GtkWidget *hbox; + GtkWidget *outer_v_box; + outer_v_box = gtk_vbox_new (FALSE, 0); hbox = gtk_hbox_new(FALSE, 0); - priv->hbox = hbox; + + priv->meta_data_h_box = hbox; // image priv->album_art = gtk_image_new(); @@ -107,8 +123,12 @@ metadata_widget_init (MetadataWidget *self) g_signal_connect(priv->album_art, "expose-event", G_CALLBACK(metadata_image_expose), GTK_WIDGET(self)); + + g_signal_connect(GTK_WIDGET(self), "expose-event", + G_CALLBACK(metadata_widget_triangle_draw_cb), + GTK_WIDGET(self)); - gtk_box_pack_start (GTK_BOX (priv->hbox), + gtk_box_pack_start (GTK_BOX (priv->meta_data_h_box), priv->album_art, FALSE, FALSE, @@ -150,15 +170,26 @@ metadata_widget_init (MetadataWidget *self) gtk_box_pack_start (GTK_BOX (vbox), priv->artist_label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), priv->container_label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (priv->hbox), vbox, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (priv->meta_data_h_box), vbox, FALSE, FALSE, 0); g_signal_connect(self, "style-set", G_CALLBACK(metadata_widget_set_style), GTK_WIDGET(self)); g_signal_connect (self, "selection-received", G_CALLBACK(metadata_widget_selection_received_event_callback), GTK_WIDGET(self)); - gtk_widget_set_size_request(GTK_WIDGET(self), 200, 75); - gtk_container_add (GTK_CONTAINER (self), hbox); + + // player label + GtkWidget* player_label; + player_label = gtk_label_new(""); + gtk_misc_set_alignment(GTK_MISC(player_label), (gfloat)0, (gfloat)0); + gtk_misc_set_padding (GTK_MISC(player_label), (gfloat)0, (gfloat)0); + gtk_widget_set_size_request (player_label, 200, 25); + priv->player_label = player_label; + + gtk_box_pack_start (GTK_BOX(outer_v_box), priv->player_label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX(outer_v_box), priv->meta_data_h_box, FALSE, FALSE, 0); + + gtk_container_add (GTK_CONTAINER (self), outer_v_box); } static void @@ -183,37 +214,46 @@ metadata_image_expose (GtkWidget *metadata, GdkEventExpose *event, gpointer user { g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE); MetadataWidget* widget = METADATA_WIDGET(user_data); - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widget); - draw_album_border(metadata, FALSE); + MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widget); + + if ( TRUE == dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM(priv->twin_item), + DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS)) + { + return FALSE; + } + + draw_album_border(metadata, FALSE); + if(priv->image_path->len > 0){ if(g_string_equal(priv->image_path, priv->old_image_path) == FALSE || priv->theme_change_occured == TRUE){ - priv->theme_change_occured = FALSE; + priv->theme_change_occured = FALSE; GdkPixbuf* pixbuf; pixbuf = gdk_pixbuf_new_from_file_at_size(priv->image_path->str, 60, 60, NULL); - //g_debug("metadata_load_new_image -> pixbuf from %s", - // priv->image_path->str); + if(GDK_IS_PIXBUF(pixbuf) == FALSE){ - //g_debug("problem loading the downloaded image just use the placeholder instead"); + gtk_image_clear ( GTK_IMAGE(priv->album_art)); gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60); draw_album_art_placeholder(metadata); - return TRUE; + return FALSE; } + gtk_image_set_from_pixbuf(GTK_IMAGE(priv->album_art), pixbuf); gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf)); - g_string_erase(priv->old_image_path, 0, -1); - g_string_overwrite(priv->old_image_path, 0, priv->image_path->str); + g_string_erase (priv->old_image_path, 0, -1); + g_string_overwrite (priv->old_image_path, 0, priv->image_path->str); g_object_unref(pixbuf); } return FALSE; } + gtk_image_clear (GTK_IMAGE(priv->album_art)); gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60); draw_album_art_placeholder(metadata); - return TRUE; + return FALSE; } static void @@ -308,7 +348,7 @@ draw_album_border(GtkWidget *metadata, gboolean selected) static void draw_album_art_placeholder(GtkWidget *metadata) -{ +{ cairo_t *cr; cr = gdk_cairo_create (metadata->window); GtkStyle *style; @@ -366,33 +406,48 @@ metadata_widget_selection_received_event_callback ( GtkWidget *widget, gpointer user_data ) { - //g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE); - //MetadataWidget* widget = METADATA_WIDGET(user_data); - //MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widget); - g_debug("metadata_widget_selection_request_event_callback"); draw_album_border(widget, TRUE); } /* Suppress/consume keyevents */ static gboolean -metadata_widget_button_press_event (GtkWidget *menuitem, - GdkEventButton *event) +metadata_widget_button_release_event (GtkWidget *menuitem, + GdkEventButton *event) { - GtkClipboard* board = gtk_clipboard_get (GDK_NONE); - - MetadataWidgetPrivate* priv = METADATA_WIDGET_GET_PRIVATE(METADATA_WIDGET(menuitem)); - - gchar* contents = g_strdup_printf("artist: %s \ntitle: %s \nalbum: %s", - dbusmenu_menuitem_property_get(priv->twin_item, - DBUSMENU_METADATA_MENUITEM_ARTIST), - dbusmenu_menuitem_property_get(priv->twin_item, - DBUSMENU_METADATA_MENUITEM_TITLE), - dbusmenu_menuitem_property_get(priv->twin_item, - DBUSMENU_METADATA_MENUITEM_ALBUM)); - gtk_clipboard_set_text (board, contents, -1); - gtk_clipboard_store (board); - g_free(contents); - return FALSE; + g_return_val_if_fail (IS_METADATA_WIDGET (menuitem), FALSE); + MetadataWidgetPrivate* priv = METADATA_WIDGET_GET_PRIVATE(METADATA_WIDGET(menuitem)); + // For the left raise/launch the player + if (event->button == 1){ + GVariant* new_title_event = g_variant_new_boolean(TRUE); + dbusmenu_menuitem_handle_event (priv->twin_item, + "Title menu event", + new_title_event, + 0); + } + // For the right copy track details to clipboard only if the player is running + // and there is something there + else if (event->button == 3){ + gboolean running = dbusmenu_menuitem_property_get_bool (priv->twin_item, + DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING); + gboolean hidden = dbusmenu_menuitem_property_get_bool (priv->twin_item, + DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS); + g_return_val_if_fail ( running, FALSE ); + + g_return_val_if_fail ( !hidden, FALSE ); + + GtkClipboard* board = gtk_clipboard_get (GDK_NONE); + gchar* contents = g_strdup_printf("artist: %s \ntitle: %s \nalbum: %s", + dbusmenu_menuitem_property_get(priv->twin_item, + DBUSMENU_METADATA_MENUITEM_ARTIST), + dbusmenu_menuitem_property_get(priv->twin_item, + DBUSMENU_METADATA_MENUITEM_TITLE), + dbusmenu_menuitem_property_get(priv->twin_item, + DBUSMENU_METADATA_MENUITEM_ALBUM)); + gtk_clipboard_set_text (board, contents, -1); + gtk_clipboard_store (board); + g_free(contents); + } + return TRUE; } static void @@ -403,7 +458,6 @@ metadata_widget_property_update(DbusmenuMenuitem* item, gchar* property, if(g_variant_is_of_type(value, G_VARIANT_TYPE_INT32) == TRUE && g_variant_get_int32(value) == DBUSMENU_PROPERTY_EMPTY){ - //g_debug("Metadata widget: property update - reset"); GVariant* new_value = g_variant_new_string (""); value = new_value; } @@ -427,11 +481,55 @@ metadata_widget_property_update(DbusmenuMenuitem* item, gchar* property, g_string_erase(priv->image_path, 0, -1); g_string_overwrite(priv->image_path, 0, g_variant_get_string (value, NULL)); // if its a remote image queue a redraw incase the download took too long - if (g_str_has_prefix(g_variant_get_string (value, NULL), g_get_user_cache_dir())){ - //g_debug("the image update is a download so redraw"); - gtk_widget_queue_draw(GTK_WIDGET(mitem)); - } - } + //if (g_str_has_prefix(g_variant_get_string (value, NULL), g_get_user_cache_dir())){ + gtk_widget_queue_draw(GTK_WIDGET(mitem)); + //} + } + else if (g_ascii_strcasecmp (DBUSMENU_METADATA_MENUITEM_PLAYER_NAME, property) == 0){ + gtk_label_set_label (GTK_LABEL (priv->player_label), + g_variant_get_string(value, NULL)); + } + else if (g_ascii_strcasecmp (DBUSMENU_METADATA_MENUITEM_PLAYER_ICON, property) == 0){ + metadata_widget_set_icon (mitem); + } + else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS, property) == 0){ + metadata_widget_handle_resizing (mitem); + } +} + +static void +metadata_widget_handle_resizing (MetadataWidget* self) +{ + MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); + + if (dbusmenu_menuitem_property_get_bool (priv->twin_item, + DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS) == TRUE){ + gtk_widget_hide (priv->meta_data_h_box); + gtk_widget_hide (priv->artist_label); + gtk_widget_hide (priv->piece_label); + gtk_widget_hide (priv->container_label); + gtk_widget_hide (priv->album_art); + gtk_widget_hide (priv->meta_data_v_box); + gtk_widget_set_size_request(GTK_WIDGET(self), 200, 20); + } + else{ + + gtk_widget_show (priv->meta_data_h_box); + gtk_widget_show (priv->artist_label); + gtk_widget_show (priv->piece_label); + gtk_widget_show (priv->container_label); + gtk_widget_show (priv->album_art); + gtk_widget_show (priv->meta_data_v_box); + + gtk_widget_set_size_request(GTK_WIDGET(self), 200, 95); + // This is not working! + gtk_misc_set_alignment (GTK_MISC(gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM(self))), + 0.5 /* right aligned */, + 0); + gtk_widget_show( GTK_WIDGET(gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM(self)))); + + } + gtk_widget_queue_draw(GTK_WIDGET(self)); } static void @@ -454,9 +552,48 @@ metadata_widget_set_style(GtkWidget* metadata, GtkStyle* style) gtk_widget_queue_draw(GTK_WIDGET(metadata)); } +static void +metadata_widget_set_icon (MetadataWidget *self) +{ + MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); + + gint padding = 0; + gtk_widget_style_get(GTK_WIDGET(self), "horizontal-padding", &padding, NULL); + gint width, height; + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); + + GString* banshee_string = g_string_new ( "banshee" ); + GString* app_panel = g_string_new ( g_utf8_strdown ( dbusmenu_menuitem_property_get(priv->twin_item, DBUSMENU_METADATA_MENUITEM_PLAYER_NAME), + -1 )); + GtkWidget * icon = NULL; + + // Not ideal but apparently we want the banshee icon to be the greyscale one + // and any others to be the icon from the desktop file => colour. + if ( g_string_equal ( banshee_string, app_panel ) == TRUE && + gtk_icon_theme_has_icon ( gtk_icon_theme_get_default(), app_panel->str ) ){ + g_string_append ( app_panel, "-panel" ); + icon = gtk_image_new_from_icon_name ( app_panel->str, + GTK_ICON_SIZE_MENU ); + } + else{ + icon = gtk_image_new_from_icon_name ( g_strdup (dbusmenu_menuitem_property_get ( priv->twin_item, DBUSMENU_METADATA_MENUITEM_PLAYER_ICON )), + GTK_ICON_SIZE_MENU ); + } + g_string_free ( app_panel, FALSE) ; + g_string_free ( banshee_string, FALSE) ; + + gtk_widget_set_size_request(icon, width + + 5 /* ref triangle is 5x9 pixels */ + + 1 /* padding */, + height); + gtk_misc_set_alignment(GTK_MISC(icon), 0.5 /* right aligned */, 0); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(self), GTK_WIDGET(icon)); + gtk_widget_show(icon); +} + static void -metadata_widget_set_twin_item(MetadataWidget* self, - DbusmenuMenuitem* twin_item) +metadata_widget_set_twin_item (MetadataWidget* self, + DbusmenuMenuitem* twin_item) { MetadataWidgetPrivate* priv = METADATA_WIDGET_GET_PRIVATE(self); priv->twin_item = twin_item; @@ -479,16 +616,67 @@ metadata_widget_set_twin_item(MetadataWidget* self, g_string_erase(priv->image_path, 0, -1); const gchar *arturl = dbusmenu_menuitem_property_get( priv->twin_item, DBUSMENU_METADATA_MENUITEM_ARTURL ); + + gtk_label_set_label (GTK_LABEL(priv->player_label), + dbusmenu_menuitem_property_get(priv->twin_item, + DBUSMENU_METADATA_MENUITEM_PLAYER_NAME)); + + metadata_widget_set_icon(self); + if (arturl != NULL){ g_string_overwrite( priv->image_path, 0, arturl); - // if its a remote image queue a redraw incase the download took too long if (g_str_has_prefix (arturl, g_get_user_cache_dir())){ gtk_widget_queue_draw(GTK_WIDGET(self)); } } + metadata_widget_handle_resizing (self); +} + +// Draw the triangle if the player is running ... +static gboolean +metadata_widget_triangle_draw_cb (GtkWidget *widget, + GdkEventExpose *event, + gpointer user_data) +{ + g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE); + MetadataWidget* meta = METADATA_WIDGET(user_data); + MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(meta); + + GtkStyle *style; + cairo_t *cr; + int x, y, arrow_width, arrow_height; + + if (! dbusmenu_menuitem_property_get_bool (priv->twin_item, + DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING)){ + return FALSE; + } + + style = gtk_widget_get_style (widget); + + arrow_width = 5; + arrow_height = 9; + gint vertical_offset = 3; + + x = widget->allocation.x; + y = widget->allocation.y + (double)arrow_height/2.0 + vertical_offset; + + cr = (cairo_t*) gdk_cairo_create (widget->window); + + cairo_set_line_width (cr, 1.0); + + cairo_move_to (cr, x, y); + cairo_line_to (cr, x, y + arrow_height); + cairo_line_to (cr, x + arrow_width, y + (double)arrow_height/2.0); + cairo_close_path (cr); + cairo_set_source_rgb (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0, + style->fg[gtk_widget_get_state(widget)].green/65535.0, + style->fg[gtk_widget_get_state(widget)].blue/65535.0); + cairo_fill (cr); + cairo_destroy (cr); + return FALSE; } /** @@ -500,6 +688,8 @@ metadata_widget_new(DbusmenuMenuitem *item) { GtkWidget* widget = g_object_new(METADATA_WIDGET_TYPE, NULL); + gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (widget), + TRUE); metadata_widget_set_twin_item ( METADATA_WIDGET(widget), item ); return widget; |