diff options
-rw-r--r-- | src/common-defs.h | 10 | ||||
-rw-r--r-- | src/dbus-menu-manager.c | 6 | ||||
-rw-r--r-- | src/indicator-sound.c | 8 | ||||
-rw-r--r-- | src/metadata-menu-item.vala | 3 | ||||
-rw-r--r-- | src/metadata-widget.c | 371 | ||||
-rw-r--r-- | src/mpris-controller.vala | 15 | ||||
-rw-r--r-- | src/mpris2-controller.vala | 64 | ||||
-rw-r--r-- | src/play-button.c | 64 | ||||
-rw-r--r-- | src/player-controller.vala | 15 | ||||
-rw-r--r-- | src/player-item.vala | 11 | ||||
-rw-r--r-- | src/scrub-menu-item.vala | 2 | ||||
-rw-r--r-- | src/sound-service.c | 4 | ||||
-rw-r--r-- | src/title-widget.c | 29 |
13 files changed, 312 insertions, 290 deletions
diff --git a/src/common-defs.h b/src/common-defs.h index e3b4552..e554c11 100644 --- a/src/common-defs.h +++ b/src/common-defs.h @@ -34,16 +34,16 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #define DBUSMENU_TRANSPORT_MENUITEM_PLAY_STATE "x-canonical-sound-menu-player-transport-state" #define DBUSMENU_METADATA_MENUITEM_TYPE "x-canonical-sound-menu-player-metadata-type" -#define DBUSMENU_METADATA_MENUITEM_ARTIST "x-canonical-sound-menu-player-metadata-artist" -#define DBUSMENU_METADATA_MENUITEM_TITLE "x-canonical-sound-menu-player-metadata-title" -#define DBUSMENU_METADATA_MENUITEM_ALBUM "x-canonical-sound-menu-player-metadata-album" -#define DBUSMENU_METADATA_MENUITEM_ARTURL "x-canonical-sound-menu-player-metadata-arturl" +#define DBUSMENU_METADATA_MENUITEM_ARTIST "x-canonical-sound-menu-player-metadata-xesam:artist" +#define DBUSMENU_METADATA_MENUITEM_TITLE "x-canonical-sound-menu-player-metadata-xesam:title" +#define DBUSMENU_METADATA_MENUITEM_ALBUM "x-canonical-sound-menu-player-metadata-xesam:album" +#define DBUSMENU_METADATA_MENUITEM_ARTURL "x-canonical-sound-menu-player-metadata-mpris:artUrl" #define DBUSMENU_TITLE_MENUITEM_TYPE "x-canonical-sound-menu-player-title-type" #define DBUSMENU_TITLE_MENUITEM_NAME "x-canonical-sound-menu-player-title-name" #define DBUSMENU_SCRUB_MENUITEM_TYPE "x-canonical-sound-menu-player-scrub-type" -#define DBUSMENU_SCRUB_MENUITEM_DURATION "x-canonical-sound-menu-player-scrub-time" +#define DBUSMENU_SCRUB_MENUITEM_DURATION "x-canonical-sound-menu-player-scrub-mpris:length" #define DBUSMENU_SCRUB_MENUITEM_POSITION "x-canonical-sound-menu-player-scrub-position" #define DBUSMENU_SCRUB_MENUITEM_PLAY_STATE "x-canonical-sound-menu-player-scrub-play-state" diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 6f0af9e..5ea561f 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -119,7 +119,7 @@ void dbus_menu_manager_update_mute_ui(gboolean incoming_mute_value) b_all_muted = incoming_mute_value; dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, - b_all_muted == FALSE ? _("Mute All") : _("Unmute")); + b_all_muted == FALSE ? _("Mute") : _("Unmute")); } @@ -190,7 +190,7 @@ static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service { // Mute button mute_all_menuitem = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, b_all_muted == FALSE ? _("Mute All") : _("Unmute")); + dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, b_all_muted == FALSE ? _("Mute") : _("Unmute")); g_signal_connect(G_OBJECT(mute_all_menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(set_global_mute_from_ui), NULL); dbusmenu_menuitem_property_set_bool(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_ENABLED, b_sink_available); @@ -229,7 +229,7 @@ static void set_global_mute_from_ui() toggle_global_mute(b_all_muted); dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, - b_all_muted == FALSE ? _("Mute All") : _("Unmute")); + b_all_muted == FALSE ? _("Mute") : _("Unmute")); } diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 3a7abe9..63ad72d 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -375,8 +375,6 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u g_return_if_fail(IS_INDICATOR_SOUND(userdata)); - // Ensure we are in a coherent state with the service at start up. - // Preserve ordering! } } return; @@ -464,12 +462,7 @@ tidy_up_hash() static void update_state(const gint state) { - /* g_debug("update state beginning - previous_state = %i", previous_state);*/ - previous_state = current_state; - - /* g_debug("update state 3rd line - previous_state = %i", previous_state);*/ - current_state = state; gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); indicator_image_helper_update(speaker_image, image_name); @@ -479,7 +472,6 @@ update_state(const gint state) void determine_state_from_volume(gdouble volume_percent) { - /* g_debug("determine_state_from_volume - previous_state = %i", previous_state);*/ if (device_available == FALSE) return; gint state = previous_state; diff --git a/src/metadata-menu-item.vala b/src/metadata-menu-item.vala index 3818b1c..0bb4a85 100644 --- a/src/metadata-menu-item.vala +++ b/src/metadata-menu-item.vala @@ -29,6 +29,7 @@ public class MetadataMenuitem : PlayerItem reset(attributes_format()); } + public static HashSet<string> attributes_format() { HashSet<string> attrs = new HashSet<string>(); @@ -39,4 +40,4 @@ public class MetadataMenuitem : PlayerItem return attrs; } -}
\ No newline at end of file +} diff --git a/src/metadata-widget.c b/src/metadata-widget.c index b51dbac..f600238 100644 --- a/src/metadata-widget.c +++ b/src/metadata-widget.c @@ -34,10 +34,13 @@ struct _MetadataWidgetPrivate { GtkWidget* hbox; GtkWidget* album_art; - gchar* image_path; + GString* image_path; + GString* old_image_path; GtkWidget* artist_label; GtkWidget* piece_label; GtkWidget* container_label; + GdkColor bevel_colour; + GdkColor eight_note_colour; }; #define METADATA_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), METADATA_WIDGET_TYPE, MetadataWidgetPrivate)) @@ -47,25 +50,28 @@ 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_widget_expose_event(GtkWidget* widget, GdkEventExpose* event); +static gboolean metadata_image_expose (GtkWidget *image, GdkEventExpose *event, gpointer user_data); // keyevent consumers static gboolean metadata_widget_button_press_event (GtkWidget *menuitem, GdkEventButton *event); -static gboolean metadata_widget_button_release_event (GtkWidget *menuitem, - GdkEventButton *event); // Dbusmenuitem properties update callback -static void metadata_widget_property_update(DbusmenuMenuitem* item, gchar* property, - GValue* value, gpointer userdata); +static void metadata_widget_property_update (DbusmenuMenuitem* item, + gchar* property, + GValue* value, + gpointer userdata); -static void update_album_art(MetadataWidget* self); -static void style_artist_text(MetadataWidget* self); -static void style_title_text(MetadataWidget* self); -static void style_album_text(MetadataWidget* self); +static void metadata_widget_style_labels(MetadataWidget* self, + GtkLabel* label); + +void metadata_widget_set_style(GtkWidget* button, GtkStyle* style); +static void image_set_from_pixbuf (GtkWidget *widget, + MetadataWidget* metadata, + GdkPixbuf *source); -G_DEFINE_TYPE (MetadataWidget, metadata_widget, GTK_TYPE_MENU_ITEM); +G_DEFINE_TYPE (MetadataWidget, metadata_widget, GTK_TYPE_MENU_ITEM); static void @@ -75,13 +81,11 @@ metadata_widget_class_init (MetadataWidgetClass *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; - widget_class->expose_event = metadata_widget_expose_event; + g_type_class_add_private (klass, sizeof (MetadataWidgetPrivate)); gobject_class->dispose = metadata_widget_dispose; gobject_class->finalize = metadata_widget_finalize; - } static void @@ -98,49 +102,52 @@ metadata_widget_init (MetadataWidget *self) // image priv->album_art = gtk_image_new(); - priv->image_path = g_strdup(dbusmenu_menuitem_property_get(twin_item, DBUSMENU_METADATA_MENUITEM_ARTURL)); - update_album_art(self); - + priv->image_path = g_string_new(dbusmenu_menuitem_property_get(twin_item, DBUSMENU_METADATA_MENUITEM_ARTURL)); + priv->old_image_path = g_string_new(""); + g_debug("Metadata::At startup and image path = %s", priv->image_path->str); + + g_signal_connect(priv->album_art, "expose-event", + G_CALLBACK(metadata_image_expose), + GTK_WIDGET(self)); + gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60); + gtk_box_pack_start (GTK_BOX (priv->hbox), priv->album_art, FALSE, FALSE, 0); - GtkWidget* vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); + // artist GtkWidget* artist; artist = gtk_label_new(dbusmenu_menuitem_property_get(twin_item, DBUSMENU_METADATA_MENUITEM_ARTIST)); - gtk_misc_set_alignment(GTK_MISC(artist), (gfloat)0, (gfloat)0); + gtk_misc_set_padding (GTK_MISC(artist), (gfloat)10, (gfloat)0); gtk_label_set_width_chars(GTK_LABEL(artist), 15); gtk_label_set_ellipsize(GTK_LABEL(artist), PANGO_ELLIPSIZE_MIDDLE); + metadata_widget_style_labels(self, GTK_LABEL(artist)); priv->artist_label = artist; - // Style it up. - style_artist_text(self); - // piece + // title GtkWidget* piece; piece = gtk_label_new(dbusmenu_menuitem_property_get(twin_item, DBUSMENU_METADATA_MENUITEM_TITLE)); gtk_misc_set_alignment(GTK_MISC(piece), (gfloat)0, (gfloat)0); - gtk_label_set_width_chars(GTK_LABEL(piece), 12); + gtk_misc_set_padding (GTK_MISC(piece), (gfloat)10, (gfloat)0); + gtk_label_set_width_chars(GTK_LABEL(piece), 15); gtk_label_set_ellipsize(GTK_LABEL(piece), PANGO_ELLIPSIZE_MIDDLE); + metadata_widget_style_labels(self, GTK_LABEL(piece)); priv->piece_label = piece; - // Style it up. - style_title_text(self); // container GtkWidget* container; container = gtk_label_new(dbusmenu_menuitem_property_get(twin_item, DBUSMENU_METADATA_MENUITEM_ALBUM)); gtk_misc_set_alignment(GTK_MISC(container), (gfloat)0, (gfloat)0); + gtk_misc_set_padding (GTK_MISC(container), (gfloat)10, (gfloat)0); gtk_label_set_width_chars(GTK_LABEL(container), 15); gtk_label_set_ellipsize(GTK_LABEL(container), PANGO_ELLIPSIZE_MIDDLE); + metadata_widget_style_labels(self, GTK_LABEL(container)); priv->container_label = container; - // Style it up. - style_album_text(self); - // Pack in the right order gtk_box_pack_start (GTK_BOX (vbox), priv->piece_label, FALSE, FALSE, 0); 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); @@ -150,19 +157,13 @@ metadata_widget_init (MetadataWidget *self) g_signal_connect(G_OBJECT(twin_item), "property-changed", G_CALLBACK(metadata_widget_property_update), self); gtk_widget_show_all (priv->hbox); + + g_signal_connect(self, "style-set", G_CALLBACK(metadata_widget_set_style), GTK_WIDGET(self)); + gtk_widget_set_size_request(GTK_WIDGET(self), 200, 60); gtk_container_add (GTK_CONTAINER (self), hbox); } -static gboolean -metadata_widget_expose_event(GtkWidget* widget, GdkEventExpose* event) -{ - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widget); - - gtk_container_propagate_expose(GTK_CONTAINER(widget), priv->hbox, event); - return TRUE; -} - static void metadata_widget_dispose (GObject *object) { @@ -175,21 +176,110 @@ metadata_widget_finalize (GObject *object) G_OBJECT_CLASS (metadata_widget_parent_class)->finalize (object); } -/* Suppress/consume keyevents */ +/** + * We override the expose method to enable primitive drawing of the + * empty album art image (and soon rounded rectangles on the album art) + */ static gboolean -metadata_widget_button_press_event (GtkWidget *menuitem, - GdkEventButton *event) +metadata_image_expose (GtkWidget *metadata, GdkEventExpose *event, gpointer user_data) { - g_debug("MetadataWidget::menu_press_event"); + g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE); + MetadataWidget* widget = METADATA_WIDGET(user_data); + MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widget); + + if(priv->image_path->len > 0){ + + if(g_string_equal(priv->image_path, priv->old_image_path) == FALSE){ + GdkPixbuf* pixbuf; + pixbuf = gdk_pixbuf_new_from_file(priv->image_path->str, NULL); + g_debug("metadata_widget_expose, album art update -> pixbuf from %s", + priv->image_path->str); + pixbuf = gdk_pixbuf_scale_simple(pixbuf,60, 60, GDK_INTERP_BILINEAR); + image_set_from_pixbuf (metadata, widget, pixbuf); + 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; + } + + cairo_t *cr; + cr = gdk_cairo_create (metadata->window); + GtkAllocation alloc; + gtk_widget_get_allocation (metadata, &alloc); + + cairo_rectangle (cr, + alloc.x, alloc.y, + alloc.width, alloc.height); + cairo_clip(cr); + + cairo_move_to (cr, alloc.x , alloc.y); + cairo_line_to(cr, alloc.x + alloc.width, + alloc.y); + cairo_line_to(cr, alloc.x + alloc.width, + alloc.y + alloc.height); + cairo_line_to(cr, alloc.x, alloc.y + alloc.height); + cairo_line_to(cr, alloc.x, alloc.y); + + cairo_close_path (cr); + + cairo_set_source_rgba (cr, 123.0f / 255.0f, 123.0f / 255.0f, 120.0f / 255.0f, .8f); + cairo_set_line_width (cr, 2.0); + + cairo_stroke (cr); + + // Draw the eight note + PangoLayout *layout; + PangoFontDescription *desc; + layout = pango_cairo_create_layout(cr); + PangoContext* pcontext = pango_cairo_create_context(cr); + pango_cairo_context_set_resolution (pcontext, 96); + + GString* string = g_string_new(""); + gssize size = -1; + gunichar code = g_utf8_get_char_validated("\342\231\253", size); + g_string_append_unichar (string, code); + + pango_layout_set_text(layout, string->str, -1); + desc = pango_font_description_from_string("Sans Bold 30"); + pango_layout_set_font_description(layout, desc); + pango_font_description_free(desc); + + cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.8); + pango_cairo_update_layout(cr, layout); + cairo_move_to (cr, alloc.x + alloc.width/6, alloc.y); + pango_cairo_show_layout(cr, layout); + + g_object_unref(layout); + g_object_unref(pcontext); + g_string_free (string, TRUE); + cairo_destroy (cr); + return TRUE; } +/* Suppress/consume keyevents */ static gboolean -metadata_widget_button_release_event (GtkWidget *menuitem, +metadata_widget_button_press_event (GtkWidget *menuitem, GdkEventButton *event) { - g_debug("MetadataWidget::menu_release_event"); - return TRUE; + GtkClipboard* board = gtk_clipboard_get (GDK_NONE); + gchar* title = g_strdup(dbusmenu_menuitem_property_get(twin_item, + DBUSMENU_METADATA_MENUITEM_TITLE)); + gchar* artist = g_strdup(dbusmenu_menuitem_property_get(twin_item, + DBUSMENU_METADATA_MENUITEM_ARTIST)); + gchar* album = g_strdup(dbusmenu_menuitem_property_get(twin_item, + DBUSMENU_METADATA_MENUITEM_ALBUM)); + gchar* contents = g_strdup_printf("artist: %s \ntitle: %s \nalbum: %s", artist, title, album); + g_debug("contents to be copied will be : %s", contents); + gtk_clipboard_set_text (board, contents, -1); + gtk_clipboard_store (board); + g_free(contents); + g_free(title); + g_free(artist); + g_free(album); + return FALSE; } // TODO: Manage empty/mangled music details <unknown artist> etc. @@ -212,24 +302,19 @@ metadata_widget_property_update(DbusmenuMenuitem* item, gchar* property, if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTIST, property) == 0){ gtk_label_set_text(GTK_LABEL(priv->artist_label), g_value_get_string(value)); - style_artist_text(mitem); + metadata_widget_style_labels(mitem, GTK_LABEL(priv->artist_label)); } else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_TITLE, property) == 0){ gtk_label_set_text(GTK_LABEL(priv->piece_label), g_value_get_string(value)); - style_title_text(mitem); + metadata_widget_style_labels(mitem, GTK_LABEL(priv->piece_label)); } else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ALBUM, property) == 0){ gtk_label_set_text(GTK_LABEL(priv->container_label), g_value_get_string(value)); - style_album_text(mitem); + metadata_widget_style_labels(mitem, GTK_LABEL(priv->container_label)); } else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTURL, property) == 0){ - if(priv->image_path != NULL){ - g_free(priv->image_path); - } - priv->image_path = g_value_dup_string(value); - if(priv->image_path != NULL){ - update_album_art(mitem); - } + g_string_erase(priv->image_path, 0, -1); + g_string_overwrite(priv->image_path, 0, g_value_get_string (value)); } } @@ -296,129 +381,113 @@ rounded_rectangle (cairo_t *cr, } static void -image_set_from_pixbuf (GtkImage *image, +image_set_from_pixbuf (GtkWidget *widget, + MetadataWidget* metadata, GdkPixbuf *source) { - cairo_t *cr; - cairo_t *cr_mask; - cairo_surface_t *surface; - GdkPixmap *pixmap; - GdkPixmap *bitmask; - int w; - int h; - int frame_width; - double radius; - GdkColor color; - double r; - double g; - double b; - - frame_width = 5; + cairo_t *cr; + cairo_t *cr_mask; + cairo_surface_t *surface; + GdkPixmap *pixmap; + GdkPixmap *bitmask; + int w; + int h; + int frame_width; + double radius; + GdkColor color; + double r; + double g; + double b; + + MetadataWidgetPrivate* priv = METADATA_WIDGET_GET_PRIVATE(metadata); + GtkImage* image = GTK_IMAGE(priv->album_art); + frame_width = 5; - w = gdk_pixbuf_get_width (source) + frame_width * 2; - h = gdk_pixbuf_get_height (source) + frame_width * 2; + w = gdk_pixbuf_get_width (source) + frame_width * 2; + h = gdk_pixbuf_get_height (source) + frame_width * 2; - radius = w / 10; + radius = w / 10; - pixmap = gdk_pixmap_new (gtk_widget_get_window (GTK_WIDGET (image)), w, h, -1); - bitmask = gdk_pixmap_new (gtk_widget_get_window (GTK_WIDGET (image)), w, h, 1); + pixmap = gdk_pixmap_new (gtk_widget_get_window (widget), w, h, -1); + bitmask = gdk_pixmap_new (gtk_widget_get_window (widget), w, h, 1); - if (gtk_widget_get_window (GTK_WIDGET (image)) == NULL) + if (gtk_widget_get_window (widget) == NULL) return; - cr = gdk_cairo_create (pixmap); - cr_mask = gdk_cairo_create (bitmask); + cr = gdk_cairo_create (pixmap); + cr_mask = gdk_cairo_create (bitmask); - /* setup mask */ - cairo_rectangle (cr_mask, 0, 0, w, h); - cairo_set_operator (cr_mask, CAIRO_OPERATOR_CLEAR); - cairo_fill (cr_mask); + /* setup mask */ + cairo_rectangle (cr_mask, 0, 0, w, h); + cairo_set_operator (cr_mask, CAIRO_OPERATOR_CLEAR); + cairo_fill (cr_mask); - rounded_rectangle (cr_mask, 1.0, 0.5, 0.5, radius, w - 1, h - 1); - cairo_set_operator (cr_mask, CAIRO_OPERATOR_OVER); - cairo_set_source_rgb (cr_mask, 1, 1, 1); - cairo_fill (cr_mask); + rounded_rectangle (cr_mask, 1.0, 0.5, 0.5, radius, w - 1, h - 1); + cairo_set_operator (cr_mask, CAIRO_OPERATOR_OVER); + cairo_set_source_rgb (cr_mask, 1, 1, 1); + cairo_fill (cr_mask); - color = gtk_widget_get_style (GTK_WIDGET (image))->bg [GTK_STATE_NORMAL]; - r = (float)color.red / 65535.0; - g = (float)color.green / 65535.0; - b = (float)color.blue / 65535.0; + color = gtk_widget_get_style (GTK_WIDGET (image))->bg [GTK_STATE_NORMAL]; + r = (float)color.red / 65535.0; + g = (float)color.green / 65535.0; + b = (float)color.blue / 65535.0; - /* set up image */ - cairo_rectangle (cr, 0, 0, w, h); - cairo_set_source_rgb (cr, r, g, b); - cairo_fill (cr); + /* set up image */ + cairo_rectangle (cr, 0, 0, w, h); + cairo_set_source_rgb (cr, r, g, b); + cairo_fill (cr); - rounded_rectangle (cr, - 1.0, - frame_width + 0.5, - frame_width + 0.5, - radius, - w - frame_width * 2 - 1, - h - frame_width * 2 - 1); - cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.3); - cairo_fill_preserve (cr); + rounded_rectangle (cr, + 1.0, + frame_width + 0.5, + frame_width + 0.5, + radius, + w - frame_width * 2 - 1, + h - frame_width * 2 - 1); + cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.3); + cairo_fill_preserve (cr); - surface = surface_from_pixbuf (source); - cairo_set_source_surface (cr, surface, frame_width, frame_width); - cairo_fill (cr); + surface = surface_from_pixbuf (source); + cairo_set_source_surface (cr, surface, frame_width, frame_width); + cairo_fill (cr); - gtk_image_set_from_pixmap (image, pixmap, bitmask); + gtk_image_set_from_pixmap (image, pixmap, bitmask); - cairo_surface_destroy (surface); + cairo_surface_destroy (surface); - g_object_unref (bitmask); - g_object_unref (pixmap); + g_object_unref (bitmask); + g_object_unref (pixmap); - cairo_destroy (cr_mask); - cairo_destroy (cr); -} - -static void -update_album_art(MetadataWidget* self){ - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); - GdkPixbuf* pixbuf; - pixbuf = gdk_pixbuf_new_from_file(priv->image_path, NULL); - pixbuf = gdk_pixbuf_scale_simple(pixbuf,60, 60, GDK_INTERP_BILINEAR); - g_debug("attempting to set the image with path %s", priv->image_path); - image_set_from_pixbuf (GTK_IMAGE(priv->album_art), pixbuf); - g_object_unref(pixbuf); + cairo_destroy (cr_mask); + cairo_destroy (cr); } // TODO refactor next 3 methods into one once the style has been -// "signed off" by design static void -style_artist_text(MetadataWidget* self) +metadata_widget_style_labels(MetadataWidget* self, GtkLabel* label) { - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); char* markup; - markup = g_markup_printf_escaped ("<span size=\"small\">%s</span>", - gtk_label_get_text(GTK_LABEL(priv->artist_label))); - gtk_label_set_markup (GTK_LABEL (priv->artist_label), markup); - g_free(markup); + markup = g_markup_printf_escaped ("<span size=\"smaller\">%s</span>", + gtk_label_get_text(GTK_LABEL(label))); + gtk_label_set_markup (GTK_LABEL (label), markup); + g_free(markup); } -static void -style_title_text(MetadataWidget* self) +void +metadata_widget_set_style(GtkWidget* metadata, GtkStyle* style) { - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); - - char* markup; - markup = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>", - gtk_label_get_text(GTK_LABEL(priv->piece_label))); - gtk_label_set_markup (GTK_LABEL (priv->piece_label), markup); - g_free(markup); -} - -static void -style_album_text(MetadataWidget* self) -{ - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); - char* markup; - markup = g_markup_printf_escaped ("<span size=\"small\">%s</span>", - gtk_label_get_text(GTK_LABEL(priv->container_label))); - gtk_label_set_markup (GTK_LABEL (priv->container_label), markup); - g_free(markup); + g_return_if_fail(IS_METADATA_WIDGET(metadata)); + MetadataWidget* widg = METADATA_WIDGET(metadata); + MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widg); + if(style == NULL){ + g_warning("metadata_widget_set_style -> style is NULL!"); + return; + } + else{ + g_debug("metadata_widget: about to set the style colours"); + priv->eight_note_colour = style->fg[GTK_STATE_NORMAL]; + priv->bevel_colour = style->bg[GTK_STATE_NORMAL]; + } } /** diff --git a/src/mpris-controller.vala b/src/mpris-controller.vala index 1e1e00a..fc9eee0 100644 --- a/src/mpris-controller.vala +++ b/src/mpris-controller.vala @@ -61,10 +61,6 @@ public class MprisController : GLib.Object (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(play_state); this.owner.custom_items[PlayerController.widget_order.METADATA].update(this.mpris_player.GetMetadata(), MetadataMenuitem.attributes_format()); - this.owner.custom_items[PlayerController.widget_order.SCRUB].update(this.mpris_player.GetMetadata(), - ScrubMenuitem.attributes_format()); - ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem; - scrub.update_position(this.mpris_player.PositionGet()); } public void transport_event(TransportMenuitem.action command) @@ -96,8 +92,6 @@ public class MprisController : GLib.Object double new_time_position = total_time * position/100.0; debug("new position = %f", (new_time_position * 1000)); this.mpris_player.PositionSet((int32)(new_time_position)); - ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem; - scrub.update_position(this.mpris_player.PositionGet()); } public bool connected() @@ -117,7 +111,6 @@ public class MprisController : GLib.Object v.set_int(play_state); ht.insert("state", v); this.owner.custom_items[PlayerController.widget_order.TRANSPORT].update(ht, TransportMenuitem.attributes_format()); - this.owner.custom_items[PlayerController.widget_order.SCRUB].update(ht, ScrubMenuitem.attributes_format()); } private void onTrackChange(dynamic DBus.Object mpris_client, HashTable<string,Value?> ht) @@ -125,21 +118,13 @@ public class MprisController : GLib.Object debug("onTrackChange"); this.owner.custom_items[PlayerController.widget_order.METADATA].reset(MetadataMenuitem.attributes_format()); - this.owner.custom_items[PlayerController.widget_order.SCRUB].reset(ScrubMenuitem.attributes_format()); - //HashTable<string, Value?> status_hash = new HashTable<string, Value?>(str_hash, str_equal); status st = this.mpris_player.GetStatus(); int play_state = st.playback; debug("GetStatusChange, about to update scrub with play state - %i", play_state); - ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem; - scrub.update_playstate(play_state); - this.owner.custom_items[PlayerController.widget_order.SCRUB].update(this.mpris_player.GetMetadata(), - ScrubMenuitem.attributes_format()); this.owner.custom_items[PlayerController.widget_order.METADATA].update(ht, MetadataMenuitem.attributes_format()); debug("about to update the duration on the scrub bar"); - // temporary fix - scrub.update_position(this.mpris_player.PositionGet()); } } diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 65d881a..df2bbd3 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -19,6 +19,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. */ using DBus; + [DBus (name = "org.mpris.MediaPlayer2")] public interface MprisRoot : DBus.Object { // properties @@ -89,7 +90,7 @@ public class Mpris2Controller : GLib.Object this.properties_interface.PropertiesChanged += property_changed_cb; } catch (DBus.Error e) { - error("Problems connecting to the session bus - %s", e.message); + error("Problems connecting to the session bus - %s", e.message); } } @@ -106,33 +107,41 @@ public class Mpris2Controller : GLib.Object debug("new playback state = %s", state); int p = this.determine_play_state(state); (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p); - (this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem).update_playstate(p); } Value? pos_v = changed_properties.lookup("Position"); if(pos_v != null){ int64 pos = pos_v.get_int64(); debug("new position = %i", (int)pos); - (this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem).update_position((int32)pos); } Value? meta_v = changed_properties.lookup("Metadata"); if(meta_v != null){ - debug("metadata is not empty"); - debug("artist : %s", this.player.Metadata.lookup("artist").get_string()); - this.owner.custom_items[PlayerController.widget_order.METADATA].reset(MetadataMenuitem.attributes_format()); - this.owner.custom_items[PlayerController.widget_order.METADATA].update(this.player.Metadata, + GLib.HashTable<string, Value?> changed_updates = clean_metadata(); + this.owner.custom_items[PlayerController.widget_order.METADATA].reset(MetadataMenuitem.attributes_format()); + this.owner.custom_items[PlayerController.widget_order.METADATA].update(changed_updates, MetadataMenuitem.attributes_format()); - this.owner.custom_items[PlayerController.widget_order.SCRUB].reset(ScrubMenuitem.attributes_format()); - if((int)this.player.Metadata.lookup("artist").get_string().len() > 0 || - (int)this.player.Metadata.lookup("artist").get_string().len() > 0){ - this.owner.custom_items[PlayerController.widget_order.SCRUB].update(this.player.Metadata, - ScrubMenuitem.attributes_format()); - } - (this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem).update_playstate(this.determine_play_state(this.player.PlaybackStatus)); - } } + + private GLib.HashTable<string, Value?> clean_metadata() + { + GLib.HashTable<string, Value?> changed_updates = this.player.Metadata; + Value? artist_v = this.player.Metadata.lookup("xesam:artist"); + if(artist_v != null){ + string[] artists = (string[])this.player.Metadata.lookup("xesam:artist"); + string display_artists = string.joinv(", ", artists); + changed_updates.replace("xesam:artist", display_artists); + debug("artist : %s", display_artists); + } + Value? length_v = this.player.Metadata.lookup("mpris:length"); + if(length_v != null){ + int64 duration = this.player.Metadata.lookup("mpris:length").get_int64(); + changed_updates.replace("mpris:length", duration/1000000); + } + return changed_updates; + } + private int determine_play_state(string status){ if(status == null) @@ -157,10 +166,9 @@ public class Mpris2Controller : GLib.Object debug("initial update - play state %i", status); (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(status); - this.owner.custom_items[PlayerController.widget_order.METADATA].update(this.player.Metadata, + GLib.HashTable<string, Value?> cleaned_metadata = this.clean_metadata(); + this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata, MetadataMenuitem.attributes_format()); - this.owner.custom_items[PlayerController.widget_order.SCRUB].update(this.player.Metadata, - ScrubMenuitem.attributes_format()); } public void transport_event(TransportMenuitem.action command) @@ -202,25 +210,25 @@ public class Mpris2Controller : GLib.Object public void set_position(double position) { debug("Set position with pos (0-100) %f", position); - HashTable<string, Value?> data = this.player.Metadata; - Value? time_value = data.lookup("time"); + Value? time_value = this.player.Metadata.lookup("mpris:length"); if(time_value == null){ warning("Can't fetch the duration of the track therefore cant set the position"); return; } - // work in microseconds (scale up by 10 TTP-of 3) - uint32 total_time = time_value.get_uint() * 1000; + // work in microseconds (scale up by 10 TTP-of 6) + int64 total_time = time_value.get_int64(); debug("total time of track = %i", (int)total_time); - double new_time_position = total_time * position/100.0; + double new_time_position = total_time * (position/100.0); debug("new position = %f", (new_time_position)); - Value? v = this.player.Metadata.lookup("trackid"); + Value? v = this.player.Metadata.lookup("mpris:trackid"); if(v != null){ if(v.holds (typeof (string))){ - debug("the trackid = %s", v.get_string()); DBus.ObjectPath path = new ObjectPath(v.get_string()); try{ - //this.player.SetPosition(path, (int64)(new_time_position)); + this.player.SetPosition(path, (int64)(new_time_position)); + //ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem; + //scrub.update_position(((int32)new_time_position) / 1000); } catch(DBus.Error e){ error("DBus Error calling the player objects SetPosition method %s", @@ -232,8 +240,8 @@ public class Mpris2Controller : GLib.Object public void onSeeked(int64 position){ debug("Seeked signal callback with pos = %i", (int)position/1000); - ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem; - scrub.update_position((int32)position/1000); + //ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem; + //scrub.update_position((int32)position/1000); } public bool connected() diff --git a/src/play-button.c b/src/play-button.c index 2f3a553..a2eaf2e 100644 --- a/src/play-button.c +++ b/src/play-button.c @@ -750,9 +750,9 @@ draw (GtkWidget* button, cairo_t *cr) X, Y + 2, RECT_WIDTH - 4, - INNER_RADIUS, - INNER_START, - INNER_END); + MIDDLE_RADIUS, + MIDDLE_START, + MIDDLE_END); if(priv->current_command == TRANSPORT_PREVIOUS){ draw_gradient (cr, @@ -774,35 +774,35 @@ draw (GtkWidget* button, cairo_t *cr) } // play/pause-background - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)), - CIRCLE_RADIUS, - OUTER_START, - OUTER_END); - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 0.5f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 0.5f, - CIRCLE_RADIUS - 0.75f, - MIDDLE_START, - MIDDLE_END); - - if(priv->current_command == TRANSPORT_PLAY_PAUSE){ - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.5f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.5f, - CIRCLE_RADIUS - 1.5f, - INNER_COMPRESSED_START, - INNER_COMPRESSED_END); - } - else{ - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.5f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.5f, - CIRCLE_RADIUS - 1.5f, - INNER_START, - INNER_END); - } + draw_circle (cr, + X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f, + Y - ((CIRCLE_RADIUS - OUTER_RADIUS)), + CIRCLE_RADIUS, + OUTER_START, + OUTER_END); + draw_circle (cr, + X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 0.5f, + Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 0.5f, + CIRCLE_RADIUS - 0.75f, + MIDDLE_START, + MIDDLE_END); + + if(priv->current_command == TRANSPORT_PLAY_PAUSE){ + draw_circle (cr, + X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.5f, + Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.5f, + CIRCLE_RADIUS - 1.5f, + INNER_COMPRESSED_START, + INNER_COMPRESSED_END); + } + else{ + draw_circle (cr, + X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.5f, + Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.5f, + CIRCLE_RADIUS - 1.5f, + MIDDLE_START, + MIDDLE_END); + } // draw previous-button drop-shadow _setup (&cr_surf, &surf, PREV_WIDTH, PREV_HEIGHT); _mask_prev (cr_surf, diff --git a/src/player-controller.vala b/src/player-controller.vala index 2aa4382..3e12dce 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -23,13 +23,12 @@ using Gee; public class PlayerController : GLib.Object { - public const int WIDGET_QUANTITY = 5; + public const int WIDGET_QUANTITY = 4; public static enum widget_order{ SEPARATOR, TITLE, METADATA, - SCRUB, TRANSPORT, } @@ -114,25 +113,19 @@ public class PlayerController : GLib.Object update_state(PlayerController.state.OFFLINE); this.custom_items[widget_order.TRANSPORT].reset(TransportMenuitem.attributes_format()); this.custom_items[widget_order.METADATA].reset(MetadataMenuitem.attributes_format()); - this.custom_items[widget_order.SCRUB].reset(ScrubMenuitem.attributes_format()); } public void update_layout() - { - + { if(this.current_state != state.CONNECTED){ this.custom_items[widget_order.TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE, false); - this.custom_items[widget_order.SCRUB].property_set_bool(MENUITEM_PROP_VISIBLE, - false); this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, false); return; } this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, this.custom_items[widget_order.METADATA].populated(MetadataMenuitem.attributes_format())); - this.custom_items[widget_order.SCRUB].property_set_bool(MENUITEM_PROP_VISIBLE, - this.custom_items[widget_order.SCRUB].populated(ScrubMenuitem.attributes_format())); this.custom_items[widget_order.TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE, true); } @@ -150,10 +143,6 @@ public class PlayerController : GLib.Object MetadataMenuitem metadata_item = new MetadataMenuitem(); this.custom_items.add(metadata_item); - // Scrub item - ScrubMenuitem scrub_item = new ScrubMenuitem(this); - this.custom_items.add(scrub_item); - // Transport item TransportMenuitem transport_item = new TransportMenuitem(this); this.custom_items.add(transport_item); diff --git a/src/player-item.vala b/src/player-item.vala index e5d8bfc..fbfacbd 100644 --- a/src/player-item.vala +++ b/src/player-item.vala @@ -60,7 +60,7 @@ public class PlayerItem : Dbusmenu.Menuitem string update = v.get_string().strip(); debug("with value : %s", update); // Special case for the arturl URI's. - if(property.contains("arturl")){ + if(property.contains("mpris:artUrl")){ try{ update = Filename.from_uri(update.strip()); } @@ -74,9 +74,9 @@ public class PlayerItem : Dbusmenu.Menuitem debug("with value : %i", v.get_int()); this.property_set_int(property, v.get_int()); } - else if (v.holds (typeof (uint))){ - debug("with value : %i", (int)v.get_uint()); - this.property_set_int(property, (int)v.get_uint()); + else if (v.holds (typeof (int64))){ + debug("with value : %i", (int)v.get_int64()); + this.property_set_int(property, (int)v.get_int64()); } else if(v.holds (typeof (bool))){ debug("with value : %s", v.get_boolean().to_string()); @@ -92,8 +92,9 @@ public class PlayerItem : Dbusmenu.Menuitem public bool populated(HashSet<string> attrs) { foreach(string prop in attrs){ + debug("populated ? - prop: %s", prop); int value_int = property_get_int(prop); - debug("populate - prop %s and value %i", prop, value_int); + debug("populated ? - prop %s and value %i", prop, value_int); if(property_get_int(prop) != EMPTY){ return true; } diff --git a/src/scrub-menu-item.vala b/src/scrub-menu-item.vala index 7368a0c..d7b60a0 100644 --- a/src/scrub-menu-item.vala +++ b/src/scrub-menu-item.vala @@ -42,7 +42,7 @@ public class ScrubMenuitem : PlayerItem public void update_playstate(int state) { - this.property_set_int(MENUITEM_PLAY_STATE, state); + this.property_set_int(MENUITEM_PLAY_STATE, state); } public static HashSet<string> attributes_format() diff --git a/src/sound-service.c b/src/sound-service.c index 12f067e..42ce116 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -41,8 +41,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) if (mainloop != NULL) { g_debug("Service shutdown !"); // TODO: uncomment for release !! - close_pulse_activites(); - g_main_loop_quit(mainloop); + //close_pulse_activites(); + //g_main_loop_quit(mainloop); } return; } diff --git a/src/title-widget.c b/src/title-widget.c index 8037eb7..e9f34d6 100644 --- a/src/title-widget.c +++ b/src/title-widget.c @@ -49,10 +49,6 @@ static void title_widget_finalize (GObject *object); // keyevent consumers static gboolean title_widget_button_press_event (GtkWidget *menuitem, GdkEventButton *event); -static gboolean title_widget_button_release_event (GtkWidget *menuitem, - GdkEventButton *event); -static gboolean title_widget_expose_event(GtkWidget* widget, - GdkEventExpose* event); // Dbusmenuitem properties update callback static void title_widget_property_update(DbusmenuMenuitem* item, gchar* property, @@ -72,8 +68,6 @@ title_widget_class_init (TitleWidgetClass *klass) GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); widget_class->button_press_event = title_widget_button_press_event; - widget_class->button_release_event = title_widget_button_release_event; - widget_class->expose_event = title_widget_expose_event; g_type_class_add_private (klass, sizeof (TitleWidgetPrivate)); @@ -124,24 +118,7 @@ title_widget_button_press_event (GtkWidget *menuitem, g_value_set_boolean(&value, TRUE); dbusmenu_menuitem_handle_event (priv->twin_item, "Title menu event", &value, 0); - return TRUE; -} - -static gboolean -title_widget_button_release_event (GtkWidget *menuitem, - GdkEventButton *event) -{ - g_debug("TitleWidget::menu_release_event"); - return TRUE; -} - -static gboolean -title_widget_expose_event(GtkWidget* widget, GdkEventExpose* event) -{ - TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(widget); - - gtk_container_propagate_expose(GTK_CONTAINER(widget), priv->hbox, event); - return TRUE; + return FALSE; } static void @@ -183,12 +160,12 @@ title_widget_style_name_text(TitleWidget* self) TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(self); char* markup; - markup = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>", + markup = g_markup_printf_escaped ("<span size=\"medium\">%s</span>", gtk_label_get_text(GTK_LABEL(priv->name))); gtk_label_set_markup (GTK_LABEL (priv->name), markup); g_free(markup); } - + /** * transport_new: * @returns: a new #TitleWidget. |