aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac4
-rw-r--r--src/Makefile.am3
-rw-r--r--src/common-defs.h19
-rw-r--r--src/indicator-sound.c41
-rw-r--r--src/metadata-menu-item.vala73
-rw-r--r--src/metadata-widget.c321
-rw-r--r--src/metadata-widget.h4
-rw-r--r--src/mpris2-controller.vala21
-rw-r--r--src/player-controller.vala35
-rw-r--r--src/player-item.vala6
-rw-r--r--src/sound-service-dbus.c6
-rw-r--r--src/sound-service.c6
-rw-r--r--src/title-menu-item.vala68
-rw-r--r--src/title-widget.c248
-rw-r--r--src/title-widget.h52
-rw-r--r--vapi/common-defs.vapi13
16 files changed, 387 insertions, 533 deletions
diff --git a/configure.ac b/configure.ac
index 22f04c5..ab02d4e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,10 +1,10 @@
-AC_INIT(indicator-sound, 0.7.0, conor.curran@canonical.com)
+AC_INIT(indicator-sound, 0.7.1, conor.curran@canonical.com)
AC_PREREQ(2.53)
AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(indicator-sound, 0.7.0)
+AM_INIT_AUTOMAKE(indicator-sound, 0.7.1)
AM_MAINTAINER_MODE
diff --git a/src/Makefile.am b/src/Makefile.am
index 59c8f14..fde333a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,8 +18,6 @@ libsoundmenu_la_SOURCES = \
transport-widget.h \
metadata-widget.c \
metadata-widget.h \
- title-widget.c \
- title-widget.h \
volume-widget.c \
volume-widget.h \
voip-input-widget.c \
@@ -50,7 +48,6 @@ music_bridge_VALASOURCES = \
transport-menu-item.vala \
track-specific-menu-item.vala \
metadata-menu-item.vala \
- title-menu-item.vala \
player-controller.vala \
mpris2-interfaces.vala \
mpris2-watcher.vala \
diff --git a/src/common-defs.h b/src/common-defs.h
index 65829a3..a20fb03 100644
--- a/src/common-defs.h
+++ b/src/common-defs.h
@@ -69,16 +69,15 @@ typedef enum {
#define DBUSMENU_TRACK_SPECIFIC_MENUITEM_TYPE "x-canonical-sound-menu-player-track-specific-type"
-#define DBUSMENU_METADATA_MENUITEM_TYPE "x-canonical-sound-menu-player-metadata-type"
-#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_TITLE_MENUITEM_ICON "x-canonical-sound-menu-player-title-icon"
-#define DBUSMENU_TITLE_MENUITEM_RUNNING "x-canonical-sound-menu-player-title-running"
+#define DBUSMENU_METADATA_MENUITEM_TYPE "x-canonical-sound-menu-player-metadata-type"
+#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_METADATA_MENUITEM_PLAYER_NAME "x-canonical-sound-menu-player-metadata-player-name"
+#define DBUSMENU_METADATA_MENUITEM_PLAYER_ICON "x-canonical-sound-menu-player-metadata-player-icon"
+#define DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING "x-canonical-sound-menu-player-metadata-player-running"
+#define DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS "x-canonical-sound-menu-player-metadata-hide-track-details"
#define DBUSMENU_SCRUB_MENUITEM_TYPE "x-canonical-sound-menu-player-scrub-type"
#define DBUSMENU_SCRUB_MENUITEM_DURATION "x-canonical-sound-menu-player-scrub-mpris:length"
diff --git a/src/indicator-sound.c b/src/indicator-sound.c
index 5002463..f2ec0a2 100644
--- a/src/indicator-sound.c
+++ b/src/indicator-sound.c
@@ -31,7 +31,6 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include "indicator-sound.h"
#include "transport-widget.h"
#include "metadata-widget.h"
-#include "title-widget.h"
#include "volume-widget.h"
#include "voip-input-widget.h"
#include "dbus-shared-names.h"
@@ -94,10 +93,6 @@ static gboolean new_metadata_widget (DbusmenuMenuitem * newitem,
DbusmenuMenuitem * parent,
DbusmenuClient * client,
gpointer user_data);
-static gboolean new_title_widget (DbusmenuMenuitem * newitem,
- DbusmenuMenuitem * parent,
- DbusmenuClient * client,
- gpointer user_data);
// DBUS communication
static GDBusNodeInfo *node_info = NULL;
@@ -208,9 +203,6 @@ get_menu (IndicatorObject * io)
dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client),
DBUSMENU_METADATA_MENUITEM_TYPE,
new_metadata_widget);
- dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client),
- DBUSMENU_TITLE_MENUITEM_TYPE,
- new_title_widget);
// Note: Not ideal but all key handling needs to be managed here and then
// delegated to the appropriate widget.
g_signal_connect (menu, "key-press-event", G_CALLBACK(key_press_cb), io);
@@ -360,36 +352,19 @@ new_metadata_widget (DbusmenuMenuitem * newitem,
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
+
metadata = metadata_widget_new (newitem);
+
+ g_debug ("%s (\"%s\")", __func__,
+ dbusmenu_menuitem_property_get(newitem, DBUSMENU_METADATA_MENUITEM_PLAYER_NAME));
+
GtkMenuItem *menu_metadata_widget = GTK_MENU_ITEM(metadata);
gtk_widget_show_all(metadata);
dbusmenu_gtkclient_newitem_base (DBUSMENU_GTKCLIENT(client),
- newitem, menu_metadata_widget, parent);
- return TRUE;
-}
-
-static gboolean
-new_title_widget(DbusmenuMenuitem * newitem,
- DbusmenuMenuitem * parent,
- DbusmenuClient * client,
- gpointer user_data)
-{
- g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
- g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
-
- g_debug ("%s (\"%s\")", __func__, dbusmenu_menuitem_property_get(newitem, DBUSMENU_TITLE_MENUITEM_NAME));
-
- GtkWidget* title = NULL;
-
- title = title_widget_new (newitem);
- GtkMenuItem *menu_title_widget = GTK_MENU_ITEM(title);
-
- gtk_widget_show_all(title);
-
- dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client),
- newitem,
- menu_title_widget, parent);
+ newitem,
+ menu_metadata_widget,
+ parent);
return TRUE;
}
diff --git a/src/metadata-menu-item.vala b/src/metadata-menu-item.vala
index 741bb9f..995d248 100644
--- a/src/metadata-menu-item.vala
+++ b/src/metadata-menu-item.vala
@@ -18,6 +18,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Gee;
+using Dbusmenu;
using DbusmenuMetadata;
using Gdk;
@@ -29,16 +30,21 @@ public class MetadataMenuitem : PlayerItem
private static FetchFile fetcher;
private string previous_temp_album_art_path;
- public MetadataMenuitem()
+ public MetadataMenuitem (PlayerController parent)
{
- Object(item_type: MENUITEM_TYPE);
- reset(attributes_format());
+ Object(item_type: MENUITEM_TYPE, owner: parent);
}
construct{
MetadataMenuitem.clean_album_art_temp_dir();
- this.previous_temp_album_art_path = null;
+ this.previous_temp_album_art_path = null;
this.album_art_cache_dir = MetadataMenuitem.create_album_art_temp_dir();
+ debug ("JUST ABOUT TO ATTEMPT PLAYER NAME SETTING %s", this.owner.app_info.get_name());
+ this.property_set (MENUITEM_PLAYER_NAME, this.owner.app_info.get_name());
+ this.property_set (MENUITEM_PLAYER_ICON, this.owner.icon_name);
+ this.property_set_bool (MENUITEM_PLAYER_RUNNING, false);
+ this.property_set_bool (MENUITEM_HIDE_TRACK_DETAILS, true);
+ reset (relevant_attributes_for_ui());
}
private static void clean_album_art_temp_dir()
@@ -98,10 +104,16 @@ public class MetadataMenuitem : PlayerItem
public void fetch_art(string uri, string prop)
{
File art_file = File.new_for_uri(uri);
- if(art_file.is_native() == true){
+ if (art_file.is_native() == true){
+ if (art_file.query_exists() == false){
+ // Can't load the image, set prop to empty and return.
+ this.property_set_int ( prop, EMPTY );
+ return;
+ }
string path;
try{
- path = Filename.from_uri ( uri.strip() );
+ path = Filename.from_uri ( uri.strip() );
+ debug ("Populating the artwork field with %s", uri.strip());
this.property_set ( prop, path );
}
catch(ConvertError e){
@@ -135,7 +147,7 @@ public class MetadataMenuitem : PlayerItem
PixbufLoader loader = new PixbufLoader ();
loader.write (update.data);
loader.close ();
- Pixbuf icon = loader.get_pixbuf ();
+ Pixbuf icon = loader.get_pixbuf ();
string path = this.album_art_cache_dir.concat("/downloaded-coverart-XXXXXX");
int r = FileUtils.mkstemp(path);
if(r != -1){
@@ -144,7 +156,7 @@ public class MetadataMenuitem : PlayerItem
if(this.previous_temp_album_art_path != null){
FileUtils.remove(this.previous_temp_album_art_path);
}
- this.previous_temp_album_art_path = path;
+ this.previous_temp_album_art_path = path;
}
}
catch(GLib.Error e){
@@ -152,7 +164,37 @@ public class MetadataMenuitem : PlayerItem
e.message);
}
}
+
+ public override void handle_event (string name,
+ Variant input_value,
+ uint timestamp)
+ {
+ if(this.owner.current_state == PlayerController.state.OFFLINE)
+ {
+ this.owner.instantiate();
+ }
+ else if(this.owner.current_state == PlayerController.state.CONNECTED){
+ this.owner.mpris_bridge.expose();
+ }
+ }
+ public void alter_label (string new_title)
+ {
+ if (new_title == null) return;
+ this.property_set (MENUITEM_PLAYER_NAME, new_title);
+ }
+
+ public void toggle_active_triangle (bool update)
+ {
+ debug ("toggle active triangle");
+ this.property_set_bool (MENUITEM_PLAYER_RUNNING, update);
+ }
+
+ public void should_collapse(bool collapse)
+ {
+ this.property_set_bool (MENUITEM_HIDE_TRACK_DETAILS, collapse);
+ }
+
public static HashSet<string> attributes_format()
{
HashSet<string> attrs = new HashSet<string>();
@@ -160,6 +202,19 @@ public class MetadataMenuitem : PlayerItem
attrs.add(MENUITEM_ARTIST);
attrs.add(MENUITEM_ALBUM);
attrs.add(MENUITEM_ARTURL);
+ attrs.add(MENUITEM_PLAYER_NAME);
+ attrs.add(MENUITEM_PLAYER_ICON);
+ attrs.add(MENUITEM_PLAYER_RUNNING);
+ return attrs;
+ }
+
+ public static HashSet<string> relevant_attributes_for_ui()
+ {
+ HashSet<string> attrs = new HashSet<string>();
+ attrs.add(MENUITEM_TITLE);
+ attrs.add(MENUITEM_ARTIST);
+ attrs.add(MENUITEM_ALBUM);
+ attrs.add(MENUITEM_ARTURL);
return attrs;
- }
+ }
}
diff --git a/src/metadata-widget.c b/src/metadata-widget.c
index 38ed529..f687d0c 100644
--- a/src/metadata-widget.c
+++ b/src/metadata-widget.c
@@ -28,20 +28,24 @@ 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;
- DbusmenuMenuitem* twin_item;
+ GtkWidget* player_label;
+ GdkPixbuf* icon_buf;
+ DbusmenuMenuitem* twin_item;
};
#define METADATA_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), METADATA_WIDGET_TYPE, MetadataWidgetPrivate))
@@ -51,12 +55,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,16 +78,23 @@ 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_icon_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_MENU_ITEM);
+
static void
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 +102,20 @@ 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;
+ priv->icon_buf = NULL;
+
+ 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 +125,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_after (GTK_WIDGET(self), "expose-event",
+ G_CALLBACK(metadata_widget_icon_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,20 +172,36 @@ 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)1, (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
metadata_widget_dispose (GObject *object)
{
+ MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(METADATA_WIDGET(object));
+
+ if (priv->icon_buf != NULL){
+ gdk_pixbuf_unref(priv->icon_buf);
+ }
G_OBJECT_CLASS (metadata_widget_parent_class)->dispose (object);
}
@@ -183,37 +221,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 +355,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;
@@ -341,7 +388,6 @@ draw_album_art_placeholder(GtkWidget *metadata)
_color_shade ( &fg_normal, 0.78, &light_bottom_color );
-
cairo_set_source_rgba (cr,
light_bottom_color.r,
light_bottom_color.g,
@@ -349,14 +395,13 @@ draw_album_art_placeholder(GtkWidget *metadata)
1.0);
pango_cairo_update_layout(cr, layout);
- cairo_move_to (cr, alloc.x + alloc.width/6, alloc.y + alloc.height/8);
+ cairo_move_to (cr, alloc.x + alloc.width/6, alloc.y + 3);
pango_cairo_show_layout(cr, layout);
g_object_unref(layout);
g_object_unref(pcontext);
g_string_free (string, TRUE);
cairo_destroy (cr);
-
}
static void
@@ -366,33 +411,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 +463,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 +486,48 @@ 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);
+ }
+ gtk_widget_queue_draw(GTK_WIDGET(self));
}
static void
@@ -454,9 +550,54 @@ 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);
+
+ if (priv->icon_buf != NULL){
+ gdk_pixbuf_unref(priv->icon_buf);
+ priv->icon_buf = NULL;
+ }
+
+ 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));
+ GdkPixbuf* icon_buf;
+
+ // Banshee Special case!
+ // 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" );
+ }
+ else{
+ // Otherwise use what is stored in the props
+ g_string_erase (app_panel, 0, -1);
+ g_string_overwrite (app_panel,
+ 0,
+ dbusmenu_menuitem_property_get ( priv->twin_item,
+ DBUSMENU_METADATA_MENUITEM_PLAYER_ICON ));
+ }
+ icon_buf = gtk_icon_theme_load_icon ( gtk_icon_theme_get_default(),
+ app_panel->str,
+ (width > height) ? width : height,
+ GTK_ICON_LOOKUP_GENERIC_FALLBACK,
+ NULL );
+ priv->icon_buf = icon_buf;
+ g_string_free ( app_panel, TRUE);
+ g_string_free ( banshee_string, TRUE);
+}
+
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 +620,77 @@ 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_icon_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;
+
+ gint offset = 3;
+ arrow_width = 5;
+ arrow_height = 9;
+
+ style = gtk_widget_get_style (widget);
+
+ cr = (cairo_t*) gdk_cairo_create (widget->window);
+
+ x = widget->allocation.x;
+ y = widget->allocation.y;
+
+ // Draw player icon
+ if (priv->icon_buf != NULL){
+ gdk_cairo_set_source_pixbuf (cr,
+ priv->icon_buf,
+ x + arrow_width + 1,
+ y + offset);
+ cairo_paint (cr);
+ }
+
+ // Draw triangle but only if the player is running.
+ if (dbusmenu_menuitem_property_get_bool (priv->twin_item,
+ DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING)){
+ y += (double)arrow_height/2.0 + offset;
+ 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;
}
/**
@@ -498,7 +700,6 @@ metadata_widget_set_twin_item(MetadataWidget* self,
GtkWidget*
metadata_widget_new(DbusmenuMenuitem *item)
{
-
GtkWidget* widget = g_object_new(METADATA_WIDGET_TYPE, NULL);
metadata_widget_set_twin_item ( METADATA_WIDGET(widget),
item );
diff --git a/src/metadata-widget.h b/src/metadata-widget.h
index 6021af5..30b629c 100644
--- a/src/metadata-widget.h
+++ b/src/metadata-widget.h
@@ -35,11 +35,11 @@ typedef struct _MetadataWidget MetadataWidget;
typedef struct _MetadataWidgetClass MetadataWidgetClass;
struct _MetadataWidgetClass {
- GtkMenuItemClass parent_class;
+ GtkMenuItemClass parent_class;
};
struct _MetadataWidget {
- GtkMenuItem parent;
+ GtkMenuItem parent;
};
GType metadata_widget_get_type (void);
diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala
index 04ceb88..2975066 100644
--- a/src/mpris2-controller.vala
+++ b/src/mpris2-controller.vala
@@ -83,13 +83,16 @@ public class Mpris2Controller : GLib.Object
}
Variant? meta_v = changed_properties.lookup("Metadata");
if(meta_v != null){
- GLib.HashTable<string, Variant?> changed_updates = clean_metadata();
+ GLib.HashTable<string, Variant?> changed_updates = clean_metadata();
PlayerItem metadata = this.owner.custom_items[PlayerController.widget_order.METADATA];
- metadata.reset ( MetadataMenuitem.attributes_format());
+ metadata.reset (MetadataMenuitem.relevant_attributes_for_ui());
metadata.update ( changed_updates,
- MetadataMenuitem.attributes_format());
- metadata.property_set_bool ( MENUITEM_PROP_VISIBLE,
- metadata.populated(MetadataMenuitem.attributes_format()));
+ MetadataMenuitem.relevant_attributes_for_ui());
+ MetadataMenuitem md = this.owner.custom_items[PlayerController.widget_order.METADATA] as MetadataMenuitem;
+ bool collapsing = !metadata.populated(MetadataMenuitem.relevant_attributes_for_ui());
+ md.should_collapse(collapsing);
+
+ debug ("Should metadata collapse %s", collapsing.to_string());
}
Variant? playlist_v = changed_properties.lookup("ActivePlaylist");
if ( playlist_v != null && this.owner.use_playlists == true ){
@@ -109,8 +112,8 @@ public class Mpris2Controller : GLib.Object
}
Variant? identity_v = changed_properties.lookup("Identity");
if (identity_v != null){
- TitleMenuitem title = this.owner.custom_items[PlayerController.widget_order.TITLE] as TitleMenuitem;
- title.alter_label (this.mpris2_root.Identity);
+ MetadataMenuitem md = this.owner.custom_items[PlayerController.widget_order.METADATA] as MetadataMenuitem;
+ md.alter_label (this.mpris2_root.Identity);
}
}
@@ -162,8 +165,8 @@ public class Mpris2Controller : GLib.Object
update = determine_play_state (this.player.PlaybackStatus);
}
if (this.mpris2_root.Identity != null){
- TitleMenuitem title = this.owner.custom_items[PlayerController.widget_order.TITLE] as TitleMenuitem;
- title.alter_label (this.mpris2_root.Identity);
+ MetadataMenuitem md = this.owner.custom_items[PlayerController.widget_order.METADATA] as MetadataMenuitem;
+ md.alter_label (this.mpris2_root.Identity);
}
(this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state (update);
GLib.HashTable<string, Value?>? cleaned_metadata = this.clean_metadata();
diff --git a/src/player-controller.vala b/src/player-controller.vala
index 8a7bda5..52adb23 100644
--- a/src/player-controller.vala
+++ b/src/player-controller.vala
@@ -23,11 +23,10 @@ using Gee;
public class PlayerController : GLib.Object
{
- public const int WIDGET_QUANTITY = 6;
+ public const int WIDGET_QUANTITY = 5;
public static enum widget_order{
SEPARATOR,
- TITLE,
METADATA,
TRANSPORT,
TRACK_SPECIFIC,
@@ -72,6 +71,7 @@ public class PlayerController : GLib.Object
this.construct_widgets();
this.establish_mpris_connection();
this.update_layout();
+ debug ("New player controller for %s with icon name %s", this.app_info.get_name(), this.icon_name);
}
public void update_state(state new_state)
@@ -144,26 +144,27 @@ public class PlayerController : GLib.Object
update_state(PlayerController.state.OFFLINE);
TransportMenuitem transport = this.custom_items[widget_order.TRANSPORT] as TransportMenuitem;
transport.change_play_state (Transport.State.PAUSED);
- this.custom_items[widget_order.METADATA].reset(MetadataMenuitem.attributes_format());
- TitleMenuitem title = this.custom_items[widget_order.TITLE] as TitleMenuitem;
- title.toggle_active_triangle(false);
+ this.custom_items[widget_order.METADATA].reset(MetadataMenuitem.relevant_attributes_for_ui());
+ MetadataMenuitem md = this.custom_items[widget_order.METADATA] as MetadataMenuitem;
+ md.toggle_active_triangle (false);
this.mpris_bridge = null;
}
public void update_layout()
- {
+ {
+ debug ("a call to update layout");
PlaylistsMenuitem playlists_menuitem = this.custom_items[widget_order.PLAYLISTS] as PlaylistsMenuitem;
+ MetadataMenuitem metadata_menuitem = this.custom_items[widget_order.METADATA] as MetadataMenuitem;
if(this.current_state != state.CONNECTED){
- this.custom_items[widget_order.METADATA].property_set_bool (MENUITEM_PROP_VISIBLE,
- false);
+ // TODO
+ metadata_menuitem.should_collapse (true);
playlists_menuitem.root_item.property_set_bool (MENUITEM_PROP_VISIBLE,
false );
this.custom_items[widget_order.TRANSPORT].property_set_bool (MENUITEM_PROP_VISIBLE,
this.app_info.get_id() == "banshee.desktop");
return;
}
- this.custom_items[widget_order.METADATA].property_set_bool (MENUITEM_PROP_VISIBLE,
- this.custom_items[widget_order.METADATA].populated(MetadataMenuitem.attributes_format()));
+ metadata_menuitem.should_collapse (!this.custom_items[widget_order.METADATA].populated (MetadataMenuitem.relevant_attributes_for_ui()) );
if (this.app_info.get_id() == "banshee.desktop"){
TransportMenuitem transport = this.custom_items[widget_order.TRANSPORT] as TransportMenuitem;
transport.handle_cached_action();
@@ -181,12 +182,8 @@ public class PlayerController : GLib.Object
// Separator item
this.custom_items.add(new PlayerItem(CLIENT_TYPES_SEPARATOR));
- // Title item
- TitleMenuitem title_menu_item = new TitleMenuitem(this);
- this.custom_items.add(title_menu_item);
-
// Metadata item
- MetadataMenuitem metadata_item = new MetadataMenuitem();
+ MetadataMenuitem metadata_item = new MetadataMenuitem(this);
this.custom_items.add(metadata_item);
// Transport item
@@ -202,11 +199,11 @@ public class PlayerController : GLib.Object
this.custom_items.add(playlist_menuitem);
foreach(PlayerItem item in this.custom_items){
- if (this.custom_items.index_of(item) == 5) {
+ if (this.custom_items.index_of(item) == 4) {
PlaylistsMenuitem playlists_menuitem = item as PlaylistsMenuitem;
root_menu.child_add_position(playlists_menuitem.root_item, this.menu_offset + this.custom_items.index_of(item));
}
- else if (this.custom_items.index_of(item) == 4) {
+ else if (this.custom_items.index_of(item) == 3) {
TrackSpecificMenuitem trackspecific_menuitem = item as TrackSpecificMenuitem;
root_menu.child_add_position(trackspecific_menuitem.root_item, this.menu_offset + this.custom_items.index_of(item));
}
@@ -220,8 +217,8 @@ public class PlayerController : GLib.Object
{
if(this.mpris_bridge.connected() == true){
this.update_state(state.CONNECTED);
- TitleMenuitem title = this.custom_items[widget_order.TITLE] as TitleMenuitem;
- title.toggle_active_triangle(true);
+ MetadataMenuitem md = this.custom_items[widget_order.METADATA] as MetadataMenuitem;
+ md.toggle_active_triangle(true);
this.mpris_bridge.initial_update();
}
else{
diff --git a/src/player-item.vala b/src/player-item.vala
index f71b166..162dbea 100644
--- a/src/player-item.vala
+++ b/src/player-item.vala
@@ -24,7 +24,7 @@ public class PlayerItem : Dbusmenu.Menuitem
{
public PlayerController owner {get; construct;}
public string item_type { get; construct; }
- private const int EMPTY = -1;
+ public const int EMPTY = -1;
public PlayerItem(string type)
{
@@ -37,7 +37,6 @@ public class PlayerItem : Dbusmenu.Menuitem
public void reset(HashSet<string> attrs){
foreach(string s in attrs){
- //debug("attempting to set prop %s to EMPTY", s);
this.property_set_int(s, EMPTY);
}
}
@@ -87,15 +86,12 @@ public class PlayerItem : Dbusmenu.Menuitem
this.property_set_bool(property, v.get_boolean());
}
}
- this.property_set_bool(MENUITEM_PROP_VISIBLE, populated(attributes));
}
public bool populated(HashSet<string> attrs)
{
foreach(string prop in attrs){
- //debug("populated ? - prop: %s", prop);
if(property_get_int(prop) != EMPTY){
- //debug("populated - prop %s and value %i", prop, property_get_int(prop));
return true;
}
}
diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c
index afb4f04..5d7c4cd 100644
--- a/src/sound-service-dbus.c
+++ b/src/sound-service-dbus.c
@@ -124,14 +124,16 @@ sound_service_dbus_class_init (SoundServiceDbusClass *klass)
0,
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1, G_TYPE_STRING);
+ G_TYPE_NONE, 2, G_TYPE_STRING,
+ G_TYPE_STRING);
signals[PLAYER_SPECIFIC_ITEM] = g_signal_new("player-specific-item-requested",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1, G_TYPE_STRING);
+ G_TYPE_NONE, 2, G_TYPE_STRING,
+ G_TYPE_STRING);
}
static void
diff --git a/src/sound-service.c b/src/sound-service.c
index 918bde6..dd957a0 100644
--- a/src/sound-service.c
+++ b/src/sound-service.c
@@ -47,8 +47,9 @@ service_shutdown (IndicatorService *service, gpointer user_data)
void
on_player_specific_item_requested (SoundServiceDbus* sound_service,
- const gchar* player_object_path,
- gpointer userdata)
+ const gchar* desktop_id,
+ const gchar* player_object_path,
+ gpointer userdata)
{
music_player_bridge_enable_player_specific_items_for_client (player_bridge, desktop_id);
g_debug ("ON PLAYER SPECIFIC ITEM REQUESTED %s", desktop_id);
@@ -57,6 +58,7 @@ on_player_specific_item_requested (SoundServiceDbus* sound_service,
void
on_track_specific_item_requested (SoundServiceDbus* sound_service,
const gchar* desktop_id,
+ const gchar* player_object_path,
gpointer userdata)
{
music_player_bridge_enable_track_specific_items_for_client (player_bridge, desktop_id);
diff --git a/src/title-menu-item.vala b/src/title-menu-item.vala
deleted file mode 100644
index ac93b89..0000000
--- a/src/title-menu-item.vala
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-Copyright 2010 Canonical Ltd.
-
-Authors:
- Conor Curran <conor.curran@canonical.com>
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
-by the Free Software Foundation.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-using Dbusmenu;
-using DbusmenuTitle;
-using Gee;
-
-public class TitleMenuitem : PlayerItem
-{
- public TitleMenuitem(PlayerController parent)
- {
- Object(item_type: MENUITEM_TYPE, owner: parent);
- }
-
- construct
- {
- this.property_set(MENUITEM_NAME, this.owner.app_info.get_name());
- this.property_set(MENUITEM_ICON, this.owner.icon_name);
- this.property_set_bool(MENUITEM_RUNNING, false);
- }
-
- public override void handle_event(string name, Variant input_value, uint timestamp)
- {
- if(this.owner.current_state == PlayerController.state.OFFLINE)
- {
- this.owner.instantiate();
- }
- else if(this.owner.current_state == PlayerController.state.CONNECTED){
- this.owner.mpris_bridge.expose();
- }
- }
-
- public void alter_label (string new_title)
- {
- if (new_title == null) return;
- this.property_set(MENUITEM_NAME, new_title);
- }
-
- public void toggle_active_triangle(bool update)
- {
- this.property_set_bool(MENUITEM_RUNNING, update);
- }
-
- public static HashSet<string> attributes_format()
- {
- HashSet<string> attrs = new HashSet<string>();
- attrs.add(MENUITEM_NAME);
- attrs.add(MENUITEM_RUNNING);
- attrs.add(MENUITEM_ICON);
- return attrs;
- }
-} \ No newline at end of file
diff --git a/src/title-widget.c b/src/title-widget.c
deleted file mode 100644
index b8058b8..0000000
--- a/src/title-widget.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
-Copyright 2010 Canonical Ltd.
-
-Authors:
- Conor Curran <conor.curran@canonical.com>
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
-by the Free Software Foundation.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <glib/gi18n.h>
-#include "title-widget.h"
-#include "common-defs.h"
-#include <gtk/gtk.h>
-#include <libindicator/indicator-image-helper.h>
-
-
-typedef struct _TitleWidgetPrivate TitleWidgetPrivate;
-
-struct _TitleWidgetPrivate
-{
- DbusmenuMenuitem* twin_item;
-};
-
-#define TITLE_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TITLE_WIDGET_TYPE, TitleWidgetPrivate))
-
-/* Prototypes */
-static void title_widget_class_init (TitleWidgetClass *klass);
-static void title_widget_init (TitleWidget *self);
-static void title_widget_dispose (GObject *object);
-static void title_widget_finalize (GObject *object);
-
-// keyevent consumers
-static gboolean title_widget_button_release_event (GtkWidget *menuitem,
- GdkEventButton *event);
-
-// Dbusmenuitem properties update callback
-static void title_widget_property_update(DbusmenuMenuitem* item, gchar* property,
- GVariant* value, gpointer userdata);
-static void title_widget_set_twin_item( TitleWidget* self,
- DbusmenuMenuitem* twin_item);
-static gboolean title_widget_triangle_draw_cb (GtkWidget *widget,
- GdkEventExpose *event,
- gpointer data);
-
-G_DEFINE_TYPE (TitleWidget, title_widget, GTK_TYPE_IMAGE_MENU_ITEM);
-
-static void
-title_widget_class_init (TitleWidgetClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- widget_class->button_release_event = title_widget_button_release_event;
-
- g_type_class_add_private (klass, sizeof (TitleWidgetPrivate));
-
- gobject_class->dispose = title_widget_dispose;
- gobject_class->finalize = title_widget_finalize;
-}
-
-static void
-title_widget_init (TitleWidget *self)
-{
- //g_debug("TitleWidget::title_widget_init");
-}
-
-static void
-title_widget_set_icon(TitleWidget *self)
-{
- TitleWidgetPrivate *priv = TITLE_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_TITLE_MENUITEM_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_TITLE_MENUITEM_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
-title_widget_dispose (GObject *object)
-{
- G_OBJECT_CLASS (title_widget_parent_class)->dispose (object);
-}
-
-static void
-title_widget_finalize (GObject *object)
-{
- G_OBJECT_CLASS (title_widget_parent_class)->finalize (object);
-}
-
-/* Suppress/consume keyevents */
-static gboolean
-title_widget_button_release_event (GtkWidget *menuitem,
- GdkEventButton *event)
-{
- //g_debug("TitleWidget::menu_press_event");
- TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(menuitem);
-
- GVariant* new_title_event = g_variant_new_boolean(TRUE);
- dbusmenu_menuitem_handle_event (priv->twin_item,
- "Title menu event",
- new_title_event,
- 0);
- return FALSE;
-}
-
-static void
-title_widget_property_update (DbusmenuMenuitem* item, gchar* property,
- GVariant* value, gpointer userdata)
-{
- g_return_if_fail (IS_TITLE_WIDGET (userdata));
- TitleWidget* mitem = TITLE_WIDGET(userdata);
- if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_NAME, property) == 0){
- gtk_menu_item_set_label (GTK_MENU_ITEM(mitem),
- g_variant_get_string(value, NULL));
- }
- else if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_ICON, property) == 0){
- title_widget_set_icon (mitem);
- }
-}
-
-static void
-title_widget_set_twin_item(TitleWidget* self,
- DbusmenuMenuitem* twin_item)
-{
- TitleWidgetPrivate *priv = TITLE_WIDGET_GET_PRIVATE(self);
-
- priv->twin_item = twin_item;
-
- g_signal_connect (G_OBJECT (twin_item),
- "property-changed",
- G_CALLBACK (title_widget_property_update),
- self);
- g_signal_connect_after (G_OBJECT (self),
- "expose_event",
- G_CALLBACK (title_widget_triangle_draw_cb),
- twin_item);
-
- gtk_menu_item_set_label (GTK_MENU_ITEM(self),
- dbusmenu_menuitem_property_get(priv->twin_item,
- DBUSMENU_TITLE_MENUITEM_NAME));
- title_widget_set_icon(self);
-}
-
-static gboolean
-title_widget_triangle_draw_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data)
-{
- GtkStyle *style;
- cairo_t *cr;
- int x, y, arrow_width, arrow_height;
-
- if (!GTK_IS_WIDGET (widget)) return FALSE;
- if (!DBUSMENU_IS_MENUITEM (data)) return FALSE;
-
- /* render the triangle indicator only if the application is running */
- if (! dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM(data),
- DBUSMENU_TITLE_MENUITEM_RUNNING)){
- return FALSE;
- }
-
- /* get style */
- style = gtk_widget_get_style (widget);
-
- /* set arrow position / dimensions */
- arrow_width = 5; /* the pixel-based reference triangle is 5x9 */
- arrow_height = 9;
- x = widget->allocation.x;
- y = widget->allocation.y + widget->allocation.height/2.0 - (double)arrow_height/2.0;
-
- /* initialize cairo drawing area */
- cr = (cairo_t*) gdk_cairo_create (widget->window);
-
- /* set line width */
- cairo_set_line_width (cr, 1.0);
-
- /* cairo drawing code */
- 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);
-
- /* remember to destroy cairo context to avoid leaks */
- cairo_destroy (cr);
-
- return FALSE;
-}
-
- /**
- * transport_new:
- * @returns: a new #TitleWidget.
- **/
-GtkWidget*
-title_widget_new(DbusmenuMenuitem *item)
-{
- GtkWidget* widget = g_object_new (TITLE_WIDGET_TYPE,
- NULL);
- gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (widget), TRUE);
- title_widget_set_twin_item((TitleWidget*)widget, item);
-
- return widget;
-}
-
diff --git a/src/title-widget.h b/src/title-widget.h
deleted file mode 100644
index 2be904a..0000000
--- a/src/title-widget.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-Copyright 2010 Canonical Ltd.
-
-Authors:
- Conor Curran <conor.curran@canonical.com>
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
-by the Free Software Foundation.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef __TITLE_WIDGET_H__
-#define __TITLE_WIDGET_H__
-
-#include <gtk/gtkimagemenuitem.h>
-#include <libdbusmenu-glib/menuitem.h>
-
-
-G_BEGIN_DECLS
-
-#define TITLE_WIDGET_TYPE (title_widget_get_type ())
-#define TITLE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TITLE_WIDGET_TYPE, TitleWidget))
-#define TITLE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TITLE_WIDGET_TYPE, TitleWidgetClass))
-#define IS_TITLE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TITLE_WIDGET_TYPE))
-#define IS_TITLE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TITLE_WIDGET_TYPE))
-#define TITLE_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TITLE_WIDGET_TYPE, TitleWidgetClass))
-
-typedef struct _TitleWidget TitleWidget;
-typedef struct _TitleWidgetClass TitleWidgetClass;
-
-struct _TitleWidgetClass {
- GtkImageMenuItemClass parent_class;
-};
-
-struct _TitleWidget {
- GtkImageMenuItem parent;
-};
-
-GType title_widget_get_type (void);
-GtkWidget* title_widget_new(DbusmenuMenuitem *twin_item);
-
-G_END_DECLS
-
-#endif
-
diff --git a/vapi/common-defs.vapi b/vapi/common-defs.vapi
index cd21389..33b4aad 100644
--- a/vapi/common-defs.vapi
+++ b/vapi/common-defs.vapi
@@ -24,6 +24,10 @@ namespace DbusmenuMetadata{
public const string MENUITEM_TITLE;
public const string MENUITEM_ALBUM;
public const string MENUITEM_ARTURL;
+ public const string MENUITEM_PLAYER_NAME;
+ public const string MENUITEM_PLAYER_ICON;
+ public const string MENUITEM_PLAYER_RUNNING;
+ public const string MENUITEM_HIDE_TRACK_DETAILS;
}
[CCode (cheader_filename = "common-defs.h")]
@@ -38,14 +42,6 @@ namespace DbusmenuTrackSpecific{
}
[CCode (cheader_filename = "common-defs.h")]
-namespace DbusmenuTitle{
- public const string MENUITEM_TYPE;
- public const string MENUITEM_NAME;
- public const string MENUITEM_ICON;
- public const string MENUITEM_RUNNING;
-}
-
-[CCode (cheader_filename = "common-defs.h")]
namespace DbusmenuPlaylists{
public const string MENUITEM_TYPE;
public const string MENUITEM_TITLE;
@@ -56,7 +52,6 @@ namespace DbusmenuPlaylist{
public const string MENUITEM_PATH;
}
-
[CCode (cprefix ="Transport", cheader_filename = "common-defs.h")]
namespace Transport{
public enum Action{