From 05e82f2c6a8a72aeb3a589b702e5a9f1d68251d9 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 17 Jun 2010 16:41:54 +0100 Subject: transport plugged in --- src/metadata-menu-item.vala | 20 +++++++++++++++----- src/metadata-widget.c | 8 ++++++-- src/mpris-controller.vala | 42 +++++++++++++++++++++++++++++++++++++++++- src/player-controller.vala | 18 +++++++++++++----- src/sound-service.c | 4 ++-- src/transport-menu-item.vala | 19 +++++++++++++++++-- src/transport-widget.c | 32 +++++++++++++++++++++++--------- 7 files changed, 117 insertions(+), 26 deletions(-) diff --git a/src/metadata-menu-item.vala b/src/metadata-menu-item.vala index 894ad3c..be078bd 100644 --- a/src/metadata-menu-item.vala +++ b/src/metadata-menu-item.vala @@ -17,12 +17,22 @@ public class MetadataMenuitem : Dbusmenu.Menuitem public void update(HashMap data) { - this.property_set(DBUSMENU_METADATA_MENUITEM_TEXT_ARTIST, data.get("artist")); - this.property_set(DBUSMENU_METADATA_MENUITEM_TEXT_PIECE, data.get("title")); - this.property_set(DBUSMENU_METADATA_MENUITEM_TEXT_CONTAINER, data.get("album")); - this.property_set(DBUSMENU_METADATA_MENUITEM_IMAGE_PATH, data.get("arturl")); + this.property_set(DBUSMENU_METADATA_MENUITEM_TEXT_ARTIST, data.get("artist").strip()); + this.property_set(DBUSMENU_METADATA_MENUITEM_TEXT_PIECE, data.get("title").strip()); + this.property_set(DBUSMENU_METADATA_MENUITEM_TEXT_CONTAINER, data.get("album").strip()); + this.property_set(DBUSMENU_METADATA_MENUITEM_IMAGE_PATH, sanitize_image_path(data.get("arturl"))); } - + + public static string sanitize_image_path(string path) + { + string result = path.strip(); + if(result.contains("file:///")){ + result = result.slice(7, result.len()); + } + debug("Sanitize image path - result = %s", result); + return result; + } + public override void handle_event(string name, GLib.Value input_value, uint timestamp) { debug("MetadataItem -> handle event caught!"); diff --git a/src/metadata-widget.c b/src/metadata-widget.c index e0dca6e..357c31a 100644 --- a/src/metadata-widget.c +++ b/src/metadata-widget.c @@ -176,7 +176,9 @@ metadata_widget_property_update(DbusmenuMenuitem* item, gchar* property, } else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_IMAGE_PATH, property) == 0){ priv->image_path = g_strdup(g_value_get_string(value)); - update_album_art(mitem); + if(priv->image_path != NULL){ + update_album_art(mitem); + } } } @@ -184,11 +186,13 @@ 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); + pixbuf = gdk_pixbuf_scale_simple(pixbuf,60, 60,GDK_INTERP_BILINEAR); + g_debug("attempting to set the image with path %s", priv->image_path); gtk_image_set_from_pixbuf(GTK_IMAGE(priv->album_art), pixbuf); g_object_unref(pixbuf); } + /** * transport_new: * @returns: a new #MetadataWidget. diff --git a/src/mpris-controller.vala b/src/mpris-controller.vala index f606b32..7e65594 100644 --- a/src/mpris-controller.vala +++ b/src/mpris-controller.vala @@ -17,13 +17,22 @@ 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 . */ + using Gee; + public class MprisController : GLib.Object { private DBus.Connection connection; - private dynamic DBus.Object mpris_player; + public dynamic DBus.Object mpris_player; private PlayerController controller; + struct status { + public int32 playback; + public int32 shuffle; + public int32 repeat; + public int32 endless; + } + public MprisController(string name, PlayerController controller, string mpris_interface="org.freedesktop.MediaPlayer"){ try { @@ -34,6 +43,7 @@ public class MprisController : GLib.Object this.controller = controller; this.mpris_player = this.connection.get_object ("org.mpris.".concat(name.down()) , "/Player", mpris_interface); this.mpris_player.TrackChange += onTrackChange; + this.mpris_player.StatusChange += onStatusChange; this.controller.update_playing_info(get_track_data()); } @@ -47,6 +57,36 @@ public class MprisController : GLib.Object this.controller.update_playing_info(format_metadata(ht)); } + /** + * TRUE => Playing + * FALSE => Paused + **/ + public void toggle_playback(bool state) + { + if(state == true){ + debug("about to play"); + this.mpris_player.Play(); + } + else{ + debug("about to pause"); + this.mpris_player.Pause(); + } + } + + private void onStatusChange(dynamic DBus.Object mpris_client, status st) + { + debug("onStatusChange - signal received"); + //ValueArray a = new ValueArray(4); + //Value v = new Value(typeof(int32)); + //v.set_int(st.playback); + //a.append(v); + //debug("onStatusChange - play %i", a.get_nth(0).get_int()); + //int playback = (ValueArray)st.get_nth(0).get_int(); + //int shuffle = ar.get_nth(1).get_int(); + //int repeat = ar.get_nth(2).get_int(); + //int endless = ar.get_nth(3).get_int(); + } + private static HashMap format_metadata(HashTable data) { HashMap results = new HashMap(); diff --git a/src/player-controller.vala b/src/player-controller.vala index 4c09c12..aa72cac 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -18,20 +18,20 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ - using Dbusmenu; using Gee; public class PlayerController : GLib.Object { - private const int METADATA = 2; + private const int METADATA = 2; + private const int TRANSPORT = 3; + private Dbusmenu.Menuitem root_menu; private string name; private bool is_active; private ArrayList custom_items; private MprisController mpris_adaptor; - // TODO: pass in the appropriate position for the menu (to handle multiple players) public PlayerController(Dbusmenu.Menuitem root, string client_name, bool active) { this.root_menu = root; @@ -39,12 +39,20 @@ public class PlayerController : GLib.Object this.is_active = active; this.custom_items = new ArrayList(); self_construct(); + // Temporary scenario to handle both v1 and v2 of MPRIS. if(this.name == "Vlc"){ this.mpris_adaptor = new MprisControllerV2(this.name, this); - }else{ + } + else{ this.mpris_adaptor = new MprisController(this.name, this); - } + } + + // TODO subclass dbusmenuMenuitem to something like a playermenuitem + // and use this type to collectively + // control widgets. + TransportMenuitem t = (TransportMenuitem)this.custom_items[TRANSPORT]; + t.set_adaptor(this.mpris_adaptor); } public void vanish() diff --git a/src/sound-service.c b/src/sound-service.c index 3ec7a60..38e5fba 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -45,8 +45,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/transport-menu-item.vala b/src/transport-menu-item.vala index 2259e43..2e1ed0b 100644 --- a/src/transport-menu-item.vala +++ b/src/transport-menu-item.vala @@ -26,14 +26,29 @@ public class TransportMenuitem : Dbusmenu.Menuitem /* Not ideal duplicate definition of const - see common-defs/h */ const string DBUSMENU_TRANSPORT_MENUITEM_TYPE = "x-canonical-transport-bar"; const string DBUSMENU_TRANSPORT_MENUITEM_STATE = "x-canonical-transport-state"; - + private MprisController mpris_adaptor; + public TransportMenuitem() { this.property_set(MENUITEM_PROP_TYPE, DBUSMENU_TRANSPORT_MENUITEM_TYPE); - this.property_set(DBUSMENU_TRANSPORT_MENUITEM_STATE, "play"); + // Hardcode the set up state until we can get the struct vala bug fixed + this.property_set_bool(DBUSMENU_TRANSPORT_MENUITEM_STATE, false); + debug("transport on the vala side"); } + public void set_adaptor(MprisController adaptor) + { + this.mpris_adaptor = adaptor; + } + + /** + Callback method for the handle_event + * TRUE => Playing + * FALSE => Paused + **/ public override void handle_event(string name, GLib.Value input_value, uint timestamp) { + debug("handle_event with bool value %s", input_value.get_boolean().to_string()); + this.mpris_adaptor.toggle_playback(input_value.get_boolean()); } } \ No newline at end of file diff --git a/src/transport-widget.c b/src/transport-widget.c index 2c32315..ce364e3 100644 --- a/src/transport-widget.c +++ b/src/transport-widget.c @@ -62,12 +62,12 @@ static gboolean transport_widget_button_press_event (GtkWidget *men static gboolean transport_widget_button_release_event (GtkWidget *menuitem, GdkEventButton *event); -static void transport_widget_update_state(DbusmenuMenuitem* item, +static void transport_widget_property_update(DbusmenuMenuitem* item, gchar * property, GValue * value, gpointer userdata); // utility methods -static gchar* transport_widget_determine_play_label(const gchar* state); +static gchar* transport_widget_toggle_play_label(const gchar* state); G_DEFINE_TYPE (TransportWidget, transport_widget, GTK_TYPE_MENU_ITEM); @@ -130,14 +130,18 @@ transport_widget_init (TransportWidget *self) GtkWidget *hbox; hbox = gtk_hbox_new(TRUE, 2); - priv->play_button = gtk_button_new_with_label(">"); - gtk_box_pack_start (GTK_BOX (hbox), priv->play_button, FALSE, TRUE, 0); + gchar* label = ">"; + if(dbusmenu_menuitem_property_get_bool(twin_item, DBUSMENU_TRANSPORT_MENUITEM_STATE) == TRUE){ + label = "||"; + } + priv->play_button = gtk_button_new_with_label(g_strdup(label)); + gtk_box_pack_start (GTK_BOX (hbox), priv->play_button, FALSE, TRUE, 0); priv->hbox = hbox; - g_signal_connect(G_OBJECT(twin_item), "property-changed", G_CALLBACK(transport_widget_update_state), self); + g_signal_connect(G_OBJECT(twin_item), "property-changed", G_CALLBACK(transport_widget_property_update), self); gtk_container_add (GTK_CONTAINER (self), priv->hbox); @@ -163,7 +167,16 @@ transport_widget_button_press_event (GtkWidget *menuitem, { g_debug("TransportWidget::menu_press_event"); TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE(TRANSPORT_WIDGET(menuitem)); - gtk_button_set_label(GTK_BUTTON(priv->play_button), g_strdup(transport_widget_determine_play_label(gtk_button_get_label(GTK_BUTTON(priv->play_button))))); + + gboolean state = g_ascii_strcasecmp(gtk_button_get_label(GTK_BUTTON(priv->play_button)), ">") == 0; + + gtk_button_set_label(GTK_BUTTON(priv->play_button), g_strdup(transport_widget_toggle_play_label(gtk_button_get_label(GTK_BUTTON(priv->play_button))))); + GValue value = {0}; + g_value_init(&value, G_TYPE_BOOLEAN); + g_debug("TransportWidget::menu_press_event - going to send value %i", state); + + g_value_set_boolean(&value, state); + dbusmenu_menuitem_handle_event (twin_item, "Transport state change", &value, 0); return TRUE; } @@ -180,7 +193,8 @@ transport_widget_button_release_event (GtkWidget *menuitem, * transport_widget_update_state() * Callback for updates from the other side of dbus **/ -static void transport_widget_update_state(DbusmenuMenuitem* item, gchar* property, +static void +transport_widget_property_update(DbusmenuMenuitem* item, gchar* property, GValue* value, gpointer userdata) { g_debug("transport_widget_update_state - with property %s", property); @@ -190,11 +204,11 @@ static void transport_widget_update_state(DbusmenuMenuitem* item, gchar* propert TransportWidget* bar = (TransportWidget*)userdata; TransportWidgetPrivate *priv = TRANSPORT_WIDGET_GET_PRIVATE(bar); - gtk_button_set_label(GTK_BUTTON(priv->play_button), g_strdup(transport_widget_determine_play_label(property))); + gtk_button_set_label(GTK_BUTTON(priv->play_button), g_strdup(transport_widget_toggle_play_label(property))); } // will be needed for image swapping -static gchar* transport_widget_determine_play_label(const gchar* state) +static gchar* transport_widget_toggle_play_label(const gchar* state) { gchar* label = ">"; if(g_strcmp0(state, ">") == 0){ -- cgit v1.2.3