diff options
author | Conor Curran <conor.curran@canonical.com> | 2010-07-15 13:27:06 +0100 |
---|---|---|
committer | Conor Curran <conor.curran@canonical.com> | 2010-07-15 13:27:06 +0100 |
commit | 0358622a18d0dbf2d1b413a708e248db974f97a8 (patch) | |
tree | 480a4f12b9434a404bbcf8afc8a72b32ae6f856e /src | |
parent | d8253fc0cfe667316e2e5f033bcbfba4c3044297 (diff) | |
parent | 6bab9d75b22aa21ed27e4961e6dbf4bbcdd2e94c (diff) | |
download | ayatana-indicator-sound-0358622a18d0dbf2d1b413a708e248db974f97a8.tar.gz ayatana-indicator-sound-0358622a18d0dbf2d1b413a708e248db974f97a8.tar.bz2 ayatana-indicator-sound-0358622a18d0dbf2d1b413a708e248db974f97a8.zip |
merged scrub bar work
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/common-defs.h | 17 | ||||
-rw-r--r-- | src/familiar-players-db.vala | 18 | ||||
-rw-r--r-- | src/indicator-sound.c | 29 | ||||
-rw-r--r-- | src/metadata-menu-item.vala | 10 | ||||
-rw-r--r-- | src/metadata-widget.c | 12 | ||||
-rw-r--r-- | src/mpris-controller.vala | 49 | ||||
-rw-r--r-- | src/music-player-bridge.vala | 5 | ||||
-rw-r--r-- | src/player-controller.vala | 29 | ||||
-rw-r--r-- | src/player-item.vala | 9 | ||||
-rw-r--r-- | src/scrub-menu-item.vala | 50 | ||||
-rw-r--r-- | src/scrub-widget.c | 218 | ||||
-rw-r--r-- | src/scrub-widget.h | 53 | ||||
-rw-r--r-- | src/sound-service-dbus.h | 1 | ||||
-rw-r--r-- | src/sound-service.c | 1 | ||||
-rw-r--r-- | src/title-menu-item.vala | 8 | ||||
-rw-r--r-- | src/title-widget.c | 4 |
17 files changed, 455 insertions, 61 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 79ba7d2..ed3e394 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,6 +18,8 @@ libsoundmenu_la_SOURCES = \ indicator-sound.c \ title-widget.c \ title-widget.h \ + scrub-widget.c \ + scrub-widget.h \ dbus-shared-names.h \ sound-service-client.h @@ -58,6 +60,7 @@ music_bridge_VALASOURCES = \ music-player-bridge.vala \ transport-menu-item.vala \ metadata-menu-item.vala \ + scrub-menu-item.vala \ title-menu-item.vala \ player-controller.vala \ mpris-controller-v2.vala \ diff --git a/src/common-defs.h b/src/common-defs.h index 9c1fbab..76e9558 100644 --- a/src/common-defs.h +++ b/src/common-defs.h @@ -29,11 +29,16 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #define DBUSMENU_TRANSPORT_MENUITEM_TYPE "x-canonical-transport-bar" #define DBUSMENU_TRANSPORT_MENUITEM_PLAY_STATE "x-canonical-transport-play-state" -#define DBUSMENU_METADATA_MENUITEM_TYPE "x-canonical-metadata-menu-item" -#define DBUSMENU_METADATA_MENUITEM_TEXT_ARTIST "x-canonical-metadata-text-artist" -#define DBUSMENU_METADATA_MENUITEM_TEXT_TITLE "x-canonical-metadata-text-title" -#define DBUSMENU_METADATA_MENUITEM_TEXT_ALBUM "x-canonical-metadata-text-album" -#define DBUSMENU_METADATA_MENUITEM_ARTURL "x-canonical-metadata-arturl" +#define DBUSMENU_METADATA_MENUITEM_TYPE "x-canonical-sound-menu-player-metadata-menu-item" +#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_TITLE_MENUITEM_TYPE "x-canonical-sound-menu-player-title-menu-item" -#define DBUSMENU_TITLE_MENUITEM_TEXT_NAME "x-canonical-sound-menu-player-title-name" +#define DBUSMENU_TITLE_MENUITEM_NAME "x-canonical-sound-menu-player-title-name" + +#define DBUSMENU_SCRUB_MENUITEM_TYPE "x-canonical-sound-menu-player-scrub-menu-item" +#define DBUSMENU_SCRUB_MENUITEM_DURATION "x-canonical-sound-menu-player-scrub-time" +#define DBUSMENU_SCRUB_MENUITEM_POSITION "x-canonical-sound-menu-player-scrub-position" + diff --git a/src/familiar-players-db.vala b/src/familiar-players-db.vala index b83caa3..2bc0a3c 100644 --- a/src/familiar-players-db.vala +++ b/src/familiar-players-db.vala @@ -51,18 +51,20 @@ public class FamiliarPlayersDB : GLib.Object } private bool create_key_file(){ + bool result = false; if (test(this.file_name, GLib.FileTest.EXISTS)) { this.key_file = new KeyFile(); try{ - if (this.key_file.load_from_file(this.file_name, KeyFileFlags.NONE) == true) { - return true; - } + result = this.key_file.load_from_file(this.file_name, KeyFileFlags.NONE); } - catch(FileError e){ - warning("FamiliarPlayersDB - error trying to load KeyFile"); + catch(GLib.KeyFileError e){ + warning("FamiliarPlayersDB::create_key_file() - KeyFileError"); } + catch(GLib.FileError e){ + warning("FamiliarPlayersDB::create_key_file() - FileError"); + } } - return false; + return result; } private bool check_for_keys(){ @@ -87,7 +89,7 @@ public class FamiliarPlayersDB : GLib.Object } return true; } - catch(FileError error){ + catch(GLib.KeyFileError error){ warning("Error loading the Desktop string list"); return false; } @@ -108,7 +110,7 @@ public class FamiliarPlayersDB : GLib.Object try{ data = keyfile.to_data(out data_length); } - catch(Error e){ + catch(GLib.KeyFileError e){ warning("Problems dumping keyfile to a string"); return false; } diff --git a/src/indicator-sound.c b/src/indicator-sound.c index a2d9762..e18125a 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -41,6 +41,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include "transport-widget.h" #include "metadata-widget.h" #include "title-widget.h" +#include "scrub-widget.h" #include "dbus-shared-names.h" #include "sound-service-client.h" #include "common-defs.h" @@ -94,10 +95,11 @@ static void slider_grabbed(GtkWidget *widget, gpointer user_data); static void slider_released(GtkWidget *widget, gpointer user_data); static void style_changed_cb(GtkWidget *widget, gpointer user_data); -//player widgets related +//player widget realisation methods static gboolean new_transport_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); static gboolean new_metadata_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); static gboolean new_title_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); +static gboolean new_scrub_bar_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); // DBUS communication static DBusGProxy *sound_dbus_proxy = NULL; @@ -246,7 +248,9 @@ get_menu (IndicatorObject * io) dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_TRANSPORT_MENUITEM_TYPE, new_transport_widget); 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); - // register Key-press listening on the menu widget as the slider does not allow this. + dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SCRUB_MENUITEM_TYPE, new_scrub_bar_widget); + + // register Key-press listening on the menu widget as the slider does not allow this. g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), NULL); return GTK_MENU(menu); } @@ -274,6 +278,7 @@ new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuC io = g_object_get_data (G_OBJECT (client), "indicator"); volume_slider = ido_scale_menu_item_new_with_range ("Volume", initial_volume_percent, 0, 100, 1); + ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (volume_slider), IDO_SCALE_MENU_ITEM_STYLE_IMAGE); g_object_set(volume_slider, "reverse-scroll-events", TRUE, NULL); g_signal_connect (volume_slider, @@ -373,6 +378,26 @@ new_title_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbusmenu return TRUE; } +static gboolean +new_scrub_bar_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) +{ + g_debug("indicator-sound: new_scrub_bar_widget"); + + GtkWidget* scrub_bar = NULL; + + g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); + g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); + + scrub_bar = scrub_widget_new (newitem); + GtkMenuItem *menu_scrub_widget = GTK_MENU_ITEM(scrub_widget_get_ido_bar(SCRUB_WIDGET(scrub_bar))); + + gtk_widget_show_all(scrub_widget_get_ido_bar(SCRUB_WIDGET(scrub_bar))); + + dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_scrub_widget, parent); + + return TRUE; +} + static void connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata) diff --git a/src/metadata-menu-item.vala b/src/metadata-menu-item.vala index cfcb3bc..3af9ff1 100644 --- a/src/metadata-menu-item.vala +++ b/src/metadata-menu-item.vala @@ -31,17 +31,17 @@ public class MetadataMenuitem : PlayerItem public static HashSet<string> attributes_format() { HashSet<string> attrs = new HashSet<string>(); - attrs.add(MENUITEM_TEXT_TITLE); - attrs.add(MENUITEM_TEXT_ARTIST); - attrs.add(MENUITEM_TEXT_ALBUM); + attrs.add(MENUITEM_TITLE); + attrs.add(MENUITEM_ARTIST); + attrs.add(MENUITEM_ALBUM); attrs.add(MENUITEM_ARTURL); return attrs; } public bool populated() { - return (this.property_get(MENUITEM_TEXT_TITLE) != null && - this.property_get(MENUITEM_TEXT_TITLE) != ""); + return (this.property_get(MENUITEM_TITLE) != null && + this.property_get(MENUITEM_TITLE) != ""); } }
\ No newline at end of file diff --git a/src/metadata-widget.c b/src/metadata-widget.c index 8235725..dce9226 100644 --- a/src/metadata-widget.c +++ b/src/metadata-widget.c @@ -109,7 +109,7 @@ metadata_widget_init (MetadataWidget *self) // artist GtkWidget* artist; artist = gtk_label_new(dbusmenu_menuitem_property_get(twin_item, - DBUSMENU_METADATA_MENUITEM_TEXT_ARTIST)); + DBUSMENU_METADATA_MENUITEM_ARTIST)); gtk_misc_set_alignment(GTK_MISC(artist), (gfloat)0, (gfloat)0); gtk_label_set_width_chars(GTK_LABEL(artist), 15); @@ -121,7 +121,7 @@ metadata_widget_init (MetadataWidget *self) // piece GtkWidget* piece; piece = gtk_label_new(dbusmenu_menuitem_property_get(twin_item, - DBUSMENU_METADATA_MENUITEM_TEXT_TITLE)); + 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_label_set_ellipsize(GTK_LABEL(piece), PANGO_ELLIPSIZE_MIDDLE); @@ -132,7 +132,7 @@ metadata_widget_init (MetadataWidget *self) // container GtkWidget* container; container = gtk_label_new(dbusmenu_menuitem_property_get(twin_item, - DBUSMENU_METADATA_MENUITEM_TEXT_ALBUM)); + DBUSMENU_METADATA_MENUITEM_ALBUM)); gtk_misc_set_alignment(GTK_MISC(container), (gfloat)0, (gfloat)0); gtk_label_set_width_chars(GTK_LABEL(container), 15); gtk_label_set_ellipsize(GTK_LABEL(container), PANGO_ELLIPSIZE_MIDDLE); @@ -202,15 +202,15 @@ metadata_widget_property_update(DbusmenuMenuitem* item, gchar* property, MetadataWidget* mitem = METADATA_WIDGET(userdata); MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(mitem); - if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_TEXT_ARTIST, property) == 0){ + 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); } - else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_TEXT_TITLE, property) == 0){ + 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); } - else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_TEXT_ALBUM, property) == 0){ + 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); } diff --git a/src/mpris-controller.vala b/src/mpris-controller.vala index 8dd0cc9..5e4dce2 100644 --- a/src/mpris-controller.vala +++ b/src/mpris-controller.vala @@ -26,8 +26,6 @@ public class MprisController : GLib.Object public dynamic DBus.Object mpris_player{get; construct;} public PlayerController owner {get; construct;} public string mpris_interface {get; construct;} - private string name; - struct status { public int32 playback; @@ -52,29 +50,40 @@ public class MprisController : GLib.Object this.mpris_player.TrackChange += onTrackChange; this.mpris_player.StatusChange += onStatusChange; + initial_update(); + } + private void initial_update() + { status st = this.mpris_player.GetStatus(); int play_state = st.playback; debug("GetStatusChange - play state %i", play_state); - (this.owner.custom_items[this.owner.TRANSPORT] as TransportMenuitem).change_play_state(play_state); - this.owner.custom_items[this.owner.METADATA].update(this.mpris_player.GetMetadata(), + (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()); + // temporary fix + ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem; + scrub.update_position(this.mpris_player.PositionGet()); } - private void onTrackChange(dynamic DBus.Object mpris_client, HashTable<string,Value?> ht) { debug("onTrackChange"); - this.owner.custom_items[this.owner.METADATA].reset(MetadataMenuitem.attributes_format()); - this.owner.custom_items[this.owner.METADATA].update(ht, + this.owner.custom_items[PlayerController.widget_order.METADATA].reset(MetadataMenuitem.attributes_format()); + this.owner.custom_items[PlayerController.widget_order.SCRUB].reset(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"); + this.owner.custom_items[PlayerController.widget_order.SCRUB].update(this.mpris_player.GetMetadata(), + ScrubMenuitem.attributes_format()); + // temporary fix + ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem; + scrub.update_position(this.mpris_player.PositionGet()); } - /** - * TRUE => Playing - * FALSE => Paused - **/ public void transport_event(TransportMenuitem.action command) { debug("transport_event input = %i", (int)command); @@ -101,6 +110,22 @@ public class MprisController : GLib.Object } } + public void set_position(double position) + { + //debug("Set position with pos (0-100) %f", position); + HashTable<string, Value?> data = this.mpris_player.GetMetadata(); + Value? time_value = data.lookup("time"); + if(time_value == null){ + warning("Can't fetch the duration of the track therefore cant set the position"); + return; + } + uint32 total_time = time_value.get_uint(); + //debug("total time of track = %i", (int)total_time); + 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 * 1000)); + } + public bool connected() { return (this.mpris_player != null); @@ -117,7 +142,7 @@ public class MprisController : GLib.Object Value v = Value(typeof(int)); v.set_int(play_state); ht.insert("state", v); - this.owner.custom_items[this.owner.TRANSPORT].update(ht, TransportMenuitem.attributes_format()); + this.owner.custom_items[PlayerController.widget_order.TRANSPORT].update(ht, TransportMenuitem.attributes_format()); } diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 2f87b2d..3ee7b55 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -77,7 +77,7 @@ public class MusicPlayerBridge : GLib.Object return 2; } else{ - return (2 + (this.registered_clients.size * 4)); + return (2 + (this.registered_clients.size * PlayerController.WIDGET_QUANTITY)); } } @@ -93,9 +93,8 @@ public class MusicPlayerBridge : GLib.Object this.registered_clients[client_name].update_state(PlayerController.state.READY); this.registered_clients[client_name].activate(); } - //else init a new one else{ - + //else init a new one PlayerController ctrl = new PlayerController(root_menu, client_name, calculate_menu_position(), diff --git a/src/player-controller.vala b/src/player-controller.vala index d272d14..48416b9 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -23,8 +23,15 @@ using Gee; public class PlayerController : GLib.Object { - public const int METADATA = 2; - private const int TRANSPORT = 3; + public const int WIDGET_QUANTITY = 5; + + public static enum widget_order{ + SEPARATOR, + TITLE, + METADATA, + SCRUB, + TRANSPORT + } public enum state{ OFFLINE, @@ -51,7 +58,6 @@ public class PlayerController : GLib.Object this.custom_items = new ArrayList<PlayerItem>(); this.update_state(initial_state); this.menu_offset = offset; - debug("offset = %i", offset); construct_widgets(); establish_mpris_connection(); update_layout(); @@ -66,7 +72,7 @@ public class PlayerController : GLib.Object public void activate() { this.establish_mpris_connection(); - this.custom_items[METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, true); + this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, true); } /* @@ -126,15 +132,15 @@ public class PlayerController : GLib.Object visibility = false; } debug("about the set the visibility on both the transport and metadata widget to %s", visibility.to_string()); - this.custom_items[TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE, visibility); - this.custom_items[METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, visibility); + this.custom_items[widget_order.TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE, visibility); + this.custom_items[widget_order.SCRUB].property_set_bool(MENUITEM_PROP_VISIBLE, visibility); + this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, visibility); // DEBUG if(this.mpris_adaptor == null){ warning("Why is the mpris object null"); } } - - + private void construct_widgets() { // Separator item @@ -147,11 +153,16 @@ public class PlayerController : GLib.Object // Metadata item 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); + foreach(PlayerItem item in this.custom_items){ root_menu.child_add_position(item, this.menu_offset + this.custom_items.index_of(item)); } diff --git a/src/player-item.vala b/src/player-item.vala index 3e10b7b..4bdb60d 100644 --- a/src/player-item.vala +++ b/src/player-item.vala @@ -38,6 +38,7 @@ public class PlayerItem : Dbusmenu.Menuitem foreach(string s in attrs){ debug("attempting to set prop %s to null", s); this.property_set(s, null); + this.property_set_int(s, 0); } } @@ -47,7 +48,8 @@ public class PlayerItem : Dbusmenu.Menuitem if(ensure_valid_updates(data, attributes) == false){ debug("PlayerItem::Update -> The hashtable update does not contain what we were expecting - just leave it!"); return; - } + } + foreach(string property in attributes){ string[] input_keys = property.split("-"); string search_key = input_keys[input_keys.length-1 : input_keys.length][0]; @@ -57,6 +59,7 @@ public class PlayerItem : Dbusmenu.Menuitem if (v.holds (typeof (string))){ string update = v.get_string().strip(); debug("with value : %s", update); + // Special case for the arturl URI's. if(property.contains("arturl")){ try{ update = Filename.from_uri(update.strip()); @@ -71,6 +74,10 @@ 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 (bool))){ this.property_set_bool(property, v.get_boolean()); } diff --git a/src/scrub-menu-item.vala b/src/scrub-menu-item.vala new file mode 100644 index 0000000..cfd6312 --- /dev/null +++ b/src/scrub-menu-item.vala @@ -0,0 +1,50 @@ +/* +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 DbusmenuScrub; +using Gee; + +public class ScrubMenuitem : PlayerItem +{ + public ScrubMenuitem(PlayerController parent) + { + Object(item_type: MENUITEM_TYPE, owner: parent); + } + + public override void handle_event(string name, GLib.Value input_value, uint timestamp) + { + debug("handle_event for owner %s with value: %f", this.owner.name, input_value.get_double()); + this.owner.mpris_adaptor.set_position(input_value.get_double()); + } + + public void update_position(int32 new_position) + { + this.property_set_int(MENUITEM_POSITION, new_position); + } + + + public static HashSet<string> attributes_format() + { + HashSet<string> attrs = new HashSet<string>(); + attrs.add(MENUITEM_DURATION); + attrs.add(MENUITEM_POSITION); + return attrs; + } +}
\ No newline at end of file diff --git a/src/scrub-widget.c b/src/scrub-widget.c new file mode 100644 index 0000000..799f81e --- /dev/null +++ b/src/scrub-widget.c @@ -0,0 +1,218 @@ +/* +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 "scrub-widget.h" +#include "common-defs.h" +#include <libido/idoscalemenuitem.h> + +typedef struct _ScrubWidgetPrivate ScrubWidgetPrivate; + +struct _ScrubWidgetPrivate +{ + DbusmenuMenuitem* twin_item; + GtkWidget* ido_scrub_bar; +}; + +#define SCRUB_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SCRUB_WIDGET_TYPE, ScrubWidgetPrivate)) + +/* Prototypes */ +static void scrub_widget_class_init (ScrubWidgetClass *klass); +static void scrub_widget_init (ScrubWidget *self); +static void scrub_widget_dispose (GObject *object); +static void scrub_widget_finalize (GObject *object); +static void scrub_widget_property_update( DbusmenuMenuitem* item, gchar* property, + GValue* value, gpointer userdata); +static void scrub_widget_set_twin_item( ScrubWidget* self, + DbusmenuMenuitem* twin_item); +static gchar* scrub_widget_format_time(gint time); +static void scrub_widget_set_ido_position(ScrubWidget* self, + gint position, + gint duration); +static gboolean scrub_widget_change_value_cb (GtkRange *range, + GtkScrollType scroll, + gdouble value, + gpointer user_data); + + +G_DEFINE_TYPE (ScrubWidget, scrub_widget, G_TYPE_OBJECT); + +static void +scrub_widget_class_init (ScrubWidgetClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (ScrubWidgetPrivate)); + + gobject_class->dispose = scrub_widget_dispose; + gobject_class->finalize = scrub_widget_finalize; +} + + +static void +scrub_widget_init (ScrubWidget *self) +{ + g_debug("ScrubWidget::scrub_widget_init"); + ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(self); + + priv->ido_scrub_bar = ido_scale_menu_item_new_with_range ("Scrub", 0, 0, 100, 1); + ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM(priv->ido_scrub_bar), IDO_SCALE_MENU_ITEM_STYLE_LABEL); + + g_object_set(priv->ido_scrub_bar, "reverse-scroll-events", TRUE, NULL); + + // register slider changes listening on the range + GtkWidget* scrub_widget = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_scrub_bar); + g_signal_connect(scrub_widget, "change-value", G_CALLBACK(scrub_widget_change_value_cb), self); +} + +static void +scrub_widget_dispose (GObject *object) +{ + G_OBJECT_CLASS (scrub_widget_parent_class)->dispose (object); +} + +static void +scrub_widget_finalize (GObject *object) +{ + G_OBJECT_CLASS (scrub_widget_parent_class)->finalize (object); +} + +static void +scrub_widget_property_update(DbusmenuMenuitem* item, gchar* property, + GValue* value, gpointer userdata) +{ + g_debug("scrub-widget::property_update"); + + g_return_if_fail (IS_SCRUB_WIDGET (userdata)); + ScrubWidget* mitem = SCRUB_WIDGET(userdata); + ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(mitem); + + if(g_ascii_strcasecmp(DBUSMENU_SCRUB_MENUITEM_DURATION, property) == 0){ + g_debug("scrub-widget::update length = %i", g_value_get_int(value)); + ido_scale_menu_item_set_secondary_label(IDO_SCALE_MENU_ITEM(priv->ido_scrub_bar), + scrub_widget_format_time(g_value_get_int(value))); + } + else if(g_ascii_strcasecmp(DBUSMENU_SCRUB_MENUITEM_POSITION, property) == 0){ + g_debug("scrub-widget::update position = %i", g_value_get_int(value)); + ido_scale_menu_item_set_primary_label(IDO_SCALE_MENU_ITEM(priv->ido_scrub_bar), + scrub_widget_format_time(g_value_get_int(value)/1000)); + } + scrub_widget_set_ido_position(mitem, + dbusmenu_menuitem_property_get_int(priv->twin_item, DBUSMENU_SCRUB_MENUITEM_POSITION)/1000, + dbusmenu_menuitem_property_get_int(priv->twin_item, DBUSMENU_SCRUB_MENUITEM_DURATION)); + +} + +static void +scrub_widget_set_twin_item(ScrubWidget* self, + DbusmenuMenuitem* twin_item) +{ + ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(self); + priv->twin_item = twin_item; + + g_signal_connect(G_OBJECT(twin_item), "property-changed", + G_CALLBACK(scrub_widget_property_update), self); + + gchar* left_text = scrub_widget_format_time(dbusmenu_menuitem_property_get_int(priv->twin_item, + DBUSMENU_SCRUB_MENUITEM_POSITION)/1000); + gchar* right_text = scrub_widget_format_time(dbusmenu_menuitem_property_get_int(priv->twin_item, + DBUSMENU_SCRUB_MENUITEM_DURATION)); + scrub_widget_set_ido_position(self, + dbusmenu_menuitem_property_get_int(priv->twin_item, DBUSMENU_SCRUB_MENUITEM_POSITION)/1000, + dbusmenu_menuitem_property_get_int(priv->twin_item, DBUSMENU_SCRUB_MENUITEM_DURATION)); + + ido_scale_menu_item_set_primary_label(IDO_SCALE_MENU_ITEM(priv->ido_scrub_bar), left_text); + ido_scale_menu_item_set_secondary_label(IDO_SCALE_MENU_ITEM(priv->ido_scrub_bar), right_text); + g_free(left_text); + g_free(right_text); +} + +static gboolean +scrub_widget_change_value_cb (GtkRange *range, + GtkScrollType scroll, + gdouble new_value, + gpointer user_data) +{ + g_return_val_if_fail (IS_SCRUB_WIDGET (user_data), FALSE); + ScrubWidget* mitem = SCRUB_WIDGET(user_data); + ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(mitem); + + GValue value = {0}; + g_value_init(&value, G_TYPE_DOUBLE); + gdouble clamped = CLAMP(new_value, 0, 100); + g_value_set_double(&value, clamped); + g_debug("scrub-widget-change-value callback - = %f", clamped); + dbusmenu_menuitem_handle_event (priv->twin_item, "scrubbing", &value, 0); + return FALSE; +} + +GtkWidget* +scrub_widget_get_ido_bar(ScrubWidget* self) +{ + ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(self); + return priv->ido_scrub_bar; +} + +static gchar* +scrub_widget_format_time(gint time) +{ + // Assuming its in seconds for now ... + gint minutes = time/60; + gint seconds = time % 60; + gchar* prefix="0"; + gchar* seconds_prefix="0"; + if(minutes > 9) + prefix=""; + if(seconds > 9) + seconds_prefix=""; + return g_strdup_printf("%s%i:%s%i", prefix, minutes, seconds_prefix, seconds); +} + +static void +scrub_widget_set_ido_position(ScrubWidget* self, + gint position, + gint duration) +{ + ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(self); + gdouble ido_position = position/(gdouble)duration * 100.0; + g_debug("scrub_widget_set_ido_position - pos: %i, duration: %i, ido_pos: %f", position, duration, ido_position); + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_scrub_bar); + GtkRange *range = (GtkRange*)slider; + if(duration == 0) + ido_position = 0.0; + gtk_range_set_value(range, ido_position); +} + + + /** + * scrub_widget_new: + * @returns: a new #ScrubWidget. + **/ +GtkWidget* +scrub_widget_new(DbusmenuMenuitem *item) +{ + GtkWidget* widget = g_object_new(SCRUB_WIDGET_TYPE, NULL); + scrub_widget_set_twin_item((ScrubWidget*)widget, item); + return widget; +} + diff --git a/src/scrub-widget.h b/src/scrub-widget.h new file mode 100644 index 0000000..cebe890 --- /dev/null +++ b/src/scrub-widget.h @@ -0,0 +1,53 @@ +/* +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 __SCRUB_WIDGET_H__ +#define __SCRUB_WIDGET_H__ + +#include <glib.h> +#include <glib-object.h> +#include <libdbusmenu-gtk/menu.h> + +G_BEGIN_DECLS + +#define SCRUB_WIDGET_TYPE (scrub_widget_get_type ()) +#define SCRUB_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SCRUB_WIDGET_TYPE, ScrubWidget)) +#define SCRUB_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SCRUB_WIDGET_TYPE, ScrubWidgetClass)) +#define IS_SCRUB_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SCRUB_WIDGET_TYPE)) +#define IS_SCRUB_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SCRUB_WIDGET_TYPE)) +#define SCRUB_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SCRUB_WIDGET_TYPE, ScrubWidgetClass)) + +typedef struct _ScrubWidget ScrubWidget; +typedef struct _ScrubWidgetClass ScrubWidgetClass; + +struct _ScrubWidgetClass { + GObjectClass parent_class; +}; + +struct _ScrubWidget { + GObject parent; +}; + +GType scrub_widget_get_type (void) G_GNUC_CONST; +GtkWidget* scrub_widget_new(DbusmenuMenuitem* twin_item); +GtkWidget* scrub_widget_get_ido_bar(ScrubWidget* self); + +G_END_DECLS + +#endif + diff --git a/src/sound-service-dbus.h b/src/sound-service-dbus.h index 258b610..72556ad 100644 --- a/src/sound-service-dbus.h +++ b/src/sound-service-dbus.h @@ -33,7 +33,6 @@ G_BEGIN_DECLS #define IS_SOUND_SERVICE_DBUS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SOUND_SERVICE_DBUS_TYPE)) #define SOUND_SERVICE_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SOUND_SERVICE_DBUS_TYPE, SoundServiceDbusClass)) - typedef struct _SoundServiceDbus SoundServiceDbus; typedef struct _SoundServiceDbusClass SoundServiceDbusClass; typedef struct _SoundData SoundData; diff --git a/src/sound-service.c b/src/sound-service.c index 8f4e941..8768cd3 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -39,7 +39,6 @@ should follow it. void service_shutdown (IndicatorService *service, gpointer user_data) { - if (mainloop != NULL) { g_debug("Service shutdown !"); // TODO: uncomment for release !! diff --git a/src/title-menu-item.vala b/src/title-menu-item.vala index 8183821..d7e16df 100644 --- a/src/title-menu-item.vala +++ b/src/title-menu-item.vala @@ -26,13 +26,11 @@ public class TitleMenuitem : PlayerItem public TitleMenuitem(PlayerController parent) { Object(item_type: MENUITEM_TYPE, owner: parent); - this.property_set(MENUITEM_TEXT_NAME, parent.name); + this.property_set(MENUITEM_NAME, parent.name); } public override void handle_event(string name, GLib.Value input_value, uint timestamp) - { - debug("handle_event for owner %s with owner state = %i and title menu name %s", this.owner.name, this.owner.current_state, property_get(MENUITEM_TEXT_NAME)); - + { if(this.owner.current_state == PlayerController.state.OFFLINE) { this.owner.instantiate(); @@ -43,7 +41,7 @@ public class TitleMenuitem : PlayerItem public static HashSet<string> attributes_format() { HashSet<string> attrs = new HashSet<string>(); - attrs.add(MENUITEM_TEXT_NAME); + attrs.add(MENUITEM_NAME); return attrs; } }
\ No newline at end of file diff --git a/src/title-widget.c b/src/title-widget.c index 7e48940..8037eb7 100644 --- a/src/title-widget.c +++ b/src/title-widget.c @@ -152,7 +152,7 @@ title_widget_property_update(DbusmenuMenuitem* item, gchar* property, TitleWidget* mitem = TITLE_WIDGET(userdata); TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(mitem); - if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_TEXT_NAME, property) == 0){ + if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_NAME, property) == 0){ gtk_label_set_text(GTK_LABEL(priv->name), g_value_get_string(value)); title_widget_style_name_text(mitem); } @@ -167,7 +167,7 @@ title_widget_set_twin_item(TitleWidget* self, g_signal_connect(G_OBJECT(twin_item), "property-changed", G_CALLBACK(title_widget_property_update), self); priv->name = gtk_label_new(dbusmenu_menuitem_property_get(priv->twin_item, - DBUSMENU_TITLE_MENUITEM_TEXT_NAME)); + DBUSMENU_TITLE_MENUITEM_NAME)); gtk_misc_set_padding(GTK_MISC(priv->name), 10, 0); gtk_box_pack_start (GTK_BOX (priv->hbox), priv->name, FALSE, FALSE, 0); |