From 4d9c1fa538254e065a1607de9e16dba126b55dd5 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 1 Dec 2010 20:20:00 +0000 Subject: dbus-glib removed from vala deps, initial gdbus port underway --- src/Makefile.am | 3 +- src/mpris2-controller.vala | 73 ++++++++++++++++++++++---------------------- src/music-player-bridge.vala | 12 +++----- src/player-controller.vala | 3 -- 4 files changed, 42 insertions(+), 49 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index b23e9c1..1362187 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -74,10 +74,9 @@ music_bridge_VALAFLAGS = \ --vapidir=./ \ --thread \ --pkg gee-1.0 \ - --pkg Indicate-0.2 \ --pkg Dbusmenu-Glib-0.2 \ --pkg common-defs \ - --pkg dbus-glib-1 \ + --pkg gio-2.0 \ --pkg gio-unix-2.0 \ --pkg gdk-pixbuf-2.0 diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index f440c13..0be018a 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -16,11 +16,11 @@ 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 DBus; +//using DBus; using Dbusmenu; [DBus (name = "org.mpris.MediaPlayer2")] -public interface MprisRoot : DBus.Object { +public interface MprisRoot : Object { // properties public abstract bool HasTracklist{owned get; set;} public abstract bool CanQuit{owned get; set;} @@ -28,11 +28,11 @@ public interface MprisRoot : DBus.Object { public abstract string Identity{owned get; set;} public abstract string DesktopEntry{owned get; set;} // methods - public abstract async void Quit() throws DBus.Error; - public abstract async void Raise() throws DBus.Error; + public abstract async void Quit() throws IOError; + public abstract async void Raise() throws IOError; } -[DBus (name = "org.mpris.MediaPlayer2.Player")] +/*[DBus (name = "org.mpris.MediaPlayer2.Player")] public interface MprisPlayer : DBus.Object { // properties @@ -54,7 +54,7 @@ public interface FreeDesktopProperties : DBus.Object{ Value?> changed_properties, string[] invalid); } - +*/ /* This class will entirely replace mpris-controller.vala hence why there is no point in trying to get encorporate both into the same object model. @@ -63,9 +63,10 @@ public class Mpris2Controller : GLib.Object { public static const string root_interface = "org.mpris.MediaPlayer2" ; public MprisRoot mpris2_root {get; construct;} - public MprisPlayer player {get; construct;} - public PlayerController owner {get; construct;} - public FreeDesktopProperties properties_interface {get; construct;} + /*public MprisPlayer player {get; construct;} + public FreeDesktopProperties properties_interface {get; construct;}*/ + + public PlayerController owner {get; construct;} public Mpris2Controller(PlayerController ctrl) { @@ -74,23 +75,22 @@ public class Mpris2Controller : GLib.Object construct{ try { - var connection = DBus.Bus.get (DBus.BusType.SESSION); - this.mpris2_root = (MprisRoot) connection.get_object (root_interface.concat(".").concat(this.owner.mpris_name), - "/org/mpris/MediaPlayer2", - root_interface); - this.player = (MprisPlayer) connection.get_object (root_interface.concat(".").concat(this.owner.mpris_name), + + this.mpris2_root = Bus.get_proxy_sync (BusType.SESSION, root_interface.concat(".").concat(this.owner.mpris_name), + "/org/mpris/MediaPlayer2"); + /*this.player = (MprisPlayer) connection.get_object (root_interface.concat(".").concat(this.owner.mpris_name), "/org/mpris/MediaPlayer2", root_interface.concat(".Player")); this.properties_interface = (FreeDesktopProperties) connection.get_object("org.freedesktop.Properties.PropertiesChanged", "/org/mpris/MediaPlayer2"); - this.properties_interface.PropertiesChanged += property_changed_cb; + this.properties_interface.PropertiesChanged += property_changed_cb;*/ - } catch (DBus.Error e) { + } catch (IOError e) { error("Problems connecting to the session bus - %s", e.message); } } - public void property_changed_cb(string interface_source, HashTable changed_properties, string[] invalid ) + /*public void property_changed_cb(string interface_source, HashTable changed_properties, string[] invalid ) { debug("properties-changed for interface %s and owner %s", interface_source, this.owner.mpris_name); @@ -115,11 +115,11 @@ public class Mpris2Controller : GLib.Object metadata.property_set_bool(MENUITEM_PROP_VISIBLE, metadata.populated(MetadataMenuitem.attributes_format())); } - } + }*/ - private GLib.HashTable clean_metadata() + private GLib.HashTable? clean_metadata() { - GLib.HashTable changed_updates = this.player.Metadata; + /*GLib.HashTable changed_updates = this.player.Metadata; Value? artist_v = this.player.Metadata.lookup("xesam:artist"); if(artist_v != null){ string[] artists = (string[])this.player.Metadata.lookup("xesam:artist"); @@ -133,9 +133,11 @@ public class Mpris2Controller : GLib.Object changed_updates.replace("mpris:length", duration/1000000); } return changed_updates; + */ + return null; } - private TransportMenuitem.state determine_play_state(string status){ + private TransportMenuitem.state determine_play_state(string? status){ if(status != null && status == "Playing"){ return TransportMenuitem.state.PLAYING; } @@ -145,22 +147,22 @@ public class Mpris2Controller : GLib.Object public void initial_update() { TransportMenuitem.state update; - if(this.player.PlaybackStatus == null){ + /*if(this.player.PlaybackStatus == null){ update = TransportMenuitem.state.PAUSED; - } - else{ - update = determine_play_state(this.player.PlaybackStatus); - } - (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(update); - GLib.HashTable cleaned_metadata = this.clean_metadata(); - this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata, - MetadataMenuitem.attributes_format()); + }*/ + + update = determine_play_state(null); + + (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(TransportMenuitem.state.PAUSED); + GLib.HashTable? cleaned_metadata = this.clean_metadata(); + //this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata, + // MetadataMenuitem.attributes_format()); } public void transport_update(TransportMenuitem.action command) { debug("transport_event input = %i", (int)command); - if(command == TransportMenuitem.action.PLAY_PAUSE){ + /*if(command == TransportMenuitem.action.PLAY_PAUSE){ this.player.PlayPause.begin(); } else if(command == TransportMenuitem.action.PREVIOUS){ @@ -168,26 +170,23 @@ public class Mpris2Controller : GLib.Object } else if(command == TransportMenuitem.action.NEXT){ this.player.Next.begin(); - } + }*/ } public bool connected() { - return (this.player != null && this.mpris2_root != null); + return false; } public bool was_successfull(){ - if(this.mpris2_root == null || this.player == null){ return false; - } - return true; } public void expose() { if(this.connected() == true){ - this.mpris2_root.Raise.begin(); + //this.mpris2_root.Raise.begin(); } } } diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index f13c2f4..3fc7efa 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -17,14 +17,12 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -using Indicate; using Dbusmenu; using Gee; using GLib; public class MusicPlayerBridge : GLib.Object { - private Listener listener; private Dbusmenu.Menuitem root_menu; private HashMap registered_clients; private FamiliarPlayersDB playersDB; @@ -33,9 +31,6 @@ public class MusicPlayerBridge : GLib.Object { playersDB = new FamiliarPlayersDB(); registered_clients = new HashMap (); - listener = Listener.ref_default(); - listener.server_added.connect(on_server_added); - listener.server_removed.connect(on_server_removed); } private void try_to_add_inactive_familiar_clients(){ @@ -76,7 +71,7 @@ public class MusicPlayerBridge : GLib.Object } } - public void on_server_added(Indicate.ListenerServer object, string type) + /*public void on_server_added(Indicate.ListenerServer object, string type) { debug("MusicPlayerBridge -> on_server_added with value %s", type); if(server_is_not_of_interest(type)) return; @@ -139,7 +134,7 @@ public class MusicPlayerBridge : GLib.Object return true; } return false; - } + }*/ public void set_root_menu_item(Dbusmenu.Menuitem menu) { @@ -158,6 +153,9 @@ public class MusicPlayerBridge : GLib.Object return app_info; } + /** + TODO: clean up + **/ private static string? determine_key(owned string path) { var tokens = path.split("/"); diff --git a/src/player-controller.vala b/src/player-controller.vala index e2ae4d7..46add60 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -178,9 +178,6 @@ public class PlayerController : GLib.Object return result; } - // Temporarily we will need to handle to different mpris implemenations - // Do it for now - a couple of weeks should see this messy carry on out of - // the codebase. public void determine_state() { if(this.mpris_bridge.connected() == true){ -- cgit v1.2.3 From b28241622081791ec4589d83a53078c768d4dea2 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 2 Dec 2010 19:35:49 +0000 Subject: moving in the right direction, registration happening on dbus watching --- src/Makefile.am | 2 ++ src/mpris2-controller.vala | 54 ++++++++----------------------- src/mpris2-interfaces.vala | 46 +++++++++++++++++++++++++++ src/mpris2-watcher.vala | 76 ++++++++++++++++++++++++++++++++++++++++++++ src/music-player-bridge.vala | 74 +++++++++++++++++------------------------- src/player-controller.vala | 2 +- src/sound-service.c | 4 +-- 7 files changed, 171 insertions(+), 87 deletions(-) create mode 100644 src/mpris2-interfaces.vala create mode 100644 src/mpris2-watcher.vala diff --git a/src/Makefile.am b/src/Makefile.am index 1362187..1c381f5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -60,6 +60,8 @@ music_bridge_VALASOURCES = \ metadata-menu-item.vala \ title-menu-item.vala \ player-controller.vala \ + mpris2-interfaces.vala \ + mpris2-watcher.vala \ mpris2-controller.vala \ player-item.vala \ familiar-players-db.vala \ diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 0be018a..c382e97 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -19,42 +19,15 @@ with this program. If not, see . //using DBus; using Dbusmenu; -[DBus (name = "org.mpris.MediaPlayer2")] -public interface MprisRoot : Object { - // properties - public abstract bool HasTracklist{owned get; set;} - public abstract bool CanQuit{owned get; set;} - public abstract bool CanRaise{owned get; set;} - public abstract string Identity{owned get; set;} - public abstract string DesktopEntry{owned get; set;} - // methods - public abstract async void Quit() throws IOError; - public abstract async void Raise() throws IOError; -} - -/*[DBus (name = "org.mpris.MediaPlayer2.Player")] -public interface MprisPlayer : DBus.Object { - - // properties - public abstract HashTable Metadata{owned get; set;} - public abstract int32 Position{owned get; set;} - public abstract string PlaybackStatus{owned get; set;} - // methods - public abstract async void PlayPause() throws DBus.Error; - public abstract async void Next() throws DBus.Error; - public abstract async void Previous() throws DBus.Error; - // signals - public signal void Seeked(int64 new_position); -} -[DBus (name = "org.freedesktop.DBus.Properties")] -public interface FreeDesktopProperties : DBus.Object{ +/*[DBus (name = "org.freedesktop.DBus.Properties")] + public interface FreeDesktopProperties : DBus.Object{ // signals public signal void PropertiesChanged(string source, HashTable changed_properties, string[] invalid); } -*/ + /* This class will entirely replace mpris-controller.vala hence why there is no point in trying to get encorporate both into the same object model. @@ -63,8 +36,8 @@ public class Mpris2Controller : GLib.Object { public static const string root_interface = "org.mpris.MediaPlayer2" ; public MprisRoot mpris2_root {get; construct;} - /*public MprisPlayer player {get; construct;} - public FreeDesktopProperties properties_interface {get; construct;}*/ + public MprisPlayer player {get; construct;} + //public FreeDesktopProperties properties_interface {get; construct;} public PlayerController owner {get; construct;} @@ -75,12 +48,13 @@ public class Mpris2Controller : GLib.Object construct{ try { - - this.mpris2_root = Bus.get_proxy_sync (BusType.SESSION, root_interface.concat(".").concat(this.owner.mpris_name), - "/org/mpris/MediaPlayer2"); - /*this.player = (MprisPlayer) connection.get_object (root_interface.concat(".").concat(this.owner.mpris_name), - "/org/mpris/MediaPlayer2", - root_interface.concat(".Player")); + this.mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, + root_interface.concat(".").concat(this.owner.mpris_name), + "/org/mpris/MediaPlayer2"); + this.player = Bus.get_proxy_sync ( BusType.SESSION, + root_interface.concat(".").concat(this.owner.mpris_name), + "/org/mpris/MediaPlayer2" ); + /* this.properties_interface = (FreeDesktopProperties) connection.get_object("org.freedesktop.Properties.PropertiesChanged", "/org/mpris/MediaPlayer2"); this.properties_interface.PropertiesChanged += property_changed_cb;*/ @@ -162,7 +136,7 @@ public class Mpris2Controller : GLib.Object public void transport_update(TransportMenuitem.action command) { debug("transport_event input = %i", (int)command); - /*if(command == TransportMenuitem.action.PLAY_PAUSE){ + if(command == TransportMenuitem.action.PLAY_PAUSE){ this.player.PlayPause.begin(); } else if(command == TransportMenuitem.action.PREVIOUS){ @@ -170,7 +144,7 @@ public class Mpris2Controller : GLib.Object } else if(command == TransportMenuitem.action.NEXT){ this.player.Next.begin(); - }*/ + } } public bool connected() diff --git a/src/mpris2-interfaces.vala b/src/mpris2-interfaces.vala new file mode 100644 index 0000000..ef62aba --- /dev/null +++ b/src/mpris2-interfaces.vala @@ -0,0 +1,46 @@ +/* +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +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 . +*/ + + +[DBus (name = "org.mpris.MediaPlayer2")] +public interface MprisRoot : Object { + // properties + public abstract bool HasTracklist{owned get; set;} + public abstract bool CanQuit{owned get; set;} + public abstract bool CanRaise{owned get; set;} + public abstract string Identity{owned get; set;} + public abstract string DesktopEntry{owned get; set;} + // methods + public abstract async void Quit() throws IOError; + public abstract async void Raise() throws IOError; +} + +[DBus (name = "org.mpris.MediaPlayer2.Player")] +public interface MprisPlayer : Object { + // properties + public abstract HashTable Metadata{owned get; set;} + public abstract int32 Position{owned get; set;} + public abstract string PlaybackStatus{owned get; set;} + // methods + public abstract async void PlayPause() throws IOError; + public abstract async void Next() throws IOError; + public abstract async void Previous() throws IOError; + // signals + public signal void Seeked(int64 new_position); +} diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala new file mode 100644 index 0000000..55212ec --- /dev/null +++ b/src/mpris2-watcher.vala @@ -0,0 +1,76 @@ +/* +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +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 . +*/ + +// TODO: Until match rules are properly supported in vala we need to explicitly +// watch for each client inorder to facilitate proper registration. + +public class Mpris2Watcher : GLib.Object +{ + public MusicPlayerBridge the_bridge {get; construct;} + const string BANSHEE_BUS_NAME = "org.mpris.MediaPlayer2.banshee"; + private MprisRoot mpris2_root; + private DBusConnection connection; + + public Mpris2Watcher ( MusicPlayerBridge bridge ) + { + GLib.Object(the_bridge: bridge); + } + + construct{ + try { + this.connection = Bus.get_sync ( BusType.SESSION ); + GLib.BusNameAppearedCallback banshee_change_cb = (GLib.BusNameAppearedCallback)banshee_appeared; + GLib.BusNameVanishedCallback banshee_gone_cb = (GLib.BusNameVanishedCallback)banshee_disappeared; + Bus.watch_name_on_connection ( this.connection, + BANSHEE_BUS_NAME, + BusNameWatcherFlags.AUTO_START, + banshee_change_cb, + banshee_gone_cb ); + } + catch ( IOError e ){ + warning( "Mpris2watcher could not set up a watch for mpris clients appearing on the bus: %s", + e.message ); + } + } + + private void banshee_appeared ( GLib.DBusConnection connection, + string name, + string name_owner ) + { + try { + this.mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, + BANSHEE_BUS_NAME, + "/org/mpris/MediaPlayer2" ); + this.the_bridge.client_has_become_available ( this.mpris2_root.DesktopEntry ); + debug ( "On Name Appeared - name %s, name_owner %s", this.mpris2_root.DesktopEntry, name_owner ); + } + catch ( IOError e ){ + warning( "Mpris2watcher could not instantiate an mpris root for banshee: %s", + e.message ); + } + } + + private void banshee_disappeared ( GLib.DBusConnection connection, + string name, + string name_owner ) + { + debug ( "On Name Disappeared - name %s, name_owner %s", name, name_owner ); + } + +} \ No newline at end of file diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 3fc7efa..8d7998e 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -26,13 +26,14 @@ public class MusicPlayerBridge : GLib.Object private Dbusmenu.Menuitem root_menu; private HashMap registered_clients; private FamiliarPlayersDB playersDB; - + private Mpris2Watcher watcher; + private const string DESKTOP_PREFIX = "/usr/share/applications/"; public MusicPlayerBridge() { playersDB = new FamiliarPlayersDB(); registered_clients = new HashMap (); } - + private void try_to_add_inactive_familiar_clients(){ foreach(string app in this.playersDB.records()){ if(app == null){ @@ -79,41 +80,39 @@ public class MusicPlayerBridge : GLib.Object listener_get_server_property_cb cb = (listener_get_server_property_cb)desktop_info_callback; this.listener.server_get_desktop(object, cb, this); } - } + }*/ - private void desktop_info_callback ( Indicate.ListenerServer server, - owned string path, - void* data ) - { - MusicPlayerBridge bridge = data as MusicPlayerBridge; - AppInfo? app_info = create_app_info(path); + public void client_has_become_available ( string desktop_file_name ) + { + string path = DESKTOP_PREFIX.concat ( desktop_file_name.concat( ".desktop" ) ); + AppInfo? app_info = create_app_info ( path ); if ( app_info == null ){ warning ( "Could not create app_info for path %s \n Getting out of here ", path); return; } - var mpris_key = determine_key(path); + var mpris_key = determine_key ( desktop_file_name ); - if(bridge.playersDB.already_familiar(path) == false){ - debug("New client has registered that we have seen before: %s", path); - bridge.playersDB.insert(path); - PlayerController ctrl = new PlayerController ( bridge.root_menu, + if ( this.playersDB.already_familiar ( path ) == false ){ + debug("New client has registered that we have not seen before: %s", desktop_file_name ); + this.playersDB.insert ( path ); + PlayerController ctrl = new PlayerController ( this.root_menu, app_info, mpris_key, playersDB.fetch_icon_name(path), - bridge.calculate_menu_position(), + this.calculate_menu_position(), PlayerController.state.READY ); - bridge.registered_clients.set(mpris_key, ctrl); - debug("successfully created appinfo and instance from path and set it on the respective instance"); + this.registered_clients.set ( mpris_key, ctrl ); + debug ( "successfully created appinfo and instance from path and set it on the respective instance" ); } else{ - bridge.registered_clients[mpris_key].update_state(PlayerController.state.READY); - bridge.registered_clients[mpris_key].activate(); + this.registered_clients[mpris_key].update_state ( PlayerController.state.READY ); + this.registered_clients[mpris_key].activate ( ); debug("Ignoring desktop file path callback because the db cache file has it already: %s \n", path); } } - public void on_server_removed(Indicate.ListenerServer object, string type) + /*public void on_server_removed(Indicate.ListenerServer object, string type) { debug("MusicPlayerBridge -> on_server_removed with value %s", type); if(server_is_not_of_interest(type)) return; @@ -125,44 +124,31 @@ public class MusicPlayerBridge : GLib.Object debug("Successively offlined client %s", tmp[tmp.length - 1]); } } - } - - private bool server_is_not_of_interest(string type){ - if (type == null) return true; - if (type.contains("music") == false) { - debug("server is of no interest, it is not an music server"); - return true; - } - return false; }*/ + public void set_root_menu_item(Dbusmenu.Menuitem menu) { this.root_menu = menu; - try_to_add_inactive_familiar_clients(); + this.try_to_add_inactive_familiar_clients(); + this.watcher = new Mpris2Watcher (this) ; } - public static AppInfo? create_app_info(string path) + public static AppInfo? create_app_info ( string path ) { - DesktopAppInfo info = new DesktopAppInfo.from_filename(path); - if(path == null){ - warning("Could not create a desktopappinfo instance from app: %s", path); + DesktopAppInfo info = new DesktopAppInfo.from_filename ( path ) ; + if ( path == null || info == null ){ + warning ( "Could not create a desktopappinfo instance from app: %s", path ); return null; } - GLib.AppInfo app_info = info as GLib.AppInfo; + GLib.AppInfo app_info = info as GLib.AppInfo; return app_info; } - /** - TODO: clean up - **/ - private static string? determine_key(owned string path) + private static string? determine_key(owned string name) { - var tokens = path.split("/"); - if ( tokens.length < 2) return null; - var filename = tokens[tokens.length - 1]; - var result = filename.split(".")[0]; - var temp = result.split("-"); + string result = name; + var temp = name.split("-"); if (temp.length > 1){ result = temp[0]; } diff --git a/src/player-controller.vala b/src/player-controller.vala index 46add60..3c9b0ff 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -114,7 +114,7 @@ public class PlayerController : GLib.Object public void vanish() { foreach(Dbusmenu.Menuitem item in this.custom_items){ - root_menu.child_delete(item); + root_menu.child_delete(item); } } diff --git a/src/sound-service.c b/src/sound-service.c index f19379d..51f5f37 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -41,8 +41,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) if (mainloop != NULL) { g_debug("Service shutdown !"); //TODO: uncomment for release !! - close_pulse_activites(); - g_main_loop_quit(mainloop); + //close_pulse_activites(); + //g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3 From d113aa188ab72d8ca3efe22ad7f336f753fb4e48 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 3 Dec 2010 13:58:30 +0000 Subject: used a signal instead of passing in ref, still vala bug is biting --- src/mpris2-watcher.vala | 36 +++++++----- src/music-player-bridge.vala | 129 ++++++++++++++++++++++--------------------- 2 files changed, 88 insertions(+), 77 deletions(-) diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index 55212ec..ed7388f 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -22,17 +22,15 @@ with this program. If not, see . public class Mpris2Watcher : GLib.Object { - public MusicPlayerBridge the_bridge {get; construct;} const string BANSHEE_BUS_NAME = "org.mpris.MediaPlayer2.banshee"; - private MprisRoot mpris2_root; private DBusConnection connection; - - public Mpris2Watcher ( MusicPlayerBridge bridge ) + public signal void clientappeared ( string desktop_name ); + + public Mpris2Watcher () { - GLib.Object(the_bridge: bridge); } - - construct{ + construct + { try { this.connection = Bus.get_sync ( BusType.SESSION ); GLib.BusNameAppearedCallback banshee_change_cb = (GLib.BusNameAppearedCallback)banshee_appeared; @@ -46,19 +44,23 @@ public class Mpris2Watcher : GLib.Object catch ( IOError e ){ warning( "Mpris2watcher could not set up a watch for mpris clients appearing on the bus: %s", e.message ); - } + } } private void banshee_appeared ( GLib.DBusConnection connection, string name, - string name_owner ) + string name_owner) { try { - this.mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, - BANSHEE_BUS_NAME, - "/org/mpris/MediaPlayer2" ); - this.the_bridge.client_has_become_available ( this.mpris2_root.DesktopEntry ); - debug ( "On Name Appeared - name %s, name_owner %s", this.mpris2_root.DesktopEntry, name_owner ); + MprisRoot mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, + BANSHEE_BUS_NAME, + "/org/mpris/MediaPlayer2" ); + //this.the_bridge.client_has_become_available ( mpris2_root.DesktopEntry ); + debug ( "On Name Appeared - name %s, name_owner %s", + mpris2_root.DesktopEntry, + name_owner ); + debug ( "this pointer in banshee appeared callback %i", (int)this); + this.clientappeared ( "mpris2_root.DesktopEntry" ); } catch ( IOError e ){ warning( "Mpris2watcher could not instantiate an mpris root for banshee: %s", @@ -66,6 +68,12 @@ public class Mpris2Watcher : GLib.Object } } + public void test_signal_emission() + { + this.clientappeared ( "test signal emission" ); + debug ( "this pointer in test-signal-emission %i", (int)this); + } + private void banshee_disappeared ( GLib.DBusConnection connection, string name, string name_owner ) diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 8d7998e..73469a4 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -24,54 +24,55 @@ using GLib; public class MusicPlayerBridge : GLib.Object { private Dbusmenu.Menuitem root_menu; - private HashMap registered_clients; - private FamiliarPlayersDB playersDB; + private HashMap registered_clients; + private FamiliarPlayersDB playersDB; private Mpris2Watcher watcher; private const string DESKTOP_PREFIX = "/usr/share/applications/"; + public MusicPlayerBridge() { - playersDB = new FamiliarPlayersDB(); - registered_clients = new HashMap (); + playersDB = new FamiliarPlayersDB(); + registered_clients = new HashMap (); } - private void try_to_add_inactive_familiar_clients(){ - foreach(string app in this.playersDB.records()){ - if(app == null){ - warning("App string in keyfile is null therefore moving on to next player"); - continue; - } + private void try_to_add_inactive_familiar_clients(){ + foreach(string app in this.playersDB.records()){ + if(app == null){ + warning("App string in keyfile is null therefore moving on to next player"); + continue; + } + + debug("attempting to make an app info from %s", app); - debug("attempting to make an app info from %s", app); - - DesktopAppInfo info = new DesktopAppInfo.from_filename(app); + DesktopAppInfo info = new DesktopAppInfo.from_filename(app); if(info == null){ - warning("Could not create a desktopappinfo instance from app,: %s , moving on to the next client", app); - continue; - } + warning("Could not create a desktopappinfo instance from app,: %s , moving on to the next client", app); + continue; + } - GLib.AppInfo app_info = info as GLib.AppInfo; + GLib.AppInfo app_info = info as GLib.AppInfo; var mpris_key = determine_key(app); - PlayerController ctrl = new PlayerController(this.root_menu, - app_info, + PlayerController ctrl = new PlayerController(this.root_menu, + app_info, mpris_key, playersDB.fetch_icon_name(app), - calculate_menu_position(), - PlayerController.state.OFFLINE); - this.registered_clients.set(mpris_key, ctrl); - } - } + calculate_menu_position(), + PlayerController.state.OFFLINE); + this.registered_clients.set(mpris_key, ctrl); + } + } - private int calculate_menu_position() - { - if(this.registered_clients.size == 0){ - return 2; - } - else{ - return (2 + (this.registered_clients.size * PlayerController.WIDGET_QUANTITY)); - } - } - + private int calculate_menu_position() + { + if(this.registered_clients.size == 0){ + return 2; + } + else{ + return (2 + (this.registered_clients.size * PlayerController.WIDGET_QUANTITY)); + } + } + /*public void on_server_added(Indicate.ListenerServer object, string type) { debug("MusicPlayerBridge -> on_server_added with value %s", type); @@ -84,8 +85,9 @@ public class MusicPlayerBridge : GLib.Object public void client_has_become_available ( string desktop_file_name ) { + debug ( "client_has_become_available %s", desktop_file_name ); string path = DESKTOP_PREFIX.concat ( desktop_file_name.concat( ".desktop" ) ); - AppInfo? app_info = create_app_info ( path ); + AppInfo? app_info = create_app_info ( path ); if ( app_info == null ){ warning ( "Could not create app_info for path %s \n Getting out of here ", path); return; @@ -93,24 +95,24 @@ public class MusicPlayerBridge : GLib.Object var mpris_key = determine_key ( desktop_file_name ); - if ( this.playersDB.already_familiar ( path ) == false ){ - debug("New client has registered that we have not seen before: %s", desktop_file_name ); - this.playersDB.insert ( path ); - PlayerController ctrl = new PlayerController ( this.root_menu, - app_info, + if ( this.playersDB.already_familiar ( path ) == false ){ + debug("New client has registered that we have not seen before: %s", desktop_file_name ); + this.playersDB.insert ( path ); + PlayerController ctrl = new PlayerController ( this.root_menu, + app_info, mpris_key, playersDB.fetch_icon_name(path), - this.calculate_menu_position(), - PlayerController.state.READY ); + this.calculate_menu_position(), + PlayerController.state.READY ); this.registered_clients.set ( mpris_key, ctrl ); debug ( "successfully created appinfo and instance from path and set it on the respective instance" ); - } - else{ - this.registered_clients[mpris_key].update_state ( PlayerController.state.READY ); - this.registered_clients[mpris_key].activate ( ); - debug("Ignoring desktop file path callback because the db cache file has it already: %s \n", path); - } - } + } + else{ + this.registered_clients[mpris_key].update_state ( PlayerController.state.READY ); + this.registered_clients[mpris_key].activate ( ); + debug("Ignoring desktop file path callback because the db cache file has it already: %s \n", path); + } + } /*public void on_server_removed(Indicate.ListenerServer object, string type) { @@ -126,24 +128,25 @@ public class MusicPlayerBridge : GLib.Object } }*/ - public void set_root_menu_item(Dbusmenu.Menuitem menu) { - this.root_menu = menu; - this.try_to_add_inactive_familiar_clients(); - this.watcher = new Mpris2Watcher (this) ; + this.root_menu = menu; + this.try_to_add_inactive_familiar_clients(); + this.watcher = new Mpris2Watcher (); + this.watcher.clientappeared += this.client_has_become_available; + this.watcher.test_signal_emission(); } - public static AppInfo? create_app_info ( string path ) - { - DesktopAppInfo info = new DesktopAppInfo.from_filename ( path ) ; - if ( path == null || info == null ){ - warning ( "Could not create a desktopappinfo instance from app: %s", path ); - return null; - } - GLib.AppInfo app_info = info as GLib.AppInfo; - return app_info; - } + public static AppInfo? create_app_info ( string path ) + { + DesktopAppInfo info = new DesktopAppInfo.from_filename ( path ) ; + if ( path == null || info == null ){ + warning ( "Could not create a desktopappinfo instance from app: %s", path ); + return null; + } + GLib.AppInfo app_info = info as GLib.AppInfo; + return app_info; + } private static string? determine_key(owned string name) { -- cgit v1.2.3 From 5aada20653702ce8996abd7d25c9bce0a59b65ff Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 3 Dec 2010 15:05:07 +0000 Subject: used a signal instead of passing in ref, still vala bug is biting --- src/mpris2-watcher.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index ed7388f..775d9b6 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -47,7 +47,7 @@ public class Mpris2Watcher : GLib.Object } } - private void banshee_appeared ( GLib.DBusConnection connection, + public void banshee_appeared ( GLib.DBusConnection connection, string name, string name_owner) { -- cgit v1.2.3 From 91aa96835684880832c8e535798ebeb6dcca4039 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 3 Dec 2010 20:03:21 +0000 Subject: new registration process complete and seemingly healthy --- src/mpris2-watcher.vala | 92 ++++++++++++++++++++++---------------------- src/music-player-bridge.vala | 4 +- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index 775d9b6..7e41b5f 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -17,68 +17,68 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -// TODO: Until match rules are properly supported in vala we need to explicitly -// watch for each client inorder to facilitate proper registration. +[DBus (name = "org.freedesktop.DBus")] +public interface FreeDesktopObject: Object { + public abstract signal void name_owner_changed (string name, + string old_owner, + string new_owner); +} public class Mpris2Watcher : GLib.Object { - const string BANSHEE_BUS_NAME = "org.mpris.MediaPlayer2.banshee"; - private DBusConnection connection; - public signal void clientappeared ( string desktop_name ); + private const string FREEDESKTOP_SERVICE = "org.freedesktop.DBus"; + private const string FREEDESKTOP_OBJECT = "/org/freedesktop/DBus"; + private const string MPRIS_PREFIX = "org.mpris.MediaPlayer2."; + private const string MPRIS_MEDIA_PLAYER_PATH = "/org/mpris/MediaPlayer2"; + + FreeDesktopObject fdesktop_obj; + + public signal void client_appeared ( string desktop_name ); + public signal void client_disappeared ( string desktop_name ); public Mpris2Watcher () { } + construct { try { - this.connection = Bus.get_sync ( BusType.SESSION ); - GLib.BusNameAppearedCallback banshee_change_cb = (GLib.BusNameAppearedCallback)banshee_appeared; - GLib.BusNameVanishedCallback banshee_gone_cb = (GLib.BusNameVanishedCallback)banshee_disappeared; - Bus.watch_name_on_connection ( this.connection, - BANSHEE_BUS_NAME, - BusNameWatcherFlags.AUTO_START, - banshee_change_cb, - banshee_gone_cb ); + this.fdesktop_obj = Bus.get_proxy_sync ( BusType.SESSION, + FREEDESKTOP_SERVICE, + FREEDESKTOP_OBJECT, + DBusProxyFlags.DO_NOT_LOAD_PROPERTIES ); + this.fdesktop_obj.name_owner_changed.connect (this.name_changes_detected); } catch ( IOError e ){ warning( "Mpris2watcher could not set up a watch for mpris clients appearing on the bus: %s", - e.message ); + e.message ); } } - public void banshee_appeared ( GLib.DBusConnection connection, - string name, - string name_owner) - { - try { - MprisRoot mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, - BANSHEE_BUS_NAME, - "/org/mpris/MediaPlayer2" ); - //this.the_bridge.client_has_become_available ( mpris2_root.DesktopEntry ); - debug ( "On Name Appeared - name %s, name_owner %s", - mpris2_root.DesktopEntry, - name_owner ); - debug ( "this pointer in banshee appeared callback %i", (int)this); - this.clientappeared ( "mpris2_root.DesktopEntry" ); + private void name_changes_detected ( FreeDesktopObject dbus_obj, + string name, + string previous_owner, + string current_owner ) { + MprisRoot mpris2_root; + if ( name.has_prefix (MPRIS_PREFIX) ){ + try { + mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, + name, + MPRIS_MEDIA_PLAYER_PATH ); + } + catch (IOError e){ + warning( "Mpris2watcher could not create a root interface: %s", + e.message ); + return; + } + if (previous_owner != "" && current_owner == "") { + debug ("Service '%s' going down", name); + client_disappeared (mpris2_root.DesktopEntry); + } + else if (previous_owner == "" && current_owner != "") { + debug ("Service '%s' has appeared", name); + client_appeared (mpris2_root.DesktopEntry); + } } - catch ( IOError e ){ - warning( "Mpris2watcher could not instantiate an mpris root for banshee: %s", - e.message ); - } } - - public void test_signal_emission() - { - this.clientappeared ( "test signal emission" ); - debug ( "this pointer in test-signal-emission %i", (int)this); - } - - private void banshee_disappeared ( GLib.DBusConnection connection, - string name, - string name_owner ) - { - debug ( "On Name Disappeared - name %s, name_owner %s", name, name_owner ); - } - } \ No newline at end of file diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 73469a4..8124021 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -133,8 +133,8 @@ public class MusicPlayerBridge : GLib.Object this.root_menu = menu; this.try_to_add_inactive_familiar_clients(); this.watcher = new Mpris2Watcher (); - this.watcher.clientappeared += this.client_has_become_available; - this.watcher.test_signal_emission(); + this.watcher.client_appeared += this.client_has_become_available; + //this.watcher.client_appeared += this.client_has_become_available; } public static AppInfo? create_app_info ( string path ) -- cgit v1.2.3 From 65127a75569ae72173423510dedbc639f71cd9ba Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Mon, 6 Dec 2010 13:22:26 +0000 Subject: registration working now but menuitems are unresponsive, now to move over to the new dbusmenu --- src/music-player-bridge.vala | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 8124021..c905c12 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -52,7 +52,7 @@ public class MusicPlayerBridge : GLib.Object } GLib.AppInfo app_info = info as GLib.AppInfo; - var mpris_key = determine_key(app); + var mpris_key = determine_key ( app ); PlayerController ctrl = new PlayerController(this.root_menu, app_info, mpris_key, @@ -93,7 +93,7 @@ public class MusicPlayerBridge : GLib.Object return; } - var mpris_key = determine_key ( desktop_file_name ); + var mpris_key = determine_key ( path ); if ( this.playersDB.already_familiar ( path ) == false ){ debug("New client has registered that we have not seen before: %s", desktop_file_name ); @@ -148,10 +148,13 @@ public class MusicPlayerBridge : GLib.Object return app_info; } - private static string? determine_key(owned string name) + private static string? determine_key(owned string path) { - string result = name; - var temp = name.split("-"); + var tokens = path.split("/"); + if ( tokens.length < 2) return null; + var filename = tokens[tokens.length - 1]; + var result = filename.split(".")[0]; + var temp = result.split("-"); if (temp.length > 1){ result = temp[0]; } -- cgit v1.2.3 From aef17a4810d3480b64b20dd6aebd8b12e104778a Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Mon, 6 Dec 2010 15:33:58 +0000 Subject: registration working perfectly and operational all over gdbus --- src/mpris2-controller.vala | 207 +++++++++++++++++++++---------------------- src/mpris2-watcher.vala | 8 +- src/music-player-bridge.vala | 34 ++++--- 3 files changed, 124 insertions(+), 125 deletions(-) diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index c382e97..ff19598 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -20,11 +20,9 @@ with this program. If not, see . using Dbusmenu; -/*[DBus (name = "org.freedesktop.DBus.Properties")] - public interface FreeDesktopProperties : DBus.Object{ - // signals - public signal void PropertiesChanged(string source, HashTable changed_properties, +[DBus (name = "org.freedesktop.DBus.Properties")] + public interface FreeDesktopProperties : Object{ + public signal void PropertiesChanged(string source, HashTable changed_properties, string[] invalid); } @@ -33,136 +31,131 @@ using Dbusmenu; point in trying to get encorporate both into the same object model. */ public class Mpris2Controller : GLib.Object -{ - public static const string root_interface = "org.mpris.MediaPlayer2" ; - public MprisRoot mpris2_root {get; construct;} - public MprisPlayer player {get; construct;} - //public FreeDesktopProperties properties_interface {get; construct;} +{ + public static const string root_interface = "org.mpris.MediaPlayer2" ; + public MprisRoot mpris2_root {get; construct;} + public MprisPlayer player {get; construct;} + public FreeDesktopProperties properties_interface {get; construct;} public PlayerController owner {get; construct;} - - public Mpris2Controller(PlayerController ctrl) - { - GLib.Object(owner: ctrl); - } - - construct{ + + public Mpris2Controller(PlayerController ctrl) + { + GLib.Object(owner: ctrl); + } + + construct{ try { - this.mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, + this.mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, root_interface.concat(".").concat(this.owner.mpris_name), - "/org/mpris/MediaPlayer2"); - this.player = Bus.get_proxy_sync ( BusType.SESSION, + "/org/mpris/MediaPlayer2"); + this.player = Bus.get_proxy_sync ( BusType.SESSION, root_interface.concat(".").concat(this.owner.mpris_name), - "/org/mpris/MediaPlayer2" ); - /* - this.properties_interface = (FreeDesktopProperties) connection.get_object("org.freedesktop.Properties.PropertiesChanged", - "/org/mpris/MediaPlayer2"); - this.properties_interface.PropertiesChanged += property_changed_cb;*/ + "/org/mpris/MediaPlayer2" ); - } catch (IOError e) { - error("Problems connecting to the session bus - %s", e.message); - } - } - - /*public void property_changed_cb(string interface_source, HashTable changed_properties, string[] invalid ) - { - debug("properties-changed for interface %s and owner %s", interface_source, this.owner.mpris_name); - - if(changed_properties == null || interface_source.has_prefix(this.root_interface) == false ){ - warning("Property-changed hash is null or this is an interface that doesn't concerns us"); - return; - } - Value? play_v = changed_properties.lookup("PlaybackStatus"); - if(play_v != null){ - string state = this.player.PlaybackStatus; - TransportMenuitem.state p = (TransportMenuitem.state)this.determine_play_state(state); - (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p); - } - - Value? meta_v = changed_properties.lookup("Metadata"); - if(meta_v != null){ - GLib.HashTable changed_updates = clean_metadata(); + this.properties_interface = Bus.get_proxy_sync ( BusType.SESSION, + "org.freedesktop.Properties.PropertiesChanged", + "/org/mpris/MediaPlayer2" ); + this.properties_interface.PropertiesChanged += property_changed_cb; + } + catch (IOError e) { + error("Problems connecting to the session bus - %s", e.message); + } + } + + public void property_changed_cb ( string interface_source, + HashTable changed_properties, + string[] invalid ) + { + debug("properties-changed for interface %s and owner %s", interface_source, this.owner.mpris_name); + if(changed_properties == null || interface_source.has_prefix(this.root_interface) == false ){ + warning("Property-changed hash is null or this is an interface that doesn't concerns us"); + return; + } + Variant? play_v = changed_properties.lookup("PlaybackStatus"); + if(play_v != null){ + string state = this.player.PlaybackStatus; + TransportMenuitem.state p = (TransportMenuitem.state)this.determine_play_state(state); + (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p); + } + Variant? meta_v = changed_properties.lookup("Metadata"); + if(meta_v != null){ + GLib.HashTable changed_updates = clean_metadata(); PlayerItem metadata = this.owner.custom_items[PlayerController.widget_order.METADATA]; - metadata.reset(MetadataMenuitem.attributes_format()); - metadata.update(changed_updates, - MetadataMenuitem.attributes_format()); - metadata.property_set_bool(MENUITEM_PROP_VISIBLE, - metadata.populated(MetadataMenuitem.attributes_format())); + metadata.reset( MetadataMenuitem.attributes_format()); + metadata.update ( changed_updates, + MetadataMenuitem.attributes_format()); + metadata.property_set_bool ( MENUITEM_PROP_VISIBLE, + metadata.populated(MetadataMenuitem.attributes_format())); } - }*/ + } - private GLib.HashTable? clean_metadata() + private GLib.HashTable? clean_metadata() { - /*GLib.HashTable changed_updates = this.player.Metadata; - Value? artist_v = this.player.Metadata.lookup("xesam:artist"); + GLib.HashTable changed_updates = this.player.Metadata; + Variant? artist_v = this.player.Metadata.lookup("xesam:artist"); if(artist_v != null){ string[] artists = (string[])this.player.Metadata.lookup("xesam:artist"); string display_artists = string.joinv(", ", artists); changed_updates.replace("xesam:artist", display_artists); debug("artist : %s", display_artists); } - Value? length_v = this.player.Metadata.lookup("mpris:length"); + Variant? length_v = this.player.Metadata.lookup("mpris:length"); if(length_v != null){ int64 duration = this.player.Metadata.lookup("mpris:length").get_int64(); changed_updates.replace("mpris:length", duration/1000000); } return changed_updates; - */ - return null; - } - - private TransportMenuitem.state determine_play_state(string? status){ - if(status != null && status == "Playing"){ - return TransportMenuitem.state.PLAYING; - } - return TransportMenuitem.state.PAUSED; + //return null; } - public void initial_update() - { - TransportMenuitem.state update; - /*if(this.player.PlaybackStatus == null){ - update = TransportMenuitem.state.PAUSED; - }*/ + private TransportMenuitem.state determine_play_state(string? status){ + if(status != null && status == "Playing"){ + return TransportMenuitem.state.PLAYING; + } + return TransportMenuitem.state.PAUSED; + } + + public void initial_update() + { + TransportMenuitem.state update; + if(this.player.PlaybackStatus == null){ + update = TransportMenuitem.state.PAUSED; + } update = determine_play_state(null); - + (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(TransportMenuitem.state.PAUSED); - GLib.HashTable? cleaned_metadata = this.clean_metadata(); - //this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata, - // MetadataMenuitem.attributes_format()); - } - - public void transport_update(TransportMenuitem.action command) - { - debug("transport_event input = %i", (int)command); - if(command == TransportMenuitem.action.PLAY_PAUSE){ - this.player.PlayPause.begin(); - } - else if(command == TransportMenuitem.action.PREVIOUS){ - this.player.Previous.begin(); - } - else if(command == TransportMenuitem.action.NEXT){ - this.player.Next.begin(); - } - } - - public bool connected() - { - return false; - } + GLib.HashTable? cleaned_metadata = this.clean_metadata(); + this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata, + MetadataMenuitem.attributes_format()); + } + + public void transport_update(TransportMenuitem.action command) + { + debug("transport_event input = %i", (int)command); + if(command == TransportMenuitem.action.PLAY_PAUSE){ + this.player.PlayPause.begin(); + } + else if(command == TransportMenuitem.action.PREVIOUS){ + this.player.Previous.begin(); + } + else if(command == TransportMenuitem.action.NEXT){ + this.player.Next.begin(); + } + } - - public bool was_successfull(){ - return false; - } + public bool connected() + { + return (this.player != null && this.mpris2_root != null); + } - public void expose() - { - if(this.connected() == true){ - //this.mpris2_root.Raise.begin(); - } - } + public void expose() + { + if(this.connected() == true){ + this.mpris2_root.Raise.begin(); + } + } } diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index 7e41b5f..1cf8baa 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -34,7 +34,7 @@ public class Mpris2Watcher : GLib.Object FreeDesktopObject fdesktop_obj; public signal void client_appeared ( string desktop_name ); - public signal void client_disappeared ( string desktop_name ); + public signal void client_disappeared ( string mpris_root_interface ); public Mpris2Watcher () { @@ -72,11 +72,11 @@ public class Mpris2Watcher : GLib.Object return; } if (previous_owner != "" && current_owner == "") { - debug ("Service '%s' going down", name); - client_disappeared (mpris2_root.DesktopEntry); + debug ("Client '%s' gone down", name); + client_disappeared (name); } else if (previous_owner == "" && current_owner != "") { - debug ("Service '%s' has appeared", name); + debug ("Client '%s' has appeared", name); client_appeared (mpris2_root.DesktopEntry); } } diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index c905c12..d1c2334 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -114,19 +114,18 @@ public class MusicPlayerBridge : GLib.Object } } - /*public void on_server_removed(Indicate.ListenerServer object, string type) + public void client_has_vanished ( string mpris_root_interface ) { - debug("MusicPlayerBridge -> on_server_removed with value %s", type); - if(server_is_not_of_interest(type)) return; - if (root_menu != null){ - var tmp = type.split("."); - debug("attempt to remove %s", tmp[tmp.length-1]); - if(tmp.length > 0){ - registered_clients[tmp[tmp.length - 1]].hibernate(); - debug("Successively offlined client %s", tmp[tmp.length - 1]); + debug("MusicPlayerBridge -> on_server_removed with value %s", mpris_root_interface); + if (root_menu != null){ + debug("attempt to remove %s", mpris_root_interface); + var mpris_key = determine_key ( mpris_root_interface ); + if ( mpris_key != null ){ + registered_clients[mpris_key].hibernate(); + debug("Successively offlined client %s", mpris_key); } - } - }*/ + } + } public void set_root_menu_item(Dbusmenu.Menuitem menu) { @@ -134,7 +133,7 @@ public class MusicPlayerBridge : GLib.Object this.try_to_add_inactive_familiar_clients(); this.watcher = new Mpris2Watcher (); this.watcher.client_appeared += this.client_has_become_available; - //this.watcher.client_appeared += this.client_has_become_available; + this.watcher.client_disappeared += this.client_has_vanished; } public static AppInfo? create_app_info ( string path ) @@ -150,8 +149,15 @@ public class MusicPlayerBridge : GLib.Object private static string? determine_key(owned string path) { - var tokens = path.split("/"); - if ( tokens.length < 2) return null; + var tokens = path.split( "/" ); + if ( tokens.length < 2 ){ + // try to split on "." + tokens = path.split("."); + if ( tokens.length < 2 ){ + // don't know what this is + return null; + } + } var filename = tokens[tokens.length - 1]; var result = filename.split(".")[0]; var temp = result.split("-"); -- cgit v1.2.3 From 1d73614b6c2789d11c7e63efcd22634015aff737 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Mon, 6 Dec 2010 15:36:19 +0000 Subject: tidy up for merge --- src/mpris2-controller.vala | 7 +------ src/sound-service.c | 5 ++--- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index ff19598..3adaad6 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -16,7 +16,6 @@ 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 DBus; using Dbusmenu; @@ -106,7 +105,6 @@ public class Mpris2Controller : GLib.Object changed_updates.replace("mpris:length", duration/1000000); } return changed_updates; - //return null; } private TransportMenuitem.state determine_play_state(string? status){ @@ -156,7 +154,4 @@ public class Mpris2Controller : GLib.Object this.mpris2_root.Raise.begin(); } } -} - - - +} \ No newline at end of file diff --git a/src/sound-service.c b/src/sound-service.c index 51f5f37..98f1881 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,9 +40,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; } -- cgit v1.2.3 From 4061f2bed3ed22262305c19e534f1007f7febbe9 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Mon, 6 Dec 2010 17:31:10 +0000 Subject: string updates working properly now --- src/mpris2-controller.vala | 4 ++-- src/player-item.vala | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 3adaad6..87f0307 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -94,10 +94,10 @@ public class Mpris2Controller : GLib.Object GLib.HashTable changed_updates = this.player.Metadata; Variant? artist_v = this.player.Metadata.lookup("xesam:artist"); if(artist_v != null){ - string[] artists = (string[])this.player.Metadata.lookup("xesam:artist"); + string[] artists = (string[])this.player.Metadata.lookup("xesam:artist"); string display_artists = string.joinv(", ", artists); changed_updates.replace("xesam:artist", display_artists); - debug("artist : %s", display_artists); + debug("artist : %s", (string)changed_updates.lookup("xesam:artist")); } Variant? length_v = this.player.Metadata.lookup("mpris:length"); if(length_v != null){ diff --git a/src/player-item.vala b/src/player-item.vala index 51471d1..54d0d89 100644 --- a/src/player-item.vala +++ b/src/player-item.vala @@ -48,7 +48,7 @@ public class PlayerItem : Dbusmenu.Menuitem * and attmepts to update the appropriate props on the object. * Album art is handled separately to deal with remote and local file paths. */ - public void update(HashTable data, HashSet attributes) + public void update(HashTable data, HashSet attributes) { debug("PlayerItem::update()"); if(data == null){ @@ -60,29 +60,29 @@ public class PlayerItem : Dbusmenu.Menuitem string[] input_keys = property.split("-"); string search_key = input_keys[input_keys.length-1 : input_keys.length][0]; debug("search key = %s", search_key); - Value? v = data.lookup(search_key); + Variant? v = data.lookup(search_key); - if (v.holds (typeof (string))){ + if (v.is_of_type ( VariantType.STRING )){ string update = v.get_string().strip(); debug("with value : %s", update); if(property.contains("mpris:artUrl")){ // We know its a metadata instance because thats the only // object with the arturl prop MetadataMenuitem metadata = this as MetadataMenuitem; - metadata.fetch_art(update.strip(), property); - continue; + metadata.fetch_art ( update, property ); + continue; } this.property_set(property, update); } - else if (v.holds (typeof (int))){ - debug("with value : %i", v.get_int()); - this.property_set_int(property, v.get_int()); + else if (v.is_of_type (VariantType.INT32 )){ + debug("with value : %i", v.get_int32()); + this.property_set_int(property, v.get_int32()); } - else if (v.holds (typeof (int64))){ + else if (v.is_of_type (VariantType.INT64 )){ debug("with value : %i", (int)v.get_int64()); this.property_set_int(property, (int)v.get_int64()); } - else if(v.holds (typeof (bool))){ + else if(v.is_of_type ( VariantType.BOOLEAN )){ debug("with value : %s", v.get_boolean().to_string()); this.property_set_bool(property, v.get_boolean()); } -- cgit v1.2.3 From 55b5ef4065d32cca71b745c8dc4790e1b71af0fd Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 7 Dec 2010 14:18:28 +0000 Subject: tabs to spaces tab width 2 --- src/common-defs.h | 46 +- src/dbus-menu-manager.c | 4 +- src/familiar-players-db.vala | 240 ++--- src/fetch-file.vala | 6 +- src/indicator-sound.c | 148 +-- src/metadata-menu-item.vala | 212 ++-- src/metadata-widget.c | 430 ++++---- src/metadata-widget.h | 4 +- src/mpris2-controller.vala | 30 +- src/mpris2-interfaces.vala | 38 +- src/music-player-bridge.vala | 14 +- src/player-controller.vala | 296 ++--- src/player-item.vala | 154 +-- src/pulse-manager.c | 22 +- src/scrub-menu-item.vala | 60 +- src/scrub-widget.c | 374 +++---- src/scrub-widget.h | 6 +- src/slider-menu-item.c | 4 +- src/title-menu-item.vala | 60 +- src/title-widget.c | 146 +-- src/title-widget.h | 4 +- src/transport-menu-item.vala | 64 +- src/transport-widget.c | 2436 +++++++++++++++++++++--------------------- src/transport-widget.h | 22 +- src/volume-widget.c | 164 +-- src/volume-widget.h | 6 +- 26 files changed, 2495 insertions(+), 2495 deletions(-) diff --git a/src/common-defs.h b/src/common-defs.h index 27dfd32..214f60a 100644 --- a/src/common-defs.h +++ b/src/common-defs.h @@ -19,33 +19,33 @@ with this program. If not, see . /* constants used for signals on the dbus. This file is shared between client and server implementation */ -#define SIGNAL_SINK_INPUT_WHILE_MUTED "SinkInputWhileMuted" -#define SIGNAL_SINK_VOLUME_UPDATE "SinkVolumeUpdate" -#define SIGNAL_SINK_MUTE_UPDATE "SinkMuteUpdate" -#define SIGNAL_SINK_AVAILABLE_UPDATE "SinkAvailableUpdate" +#define SIGNAL_SINK_INPUT_WHILE_MUTED "SinkInputWhileMuted" +#define SIGNAL_SINK_VOLUME_UPDATE "SinkVolumeUpdate" +#define SIGNAL_SINK_MUTE_UPDATE "SinkMuteUpdate" +#define SIGNAL_SINK_AVAILABLE_UPDATE "SinkAvailableUpdate" -#define DBUSMENU_PROPERTY_EMPTY -1 +#define DBUSMENU_PROPERTY_EMPTY -1 /* DBUS Custom Items */ -#define DBUSMENU_VOLUME_MENUITEM_TYPE "x-canonical-ido-volume-type" -#define DBUSMENU_VOLUME_MENUITEM_LEVEL "x-canonical-ido-volume-level" +#define DBUSMENU_VOLUME_MENUITEM_TYPE "x-canonical-ido-volume-type" +#define DBUSMENU_VOLUME_MENUITEM_LEVEL "x-canonical-ido-volume-level" -#define DBUSMENU_TRANSPORT_MENUITEM_TYPE "x-canonical-sound-menu-player-transport-type" +#define DBUSMENU_TRANSPORT_MENUITEM_TYPE "x-canonical-sound-menu-player-transport-type" #define DBUSMENU_TRANSPORT_MENUITEM_PLAY_STATE "x-canonical-sound-menu-player-transport-state" -#define DBUSMENU_METADATA_MENUITEM_TYPE "x-canonical-sound-menu-player-metadata-type" -#define DBUSMENU_METADATA_MENUITEM_ARTIST "x-canonical-sound-menu-player-metadata-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_SCRUB_MENUITEM_TYPE "x-canonical-sound-menu-player-scrub-type" -#define DBUSMENU_SCRUB_MENUITEM_DURATION "x-canonical-sound-menu-player-scrub-mpris:length" -#define DBUSMENU_SCRUB_MENUITEM_POSITION "x-canonical-sound-menu-player-scrub-position" -#define DBUSMENU_SCRUB_MENUITEM_PLAY_STATE "x-canonical-sound-menu-player-scrub-play-state" +#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_SCRUB_MENUITEM_TYPE "x-canonical-sound-menu-player-scrub-type" +#define DBUSMENU_SCRUB_MENUITEM_DURATION "x-canonical-sound-menu-player-scrub-mpris:length" +#define DBUSMENU_SCRUB_MENUITEM_POSITION "x-canonical-sound-menu-player-scrub-position" +#define DBUSMENU_SCRUB_MENUITEM_PLAY_STATE "x-canonical-sound-menu-player-scrub-play-state" diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 63e91b4..37e1c18 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -82,7 +82,7 @@ void dbus_menu_manager_update_volume(gdouble volume) GValue value = {0}; g_value_init(&value, G_TYPE_DOUBLE); g_value_set_double(&value, volume); - dbusmenu_menuitem_property_set_value(DBUSMENU_MENUITEM(volume_slider_menuitem), DBUSMENU_VOLUME_MENUITEM_LEVEL, &value); + dbusmenu_menuitem_property_set_value(DBUSMENU_MENUITEM(volume_slider_menuitem), DBUSMENU_VOLUME_MENUITEM_LEVEL, &value); } @@ -106,7 +106,7 @@ void dbus_menu_manager_update_pa_state(gboolean pa_state, gboolean sink_availabl // Emit the signals after the menus are setup/torn down // preserve ordering ! sound_service_dbus_update_sink_availability(dbus_interface, sink_available); - dbus_menu_manager_update_volume(percent); + dbus_menu_manager_update_volume(percent); sound_service_dbus_update_sink_mute(dbus_interface, sink_muted); dbus_menu_manager_update_mute_ui(b_all_muted); } diff --git a/src/familiar-players-db.vala b/src/familiar-players-db.vala index 47ddc70..7012b5a 100644 --- a/src/familiar-players-db.vala +++ b/src/familiar-players-db.vala @@ -27,138 +27,138 @@ using GLib.Environment; // TODO: more refactoring needed here public class FamiliarPlayersDB : GLib.Object { - private const string GROUP_NAME = "Seen Database"; - private const string KEY_NAME = "DesktopFiles"; + private const string GROUP_NAME = "Seen Database"; + private const string KEY_NAME = "DesktopFiles"; private const string DEFAULT_APP_DESKTOP = "/usr/share/applications/banshee-1.desktop"; - private HashMap players_DB; - private string file_name; - private string dir_name; - private KeyFile key_file; - private uint write_id; - - public FamiliarPlayersDB() - { - this.write_id = 0; - this.players_DB = new HashMap(); + private HashMap players_DB; + private string file_name; + private string dir_name; + private KeyFile key_file; + private uint write_id; + + public FamiliarPlayersDB() + { + this.write_id = 0; + this.players_DB = new HashMap(); if ( !create_key_file() ){ this.players_DB.set(DEFAULT_APP_DESKTOP, true); this.write_db(); } - this.dir_name = build_filename(get_user_cache_dir(), "indicators", "sound"); - this.file_name = build_filename(this.dir_name, "familiar-players-db.keyfile"); - if(create_key_file() && check_for_keys() && load_data_from_key_file()){ - debug("keyfiles in place and ready for action"); - } - else{ - this.key_file = null; - warning("FamiliarPlayersDB:: problems loading key file - can't go any further"); - } - } + this.dir_name = build_filename(get_user_cache_dir(), "indicators", "sound"); + this.file_name = build_filename(this.dir_name, "familiar-players-db.keyfile"); + if(create_key_file() && check_for_keys() && load_data_from_key_file()){ + debug("keyfiles in place and ready for action"); + } + else{ + this.key_file = null; + warning("FamiliarPlayersDB:: problems loading key file - can't go any further"); + } + } - private bool create_key_file(){ - bool result = false; - if (test(this.file_name, GLib.FileTest.EXISTS)) { - this.key_file = new KeyFile(); - try{ - result = this.key_file.load_from_file(this.file_name, KeyFileFlags.NONE); - } - catch(GLib.KeyFileError e){ - warning("FamiliarPlayersDB::create_key_file() - KeyFileError"); - } - catch(GLib.FileError e){ - warning("FamiliarPlayersDB::create_key_file() - FileError"); - } - } - return result; - } + private bool create_key_file(){ + bool result = false; + if (test(this.file_name, GLib.FileTest.EXISTS)) { + this.key_file = new KeyFile(); + try{ + result = this.key_file.load_from_file(this.file_name, KeyFileFlags.NONE); + } + catch(GLib.KeyFileError e){ + warning("FamiliarPlayersDB::create_key_file() - KeyFileError"); + } + catch(GLib.FileError e){ + warning("FamiliarPlayersDB::create_key_file() - FileError"); + } + } + return result; + } - private bool check_for_keys(){ - try{ - if(this.key_file.has_key(GROUP_NAME, KEY_NAME) == true){ - return true; - } - } - catch(KeyFileError e){ - return false; - } - warning("Seen DB '%s' does not have key '%s' in group '%s'", this.file_name, KEY_NAME, GROUP_NAME); - return false; - } - - private bool load_data_from_key_file(){ - try{ - string[] desktops = this.key_file.get_string_list(GROUP_NAME, - KEY_NAME); - foreach(string s in desktops){ - this.players_DB.set(s, true); - } - return true; - } - catch(GLib.KeyFileError error){ - warning("Error loading the Desktop string list"); - return false; - } - } + private bool check_for_keys(){ + try{ + if(this.key_file.has_key(GROUP_NAME, KEY_NAME) == true){ + return true; + } + } + catch(KeyFileError e){ + return false; + } + warning("Seen DB '%s' does not have key '%s' in group '%s'", this.file_name, KEY_NAME, GROUP_NAME); + return false; + } + + private bool load_data_from_key_file(){ + try{ + string[] desktops = this.key_file.get_string_list(GROUP_NAME, + KEY_NAME); + foreach(string s in desktops){ + this.players_DB.set(s, true); + } + return true; + } + catch(GLib.KeyFileError error){ + warning("Error loading the Desktop string list"); + return false; + } + } - private bool write_db() - { - KeyFile keyfile = new KeyFile(); - string[] desktops = {}; - foreach(string key in this.players_DB.keys){ - desktops += key; - } - keyfile.set_string_list(GROUP_NAME, - KEY_NAME, - desktops); - size_t data_length; - string data = null; - try{ - data = keyfile.to_data(out data_length); - } - catch(GLib.KeyFileError e){ - warning("Problems dumping keyfile to a string"); - return false; - } - - if(create_with_parents(this.dir_name, 0700) != 0){ - warning("Unable to make directory: %s", this.dir_name); - return false; - } + private bool write_db() + { + KeyFile keyfile = new KeyFile(); + string[] desktops = {}; + foreach(string key in this.players_DB.keys){ + desktops += key; + } + keyfile.set_string_list(GROUP_NAME, + KEY_NAME, + desktops); + size_t data_length; + string data = null; + try{ + data = keyfile.to_data(out data_length); + } + catch(GLib.KeyFileError e){ + warning("Problems dumping keyfile to a string"); + return false; + } + + if(create_with_parents(this.dir_name, 0700) != 0){ + warning("Unable to make directory: %s", this.dir_name); + return false; + } - try{ - if(set_contents(this.file_name, data, (ssize_t)data_length) == false){ - warning("Unable to write out file '%s'", this.file_name); - } - } - catch(FileError err){ - warning("Unable to write out file '%s'", this.file_name); - } - return true; - } + try{ + if(set_contents(this.file_name, data, (ssize_t)data_length) == false){ + warning("Unable to write out file '%s'", this.file_name); + } + } + catch(FileError err){ + warning("Unable to write out file '%s'", this.file_name); + } + return true; + } - public void insert(string desktop) - { - if(already_familiar(desktop) == false){ - if(this.write_id != 0){ - Source.remove(this.write_id); - this.write_id = 0; - } - this.write_id = Timeout.add_seconds(60, write_db); - this.players_DB.set(desktop.dup(), true); - } - } - - public bool already_familiar(string desktop) - { - debug("playerDB->already_familiar - result %s", this.players_DB.keys.contains(desktop).to_string()); - return this.players_DB.keys.contains(desktop); - } + public void insert(string desktop) + { + if(already_familiar(desktop) == false){ + if(this.write_id != 0){ + Source.remove(this.write_id); + this.write_id = 0; + } + this.write_id = Timeout.add_seconds(60, write_db); + this.players_DB.set(desktop.dup(), true); + } + } + + public bool already_familiar(string desktop) + { + debug("playerDB->already_familiar - result %s", this.players_DB.keys.contains(desktop).to_string()); + return this.players_DB.keys.contains(desktop); + } - public Gee.Set records() - { - return this.players_DB.keys; - } + public Gee.Set records() + { + return this.players_DB.keys; + } public static string? fetch_icon_name(string desktop_path) { diff --git a/src/fetch-file.vala b/src/fetch-file.vala index e6fc11d..e94afef 100644 --- a/src/fetch-file.vala +++ b/src/fetch-file.vala @@ -15,15 +15,15 @@ * . * * Authors - * Gordon Allott - * Conor Curran + * Gordon Allott + * Conor Curran */ public class FetchFile : Object { /* public variables */ public string uri {get; construct;} - public string intended_property {get; construct;} + public string intended_property {get; construct;} /* private variables */ private DataInputStream stream; diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 7797f49..d5cc54c 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -46,7 +46,7 @@ typedef struct _IndicatorSoundPrivate IndicatorSoundPrivate; struct _IndicatorSoundPrivate { - GtkWidget* volume_widget; + GtkWidget* volume_widget; GList* transport_widgets_list; }; @@ -67,7 +67,7 @@ G_DEFINE_TYPE (IndicatorSound, indicator_sound, INDICATOR_OBJECT_TYPE); static GtkLabel * get_label (IndicatorObject * io); static GtkImage * get_icon (IndicatorObject * io); static GtkMenu * get_menu (IndicatorObject * io); -static void indicator_sound_scroll (IndicatorObject* io, gint delta, IndicatorScrollDirection direction); +static void indicator_sound_scroll (IndicatorObject* io, gint delta, IndicatorScrollDirection direction); //Slider related static gboolean new_volume_slider_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); @@ -131,8 +131,8 @@ indicator_sound_class_init (IndicatorSoundClass *klass) IndicatorObjectClass *io_class = INDICATOR_OBJECT_CLASS(klass); - g_type_class_add_private (klass, sizeof (IndicatorSoundPrivate)); - + g_type_class_add_private (klass, sizeof (IndicatorSoundPrivate)); + io_class->get_label = get_label; io_class->get_image = get_icon; io_class->get_menu = get_menu; @@ -153,13 +153,13 @@ indicator_sound_init (IndicatorSound *self) blocked_id = 0; initial_mute = FALSE; device_available = TRUE; - - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self); - priv->volume_widget = NULL; + + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self); + priv->volume_widget = NULL; GList* t_list = NULL; priv->transport_widgets_list = t_list; - g_signal_connect(G_OBJECT(self->service), + g_signal_connect(G_OBJECT(self->service), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection_changed), self); return; @@ -178,7 +178,7 @@ indicator_sound_dispose (GObject *object) free_the_animation_list(); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (self)); + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (self)); g_list_free ( priv->transport_widgets_list ); @@ -204,7 +204,7 @@ static GtkImage * get_icon (IndicatorObject * io) { gchar* current_name = g_hash_table_lookup(volume_states, - GINT_TO_POINTER(current_state)); + GINT_TO_POINTER(current_state)); //g_debug("At start-up attempting to set the image to %s", // current_name); speaker_image = indicator_image_helper(current_name); @@ -220,18 +220,18 @@ static GtkMenu * get_menu (IndicatorObject * io) { DbusmenuGtkMenu* menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT); - + DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu); g_object_set_data (G_OBJECT (client), "indicator", io); dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_VOLUME_MENUITEM_TYPE, new_volume_slider_widget); 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. + // 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), io); g_signal_connect(menu, "key-release-event", G_CALLBACK(key_release_cb), io); - return GTK_MENU(menu); + return GTK_MENU(menu); } static void @@ -256,13 +256,13 @@ new_transport_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbus g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); bar = transport_widget_new(newitem); - io = g_object_get_data (G_OBJECT (client), "indicator"); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); + io = g_object_get_data (G_OBJECT (client), "indicator"); + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); priv->transport_widgets_list = g_list_append ( priv->transport_widgets_list, bar ); GtkMenuItem *menu_transport_bar = GTK_MENU_ITEM(bar); - gtk_widget_show_all(bar); + gtk_widget_show_all(bar); dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_transport_bar, parent); return TRUE; @@ -281,7 +281,7 @@ new_metadata_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbusm metadata = metadata_widget_new (newitem); GtkMenuItem *menu_metadata_widget = GTK_MENU_ITEM(metadata); - gtk_widget_show_all(metadata); + gtk_widget_show_all(metadata); dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_metadata_widget, parent); return TRUE; @@ -290,22 +290,22 @@ new_metadata_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbusm static gboolean new_title_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) { - //g_debug("indicator-sound: new_title_widget"); + //g_debug("indicator-sound: new_title_widget"); 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)); + //g_debug ("%s (\"%s\")", __func__, dbusmenu_menuitem_property_get(newitem, DBUSMENU_TITLE_MENUITEM_NAME)); - GtkWidget* title = NULL; + 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); + dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), + newitem, + menu_title_widget, parent); return TRUE; } @@ -320,27 +320,27 @@ new_volume_slider_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); - volume_widget = volume_widget_new (newitem); - io = g_object_get_data (G_OBJECT (client), "indicator"); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); + volume_widget = volume_widget_new (newitem); + io = g_object_get_data (G_OBJECT (client), "indicator"); + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); priv->volume_widget = volume_widget; - GtkWidget* ido_slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); + GtkWidget* ido_slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); - g_signal_connect(ido_slider_widget, "style-set", G_CALLBACK(style_changed_cb), NULL); - gtk_widget_set_sensitive(ido_slider_widget, - !initial_mute); - gtk_widget_show_all(ido_slider_widget); + g_signal_connect(ido_slider_widget, "style-set", G_CALLBACK(style_changed_cb), NULL); + gtk_widget_set_sensitive(ido_slider_widget, + !initial_mute); + gtk_widget_show_all(ido_slider_widget); - + GtkMenuItem *menu_volume_item = GTK_MENU_ITEM(ido_slider_widget); - dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), - newitem, - menu_volume_item, - parent); + dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), + newitem, + menu_volume_item, + parent); fetch_mute_value_from_dbus(); fetch_sink_availability_from_dbus(INDICATOR_SOUND (io)); - return TRUE; + return TRUE; } @@ -374,14 +374,14 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID); dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_CALLBACK(catch_signal_sink_mute_update), user_data, NULL); dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_CALLBACK(catch_signal_sink_availability_update), NULL, NULL); + dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_CALLBACK(catch_signal_sink_availability_update), NULL, NULL); if( service_restart == TRUE){ fetch_mute_value_from_dbus(); // Ensure UI is in sync with service again. IndicatorSound* indicator = INDICATOR_SOUND(user_data); fetch_sink_availability_from_dbus(indicator); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); if(priv->volume_widget != NULL){ determine_state_from_volume (volume_widget_get_current_volume(priv->volume_widget)); } @@ -390,7 +390,7 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u else{ g_warning("Indicator has been disconnected from the service -> SHOCK HORROR"); IndicatorSound* indicator = INDICATOR_SOUND(user_data); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); if(priv->volume_widget != NULL){ g_warning("indicator still has a slider, service must have crashed"); @@ -556,8 +556,8 @@ reset_mute_blocking_animation() static void fetch_sink_availability_from_dbus(IndicatorSound* self) { - g_return_if_fail(IS_INDICATOR_SOUND(self)); - + g_return_if_fail(IS_INDICATOR_SOUND(self)); + GError * error = NULL; gboolean * available_input; available_input = g_new0(gboolean, 1); @@ -568,17 +568,17 @@ fetch_sink_availability_from_dbus(IndicatorSound* self) g_free(available_input); return; } - + device_available = *available_input; if (device_available == FALSE) { update_state(STATE_SINKS_NONE); //g_debug("NO DEVICE AVAILABLE"); } - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self); + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self); if(priv->volume_widget != NULL){ - GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); + GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); gtk_widget_set_sensitive(slider_widget, device_available); } @@ -635,14 +635,14 @@ catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer u reset_mute_blocking_animation(); } //g_debug("signal caught - sink mute update with mute value: %i", mute_value); - g_return_if_fail(IS_INDICATOR_SOUND(userdata)); - IndicatorSound* indicator = INDICATOR_SOUND(userdata); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); - - if(priv->volume_widget == NULL){ - return; - } - GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); + g_return_if_fail(IS_INDICATOR_SOUND(userdata)); + IndicatorSound* indicator = INDICATOR_SOUND(userdata); + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); + + if(priv->volume_widget == NULL){ + return; + } + GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); gtk_widget_set_sensitive(slider_widget, !mute_value); } @@ -669,16 +669,16 @@ key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data) { gboolean digested = FALSE; - g_return_val_if_fail(IS_INDICATOR_SOUND(data), FALSE); + g_return_val_if_fail(IS_INDICATOR_SOUND(data), FALSE); - IndicatorSound *indicator = INDICATOR_SOUND (data); + IndicatorSound *indicator = INDICATOR_SOUND (data); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); - if(priv->volume_widget == NULL){ - return FALSE; - } - - GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); + if(priv->volume_widget == NULL){ + return FALSE; + } + + GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)slider_widget); GtkRange* range = (GtkRange*)slider; g_return_val_if_fail(GTK_IS_RANGE(range), FALSE); @@ -720,7 +720,7 @@ key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data) new_value = CLAMP(new_value, 0, 100); if (new_value != current_value && current_state != STATE_MUTED) { //g_debug("Attempting to set the range from the key listener to %f", new_value); - volume_widget_update(VOLUME_WIDGET(priv->volume_widget), new_value); + volume_widget_update(VOLUME_WIDGET(priv->volume_widget), new_value); } } else if (IS_TRANSPORT_WIDGET(menuitem) == TRUE) { @@ -769,11 +769,11 @@ key_release_cb(GtkWidget* widget, GdkEventKey* event, gpointer data) { gboolean digested = FALSE; - g_return_val_if_fail(IS_INDICATOR_SOUND(data), FALSE); + g_return_val_if_fail(IS_INDICATOR_SOUND(data), FALSE); - IndicatorSound *indicator = INDICATOR_SOUND (data); + IndicatorSound *indicator = INDICATOR_SOUND (data); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); GtkWidget *menuitem; @@ -829,25 +829,25 @@ style_changed_cb(GtkWidget *widget, gpointer user_data) static void indicator_sound_scroll (IndicatorObject *io, gint delta, IndicatorScrollDirection direction) { - //g_debug("indicator-sound-scroll - current slider value"); + //g_debug("indicator-sound-scroll - current slider value"); - if (device_available == FALSE || current_state == STATE_MUTED) + if (device_available == FALSE || current_state == STATE_MUTED) return; - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); - - GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); + + GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)slider_widget); GtkRange* range = (GtkRange*)slider; g_return_if_fail(GTK_IS_RANGE(range)); gdouble value = gtk_range_get_value(range); GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (slider)); - //g_debug("indicator-sound-scroll - current slider value %f", value); + //g_debug("indicator-sound-scroll - current slider value %f", value); if (direction == INDICATOR_OBJECT_SCROLL_UP) { value += adj->step_increment; } else { value -= adj->step_increment; } - //g_debug("indicator-sound-scroll - update slider with value %f", value); - volume_widget_update(VOLUME_WIDGET(priv->volume_widget), value); + //g_debug("indicator-sound-scroll - update slider with value %f", value); + volume_widget_update(VOLUME_WIDGET(priv->volume_widget), value); } diff --git a/src/metadata-menu-item.vala b/src/metadata-menu-item.vala index c9ab4dd..e84e902 100644 --- a/src/metadata-menu-item.vala +++ b/src/metadata-menu-item.vala @@ -23,48 +23,48 @@ using Gdk; public class MetadataMenuitem : PlayerItem { - public const string ALBUM_ART_DIR_SUFFIX = "indicators/sound/album-art-cache"; - - public static string album_art_cache_dir; - private static FetchFile fetcher; - private string previous_temp_album_art_path; - - public MetadataMenuitem() + public const string ALBUM_ART_DIR_SUFFIX = "indicators/sound/album-art-cache"; + + public static string album_art_cache_dir; + private static FetchFile fetcher; + private string previous_temp_album_art_path; + + public MetadataMenuitem() { - Object(item_type: MENUITEM_TYPE); - reset(attributes_format()); - } - - construct{ - MetadataMenuitem.clean_album_art_temp_dir(); - this.previous_temp_album_art_path = null; - this.album_art_cache_dir = MetadataMenuitem.create_album_art_temp_dir(); - } + Object(item_type: MENUITEM_TYPE); + reset(attributes_format()); + } + + construct{ + MetadataMenuitem.clean_album_art_temp_dir(); + this.previous_temp_album_art_path = null; + this.album_art_cache_dir = MetadataMenuitem.create_album_art_temp_dir(); + } - private static void clean_album_art_temp_dir() - { - string path = GLib.Path.build_filename(Environment.get_user_cache_dir(), ALBUM_ART_DIR_SUFFIX); + private static void clean_album_art_temp_dir() + { + string path = GLib.Path.build_filename(Environment.get_user_cache_dir(), ALBUM_ART_DIR_SUFFIX); - GLib.File? album_art_dir = GLib.File.new_for_path(path); - - if(delete_album_art_contents(album_art_dir) == false) - { - warning("could not remove the temp album art files %s", path); - } - } + GLib.File? album_art_dir = GLib.File.new_for_path(path); + + if(delete_album_art_contents(album_art_dir) == false) + { + warning("could not remove the temp album art files %s", path); + } + } - private static string? create_album_art_temp_dir() - { - string path = GLib.Path.build_filename(Environment.get_user_cache_dir(), ALBUM_ART_DIR_SUFFIX); - if(DirUtils.create(path, 0700) == -1){ - warning("could not create a temp dir for remote album art, it must have been created already"); - } - return path; - } - - private static bool delete_album_art_contents (GLib.File dir) + private static string? create_album_art_temp_dir() + { + string path = GLib.Path.build_filename(Environment.get_user_cache_dir(), ALBUM_ART_DIR_SUFFIX); + if(DirUtils.create(path, 0700) == -1){ + warning("could not create a temp dir for remote album art, it must have been created already"); + } + return path; + } + + private static bool delete_album_art_contents (GLib.File dir) { - bool result = true; + bool result = true; try { var e = dir.enumerate_children (FILE_ATTRIBUTE_STANDARD_NAME, FileQueryInfoFlags.NOFOLLOW_SYMLINKS, @@ -73,9 +73,9 @@ public class MetadataMenuitem : PlayerItem { var file = e.next_file (null); - debug("file name = %s", file.get_name()); - - if (file == null) + debug("file name = %s", file.get_name()); + + if (file == null) break; var child = dir.get_child (file.get_name ()); @@ -84,82 +84,82 @@ public class MetadataMenuitem : PlayerItem child.delete (null); } catch (Error error_) { warning (@"Unable to delete file '$(child.get_basename ()): $(error_.message)"); - result = false; + result = false; } } } catch (Error error) { warning (@"Unable to read files from directory '$(dir.get_basename ())': %s", error.message); - result = false; + result = false; } - return result; + return result; } - public void fetch_art(string uri, string prop) - { - File art_file = File.new_for_uri(uri); - if(art_file.is_native() == true){ - string path; - try{ - path = Filename.from_uri(uri.strip()); - this.property_set(prop, path); - } - catch(ConvertError e){ - warning("Problem converting URI %s to file path", - uri); - } - // eitherway return, the artwork was local - return; - } - debug("fetch_art -remotely %s", this.album_art_cache_dir); - // If we didn't manage to create the temp dir - // don't bother with remote - if(this.album_art_cache_dir == null){ - return; - } - // green light to go remote - this.fetcher = new FetchFile (uri, prop); - this.fetcher.failed.connect (() => { this.on_fetcher_failed ();}); - this.fetcher.completed.connect (this.on_fetcher_completed); - this.fetcher.fetch_data (); - } - - private void on_fetcher_failed () - { - warning("on_fetcher_failed -> could not fetch artwork"); - } + public void fetch_art(string uri, string prop) + { + File art_file = File.new_for_uri(uri); + if(art_file.is_native() == true){ + string path; + try{ + path = Filename.from_uri(uri.strip()); + this.property_set(prop, path); + } + catch(ConvertError e){ + warning("Problem converting URI %s to file path", + uri); + } + // eitherway return, the artwork was local + return; + } + debug("fetch_art -remotely %s", this.album_art_cache_dir); + // If we didn't manage to create the temp dir + // don't bother with remote + if(this.album_art_cache_dir == null){ + return; + } + // green light to go remote + this.fetcher = new FetchFile (uri, prop); + this.fetcher.failed.connect (() => { this.on_fetcher_failed ();}); + this.fetcher.completed.connect (this.on_fetcher_completed); + this.fetcher.fetch_data (); + } + + private void on_fetcher_failed () + { + warning("on_fetcher_failed -> could not fetch artwork"); + } - private void on_fetcher_completed(ByteArray update, string property) - { - try{ - PixbufLoader loader = new PixbufLoader (); - loader.write (update.data); - loader.close (); - Pixbuf icon = loader.get_pixbuf (); - string path = this.album_art_cache_dir.concat("/downloaded-coverart-XXXXXX"); - int r = FileUtils.mkstemp(path); - if(r != -1){ - icon.save (path, loader.get_format().get_name()); - this.property_set(property, path); - if(this.previous_temp_album_art_path != null){ - FileUtils.remove(this.previous_temp_album_art_path); - } - this.previous_temp_album_art_path = path; - } - } - catch(GLib.Error e){ - warning("Problem creating file from bytearray fetched from the interweb - error: %s", - e.message); - } - } - - public static HashSet attributes_format() - { - HashSet attrs = new HashSet(); - attrs.add(MENUITEM_TITLE); + private void on_fetcher_completed(ByteArray update, string property) + { + try{ + PixbufLoader loader = new PixbufLoader (); + loader.write (update.data); + loader.close (); + Pixbuf icon = loader.get_pixbuf (); + string path = this.album_art_cache_dir.concat("/downloaded-coverart-XXXXXX"); + int r = FileUtils.mkstemp(path); + if(r != -1){ + icon.save (path, loader.get_format().get_name()); + this.property_set(property, path); + if(this.previous_temp_album_art_path != null){ + FileUtils.remove(this.previous_temp_album_art_path); + } + this.previous_temp_album_art_path = path; + } + } + catch(GLib.Error e){ + warning("Problem creating file from bytearray fetched from the interweb - error: %s", + e.message); + } + } + + public static HashSet attributes_format() + { + HashSet attrs = new HashSet(); + attrs.add(MENUITEM_TITLE); attrs.add(MENUITEM_ARTIST); attrs.add(MENUITEM_ALBUM); attrs.add(MENUITEM_ARTURL); - return attrs; - } + return attrs; + } } diff --git a/src/metadata-widget.c b/src/metadata-widget.c index ac8355c..1e2c891 100644 --- a/src/metadata-widget.c +++ b/src/metadata-widget.c @@ -34,14 +34,14 @@ typedef struct _MetadataWidgetPrivate MetadataWidgetPrivate; struct _MetadataWidgetPrivate { gboolean theme_change_occured; - GtkWidget* hbox; - GtkWidget* album_art; - GString* image_path; - GString* old_image_path; - GtkWidget* artist_label; - GtkWidget* piece_label; - GtkWidget* container_label; - DbusmenuMenuitem* twin_item; + GtkWidget* hbox; + GtkWidget* album_art; + GString* image_path; + GString* old_image_path; + GtkWidget* artist_label; + GtkWidget* piece_label; + GtkWidget* container_label; + DbusmenuMenuitem* twin_item; }; #define METADATA_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), METADATA_WIDGET_TYPE, MetadataWidgetPrivate)) @@ -57,11 +57,11 @@ static void metadata_widget_set_twin_item (MetadataWidget* self, DbusmenuMenuite // keyevent consumers static gboolean metadata_widget_button_press_event (GtkWidget *menuitem, - GdkEventButton *event); + GdkEventButton *event); // Dbusmenuitem properties update callback static void metadata_widget_property_update (DbusmenuMenuitem* item, gchar* property, - GValue* value, + GValue* value, gpointer userdata); static void metadata_widget_style_labels ( MetadataWidget* self, GtkLabel* label); @@ -77,105 +77,105 @@ 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); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - widget_class->button_press_event = metadata_widget_button_press_event; - - g_type_class_add_private (klass, sizeof (MetadataWidgetPrivate)); + widget_class->button_press_event = metadata_widget_button_press_event; + + g_type_class_add_private (klass, sizeof (MetadataWidgetPrivate)); - gobject_class->dispose = metadata_widget_dispose; - gobject_class->finalize = metadata_widget_finalize; + gobject_class->dispose = metadata_widget_dispose; + gobject_class->finalize = metadata_widget_finalize; } static void metadata_widget_init (MetadataWidget *self) { - //g_debug("MetadataWidget::metadata_widget_init"); + //g_debug("MetadataWidget::metadata_widget_init"); - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); - GtkWidget *hbox; + MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); + GtkWidget *hbox; - hbox = gtk_hbox_new(FALSE, 0); - priv->hbox = hbox; + hbox = gtk_hbox_new(FALSE, 0); + priv->hbox = hbox; - // image - priv->album_art = gtk_image_new(); - priv->image_path = g_string_new(dbusmenu_menuitem_property_get(priv->twin_item, + // image + priv->album_art = gtk_image_new(); + priv->image_path = g_string_new(dbusmenu_menuitem_property_get(priv->twin_item, DBUSMENU_METADATA_MENUITEM_ARTURL)); - priv->old_image_path = g_string_new(""); - + priv->old_image_path = g_string_new(""); + g_signal_connect(priv->album_art, "expose-event", G_CALLBACK(metadata_image_expose), - GTK_WIDGET(self)); - gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60); - - gtk_box_pack_start (GTK_BOX (priv->hbox), + GTK_WIDGET(self)); + gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60); + + gtk_box_pack_start (GTK_BOX (priv->hbox), priv->album_art, FALSE, FALSE, - 1); + 1); priv->theme_change_occured = FALSE; GtkWidget* vbox = gtk_vbox_new(FALSE, 0); - - // artist - GtkWidget* artist; - artist = gtk_label_new(dbusmenu_menuitem_property_get(priv->twin_item, - DBUSMENU_METADATA_MENUITEM_ARTIST)); - gtk_misc_set_alignment(GTK_MISC(artist), (gfloat)0, (gfloat)0); - gtk_misc_set_padding (GTK_MISC(artist), (gfloat)10, (gfloat)0); + + // artist + GtkWidget* artist; + artist = gtk_label_new(dbusmenu_menuitem_property_get(priv->twin_item, + DBUSMENU_METADATA_MENUITEM_ARTIST)); + gtk_misc_set_alignment(GTK_MISC(artist), (gfloat)0, (gfloat)0); + gtk_misc_set_padding (GTK_MISC(artist), (gfloat)10, (gfloat)0); gtk_widget_set_size_request (artist, 140, 15); - gtk_label_set_ellipsize(GTK_LABEL(artist), PANGO_ELLIPSIZE_MIDDLE); - metadata_widget_style_labels(self, GTK_LABEL(artist)); - priv->artist_label = artist; - - // title - GtkWidget* piece; - piece = gtk_label_new(dbusmenu_menuitem_property_get( priv->twin_item, - DBUSMENU_METADATA_MENUITEM_TITLE) ); - gtk_misc_set_alignment(GTK_MISC(piece), (gfloat)0, (gfloat)0); - gtk_misc_set_padding (GTK_MISC(piece), (gfloat)10, (gfloat)-5); + gtk_label_set_ellipsize(GTK_LABEL(artist), PANGO_ELLIPSIZE_MIDDLE); + metadata_widget_style_labels(self, GTK_LABEL(artist)); + priv->artist_label = artist; + + // title + GtkWidget* piece; + piece = gtk_label_new(dbusmenu_menuitem_property_get( priv->twin_item, + DBUSMENU_METADATA_MENUITEM_TITLE) ); + gtk_misc_set_alignment(GTK_MISC(piece), (gfloat)0, (gfloat)0); + gtk_misc_set_padding (GTK_MISC(piece), (gfloat)10, (gfloat)-5); gtk_widget_set_size_request (piece, 140, 15); gtk_label_set_ellipsize(GTK_LABEL(piece), PANGO_ELLIPSIZE_MIDDLE); - metadata_widget_style_labels(self, GTK_LABEL(piece)); - priv->piece_label = piece; - - // container - GtkWidget* container; - container = gtk_label_new(dbusmenu_menuitem_property_get( priv->twin_item, - DBUSMENU_METADATA_MENUITEM_ALBUM) ); - gtk_misc_set_alignment(GTK_MISC(container), (gfloat)0, (gfloat)0); - gtk_misc_set_padding (GTK_MISC(container), (gfloat)10, (gfloat)0); + metadata_widget_style_labels(self, GTK_LABEL(piece)); + priv->piece_label = piece; + + // container + GtkWidget* container; + container = gtk_label_new(dbusmenu_menuitem_property_get( priv->twin_item, + DBUSMENU_METADATA_MENUITEM_ALBUM) ); + gtk_misc_set_alignment(GTK_MISC(container), (gfloat)0, (gfloat)0); + gtk_misc_set_padding (GTK_MISC(container), (gfloat)10, (gfloat)0); gtk_widget_set_size_request (container, 140, 15); - gtk_label_set_ellipsize(GTK_LABEL(container), PANGO_ELLIPSIZE_MIDDLE); - metadata_widget_style_labels(self, GTK_LABEL(container)); - priv->container_label = container; + gtk_label_set_ellipsize(GTK_LABEL(container), PANGO_ELLIPSIZE_MIDDLE); + metadata_widget_style_labels(self, GTK_LABEL(container)); + priv->container_label = container; - gtk_box_pack_start (GTK_BOX (vbox), priv->piece_label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), priv->artist_label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), priv->container_label, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (priv->hbox), vbox, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), priv->piece_label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), priv->artist_label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), priv->container_label, FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX (priv->hbox), 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_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_WIDGET(self)); + gtk_widget_set_size_request(GTK_WIDGET(self), 200, 75); gtk_container_add (GTK_CONTAINER (self), hbox); } static void metadata_widget_dispose (GObject *object) { - G_OBJECT_CLASS (metadata_widget_parent_class)->dispose (object); + G_OBJECT_CLASS (metadata_widget_parent_class)->dispose (object); } static void metadata_widget_finalize (GObject *object) { - G_OBJECT_CLASS (metadata_widget_parent_class)->finalize (object); + G_OBJECT_CLASS (metadata_widget_parent_class)->finalize (object); } @@ -186,46 +186,46 @@ metadata_widget_finalize (GObject *object) static gboolean metadata_image_expose (GtkWidget *metadata, GdkEventExpose *event, 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_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); - if(priv->image_path->len > 0){ - if(g_string_equal(priv->image_path, priv->old_image_path) == 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; - GdkPixbuf* pixbuf; - pixbuf = gdk_pixbuf_new_from_file(priv->image_path->str, 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"); - draw_album_art_placeholder(metadata); - return TRUE; - } - pixbuf = gdk_pixbuf_scale_simple(pixbuf,60, 60, GDK_INTERP_BILINEAR); - gtk_image_set_from_pixbuf(GTK_IMAGE(priv->album_art), pixbuf); - g_string_erase(priv->old_image_path, 0, -1); - g_string_overwrite(priv->old_image_path, 0, priv->image_path->str); - - g_object_unref(pixbuf); - } - return FALSE; - } - draw_album_art_placeholder(metadata); - return TRUE; + GdkPixbuf* pixbuf; + pixbuf = gdk_pixbuf_new_from_file(priv->image_path->str, 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"); + draw_album_art_placeholder(metadata); + return TRUE; + } + pixbuf = gdk_pixbuf_scale_simple(pixbuf,60, 60, GDK_INTERP_BILINEAR); + gtk_image_set_from_pixbuf(GTK_IMAGE(priv->album_art), pixbuf); + g_string_erase(priv->old_image_path, 0, -1); + g_string_overwrite(priv->old_image_path, 0, priv->image_path->str); + + g_object_unref(pixbuf); + } + return FALSE; + } + draw_album_art_placeholder(metadata); + return TRUE; } static void draw_album_border(GtkWidget *metadata, gboolean selected) { - cairo_t *cr; - cr = gdk_cairo_create (metadata->window); + cairo_t *cr; + cr = gdk_cairo_create (metadata->window); GtkStyle *style; - style = gtk_widget_get_style (metadata); + style = gtk_widget_get_style (metadata); - GtkAllocation alloc; - gtk_widget_get_allocation (metadata, &alloc); + GtkAllocation alloc; + gtk_widget_get_allocation (metadata, &alloc); gint offset = 1; alloc.width = alloc.width + (offset * 2); @@ -236,14 +236,14 @@ draw_album_border(GtkWidget *metadata, gboolean selected) CairoColorRGB bg_normal, fg_normal; bg_normal.r = style->bg[0].red/65535.0; - bg_normal.g = style->bg[0].green/65535.0; - bg_normal.b = style->bg[0].blue/65535.0; + bg_normal.g = style->bg[0].green/65535.0; + bg_normal.b = style->bg[0].blue/65535.0; gint state = selected ? 5 : 0; - fg_normal.r = style->fg[state].red/65535.0; - fg_normal.g = style->fg[state].green/65535.0; - fg_normal.b = style->fg[state].blue/65535.0; + fg_normal.r = style->fg[state].red/65535.0; + fg_normal.g = style->fg[state].green/65535.0; + fg_normal.b = style->fg[state].blue/65535.0; CairoColorRGB dark_top_color; CairoColorRGB light_bottom_color; @@ -259,15 +259,15 @@ draw_album_border(GtkWidget *metadata, gboolean selected) cairo_set_line_width (cr, 1.0); - cairo_clip ( cr ); + cairo_clip ( cr ); cairo_move_to (cr, alloc.x, alloc.y ); - cairo_line_to (cr, alloc.x + alloc.width, - alloc.y ); + cairo_line_to (cr, alloc.x + alloc.width, + alloc.y ); cairo_line_to ( cr, alloc.x + alloc.width, - alloc.y + alloc.height ); - cairo_line_to ( cr, alloc.x, alloc.y + alloc.height ); - cairo_line_to ( cr, alloc.x, alloc.y); + alloc.y + alloc.height ); + cairo_line_to ( cr, alloc.x, alloc.y + alloc.height ); + cairo_line_to ( cr, alloc.x, alloc.y); cairo_close_path (cr); cairo_set_source_rgba ( cr, @@ -278,9 +278,9 @@ draw_album_border(GtkWidget *metadata, gboolean selected) cairo_fill ( cr ); - cairo_move_to (cr, alloc.x, alloc.y ); - cairo_line_to (cr, alloc.x + alloc.width, - alloc.y ); + cairo_move_to (cr, alloc.x, alloc.y ); + cairo_line_to (cr, alloc.x + alloc.width, + alloc.y ); cairo_close_path (cr); cairo_set_source_rgba ( cr, @@ -291,11 +291,11 @@ draw_album_border(GtkWidget *metadata, gboolean selected) cairo_stroke ( cr ); - cairo_move_to ( cr, alloc.x + alloc.width, - alloc.y + alloc.height ); - cairo_line_to ( cr, alloc.x, alloc.y + alloc.height ); + cairo_move_to ( cr, alloc.x + alloc.width, + alloc.y + alloc.height ); + cairo_line_to ( cr, alloc.x, alloc.y + alloc.height ); - cairo_close_path (cr); + cairo_close_path (cr); cairo_set_source_rgba ( cr, light_bottom_color.r, light_bottom_color.g, @@ -303,41 +303,41 @@ draw_album_border(GtkWidget *metadata, gboolean selected) 1.0); cairo_stroke ( cr ); - cairo_destroy (cr); + cairo_destroy (cr); } static void draw_album_art_placeholder(GtkWidget *metadata) -{ - cairo_t *cr; - cr = gdk_cairo_create (metadata->window); +{ + cairo_t *cr; + cr = gdk_cairo_create (metadata->window); GtkStyle *style; - style = gtk_widget_get_style (metadata); + style = gtk_widget_get_style (metadata); - GtkAllocation alloc; - gtk_widget_get_allocation (metadata, &alloc); + GtkAllocation alloc; + gtk_widget_get_allocation (metadata, &alloc); PangoLayout *layout; - PangoFontDescription *desc; - layout = pango_cairo_create_layout(cr); - PangoContext* pcontext = pango_cairo_create_context(cr); - pango_cairo_context_set_resolution (pcontext, 96); - - GString* string = g_string_new(""); - gssize size = -1; - gunichar code = g_utf8_get_char_validated("\342\231\253", size); - g_string_append_unichar (string, code); - - pango_layout_set_text(layout, string->str, -1); - desc = pango_font_description_from_string("Sans Bold 30"); - pango_layout_set_font_description(layout, desc); - pango_font_description_free(desc); + PangoFontDescription *desc; + layout = pango_cairo_create_layout(cr); + PangoContext* pcontext = pango_cairo_create_context(cr); + pango_cairo_context_set_resolution (pcontext, 96); + + GString* string = g_string_new(""); + gssize size = -1; + gunichar code = g_utf8_get_char_validated("\342\231\253", size); + g_string_append_unichar (string, code); + + pango_layout_set_text(layout, string->str, -1); + desc = pango_font_description_from_string("Sans Bold 30"); + pango_layout_set_font_description(layout, desc); + pango_font_description_free(desc); CairoColorRGB fg_normal, light_bottom_color; - fg_normal.r = style->fg[0].red/65535.0; - fg_normal.g = style->fg[0].green/65535.0; - fg_normal.b = style->fg[0].blue/65535.0; + fg_normal.r = style->fg[0].red/65535.0; + fg_normal.g = style->fg[0].green/65535.0; + fg_normal.b = style->fg[0].blue/65535.0; _color_shade ( &fg_normal, 0.78, &light_bottom_color ); @@ -348,14 +348,14 @@ draw_album_art_placeholder(GtkWidget *metadata) light_bottom_color.b, 1.0); - pango_cairo_update_layout(cr, layout); - cairo_move_to (cr, alloc.x + alloc.width/6, alloc.y + alloc.height/8); - pango_cairo_show_layout(cr, layout); + pango_cairo_update_layout(cr, layout); + cairo_move_to (cr, alloc.x + alloc.width/6, alloc.y + alloc.height/8); + pango_cairo_show_layout(cr, layout); - g_object_unref(layout); - g_object_unref(pcontext); - g_string_free (string, TRUE); - cairo_destroy (cr); + g_object_unref(layout); + g_object_unref(pcontext); + g_string_free (string, TRUE); + cairo_destroy (cr); } @@ -366,9 +366,9 @@ 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_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); } @@ -378,21 +378,21 @@ static gboolean metadata_widget_button_press_event (GtkWidget *menuitem, GdkEventButton *event) { - GtkClipboard* board = gtk_clipboard_get (GDK_NONE); + GtkClipboard* board = gtk_clipboard_get (GDK_NONE); - MetadataWidgetPrivate* priv = METADATA_WIDGET_GET_PRIVATE(METADATA_WIDGET(menuitem)); + MetadataWidgetPrivate* priv = METADATA_WIDGET_GET_PRIVATE(METADATA_WIDGET(menuitem)); - gchar* contents = g_strdup_printf("artist: %s \ntitle: %s \nalbum: %s", + gchar* contents = g_strdup_printf("artist: %s \ntitle: %s \nalbum: %s", dbusmenu_menuitem_property_get(priv->twin_item, - DBUSMENU_METADATA_MENUITEM_ARTIST), + DBUSMENU_METADATA_MENUITEM_ARTIST), dbusmenu_menuitem_property_get(priv->twin_item, - DBUSMENU_METADATA_MENUITEM_TITLE), + 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; + DBUSMENU_METADATA_MENUITEM_ALBUM)); + gtk_clipboard_set_text (board, contents, -1); + gtk_clipboard_store (board); + g_free(contents); + return FALSE; } // TODO: Manage empty/mangled music details etc. @@ -400,65 +400,65 @@ static void metadata_widget_property_update(DbusmenuMenuitem* item, gchar* property, GValue* value, gpointer userdata) { - g_return_if_fail (IS_METADATA_WIDGET (userdata)); - - if(g_value_get_int(value) == DBUSMENU_PROPERTY_EMPTY){ - //g_debug("Metadata widget: property update - reset"); - GValue new_value = {0}; - g_value_init(&new_value, G_TYPE_STRING); - g_value_set_string(&new_value, g_strdup("")); - value = &new_value; - } - - MetadataWidget* mitem = METADATA_WIDGET(userdata); - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(mitem); - - if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTIST, property) == 0){ - gtk_label_set_text(GTK_LABEL(priv->artist_label), g_value_get_string(value)); - metadata_widget_style_labels(mitem, GTK_LABEL(priv->artist_label)); - } - else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_TITLE, property) == 0){ - gtk_label_set_text(GTK_LABEL(priv->piece_label), g_value_get_string(value)); - metadata_widget_style_labels(mitem, GTK_LABEL(priv->piece_label)); - } - else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ALBUM, property) == 0){ - gtk_label_set_text(GTK_LABEL(priv->container_label), g_value_get_string(value)); - metadata_widget_style_labels(mitem, GTK_LABEL(priv->container_label)); - } - else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTURL, property) == 0){ - g_string_erase(priv->image_path, 0, -1); - g_string_overwrite(priv->image_path, 0, g_value_get_string (value)); - // if its a remote image queue a redraw incase the download took too long - if (g_str_has_prefix(g_value_get_string (value), g_get_user_cache_dir())){ - //g_debug("the image update is a download so redraw"); - gtk_widget_queue_draw(GTK_WIDGET(mitem)); - } - } + g_return_if_fail (IS_METADATA_WIDGET (userdata)); + + if(g_value_get_int(value) == DBUSMENU_PROPERTY_EMPTY){ + //g_debug("Metadata widget: property update - reset"); + GValue new_value = {0}; + g_value_init(&new_value, G_TYPE_STRING); + g_value_set_string(&new_value, g_strdup("")); + value = &new_value; + } + + MetadataWidget* mitem = METADATA_WIDGET(userdata); + MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(mitem); + + if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTIST, property) == 0){ + gtk_label_set_text(GTK_LABEL(priv->artist_label), g_value_get_string(value)); + metadata_widget_style_labels(mitem, GTK_LABEL(priv->artist_label)); + } + else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_TITLE, property) == 0){ + gtk_label_set_text(GTK_LABEL(priv->piece_label), g_value_get_string(value)); + metadata_widget_style_labels(mitem, GTK_LABEL(priv->piece_label)); + } + else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ALBUM, property) == 0){ + gtk_label_set_text(GTK_LABEL(priv->container_label), g_value_get_string(value)); + metadata_widget_style_labels(mitem, GTK_LABEL(priv->container_label)); + } + else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTURL, property) == 0){ + g_string_erase(priv->image_path, 0, -1); + g_string_overwrite(priv->image_path, 0, g_value_get_string (value)); + // if its a remote image queue a redraw incase the download took too long + if (g_str_has_prefix(g_value_get_string (value), g_get_user_cache_dir())){ + //g_debug("the image update is a download so redraw"); + gtk_widget_queue_draw(GTK_WIDGET(mitem)); + } + } } static void metadata_widget_style_labels(MetadataWidget* self, GtkLabel* label) { - char* markup; - markup = g_markup_printf_escaped ("%s", - gtk_label_get_text(GTK_LABEL(label))); - gtk_label_set_markup (GTK_LABEL (label), markup); - g_free(markup); + char* markup; + markup = g_markup_printf_escaped ("%s", + gtk_label_get_text(GTK_LABEL(label))); + gtk_label_set_markup (GTK_LABEL (label), markup); + g_free(markup); } static void metadata_widget_set_style(GtkWidget* metadata, GtkStyle* style) { - g_return_if_fail(IS_METADATA_WIDGET(metadata)); - MetadataWidget* widg = METADATA_WIDGET(metadata); - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widg); + g_return_if_fail(IS_METADATA_WIDGET(metadata)); + MetadataWidget* widg = METADATA_WIDGET(metadata); + MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widg); priv->theme_change_occured = TRUE; - gtk_widget_queue_draw(GTK_WIDGET(metadata)); + gtk_widget_queue_draw(GTK_WIDGET(metadata)); } static void metadata_widget_set_twin_item(MetadataWidget* self, - DbusmenuMenuitem* twin_item) + DbusmenuMenuitem* twin_item) { MetadataWidgetPrivate* priv = METADATA_WIDGET_GET_PRIVATE(self); priv->twin_item = twin_item; @@ -467,27 +467,27 @@ metadata_widget_set_twin_item(MetadataWidget* self, gtk_label_set_text( GTK_LABEL(priv->container_label), dbusmenu_menuitem_property_get( priv->twin_item, DBUSMENU_METADATA_MENUITEM_ALBUM)); - metadata_widget_style_labels( self, GTK_LABEL(priv->container_label)); + metadata_widget_style_labels( self, GTK_LABEL(priv->container_label)); gtk_label_set_text( GTK_LABEL(priv->piece_label), dbusmenu_menuitem_property_get( priv->twin_item, DBUSMENU_METADATA_MENUITEM_TITLE)); - metadata_widget_style_labels( self, GTK_LABEL(priv->piece_label)); + metadata_widget_style_labels( self, GTK_LABEL(priv->piece_label)); gtk_label_set_text( GTK_LABEL(priv->artist_label), dbusmenu_menuitem_property_get( priv->twin_item, DBUSMENU_METADATA_MENUITEM_ARTIST)); - metadata_widget_style_labels( self, GTK_LABEL(priv->artist_label)); + metadata_widget_style_labels( self, GTK_LABEL(priv->artist_label)); g_string_erase(priv->image_path, 0, -1); - g_string_overwrite( priv->image_path, + g_string_overwrite( priv->image_path, 0, dbusmenu_menuitem_property_get( priv->twin_item, DBUSMENU_METADATA_MENUITEM_ARTURL )); - // if its a remote image queue a redraw incase the download took too long - if (g_str_has_prefix (dbusmenu_menuitem_property_get (priv->twin_item, DBUSMENU_METADATA_MENUITEM_ARTURL ), + // if its a remote image queue a redraw incase the download took too long + if (g_str_has_prefix (dbusmenu_menuitem_property_get (priv->twin_item, DBUSMENU_METADATA_MENUITEM_ARTURL ), g_get_user_cache_dir())){ - gtk_widget_queue_draw(GTK_WIDGET(self)); + gtk_widget_queue_draw(GTK_WIDGET(self)); } } @@ -499,7 +499,7 @@ GtkWidget* metadata_widget_new(DbusmenuMenuitem *item) { - GtkWidget* widget = g_object_new(METADATA_WIDGET_TYPE, NULL); + GtkWidget* widget = g_object_new(METADATA_WIDGET_TYPE, NULL); metadata_widget_set_twin_item ( METADATA_WIDGET(widget), item ); return widget; diff --git a/src/metadata-widget.h b/src/metadata-widget.h index 814d5e8..6021af5 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 87f0307..59e3122 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -31,8 +31,8 @@ using Dbusmenu; */ public class Mpris2Controller : GLib.Object { - public static const string root_interface = "org.mpris.MediaPlayer2" ; - public MprisRoot mpris2_root {get; construct;} + public static const string root_interface = "org.mpris.MediaPlayer2" ; + public MprisRoot mpris2_root {get; construct;} public MprisPlayer player {get; construct;} public FreeDesktopProperties properties_interface {get; construct;} @@ -89,25 +89,25 @@ public class Mpris2Controller : GLib.Object } } - private GLib.HashTable? clean_metadata() - { - GLib.HashTable changed_updates = this.player.Metadata; + private GLib.HashTable? clean_metadata() + { + GLib.HashTable changed_updates = this.player.Metadata; Variant? artist_v = this.player.Metadata.lookup("xesam:artist"); if(artist_v != null){ string[] artists = (string[])this.player.Metadata.lookup("xesam:artist"); - string display_artists = string.joinv(", ", artists); - changed_updates.replace("xesam:artist", display_artists); - debug("artist : %s", (string)changed_updates.lookup("xesam:artist")); + string display_artists = string.joinv(", ", artists); + changed_updates.replace("xesam:artist", display_artists); + debug("artist : %s", (string)changed_updates.lookup("xesam:artist")); } Variant? length_v = this.player.Metadata.lookup("mpris:length"); if(length_v != null){ - int64 duration = this.player.Metadata.lookup("mpris:length").get_int64(); - changed_updates.replace("mpris:length", duration/1000000); + int64 duration = this.player.Metadata.lookup("mpris:length").get_int64(); + changed_updates.replace("mpris:length", duration/1000000); } - return changed_updates; - } - - private TransportMenuitem.state determine_play_state(string? status){ + return changed_updates; + } + + private TransportMenuitem.state determine_play_state(string? status){ if(status != null && status == "Playing"){ return TransportMenuitem.state.PLAYING; } @@ -133,7 +133,7 @@ public class Mpris2Controller : GLib.Object { debug("transport_event input = %i", (int)command); if(command == TransportMenuitem.action.PLAY_PAUSE){ - this.player.PlayPause.begin(); + this.player.PlayPause.begin(); } else if(command == TransportMenuitem.action.PREVIOUS){ this.player.Previous.begin(); diff --git a/src/mpris2-interfaces.vala b/src/mpris2-interfaces.vala index ef62aba..ebea135 100644 --- a/src/mpris2-interfaces.vala +++ b/src/mpris2-interfaces.vala @@ -20,27 +20,27 @@ with this program. If not, see . [DBus (name = "org.mpris.MediaPlayer2")] public interface MprisRoot : Object { - // properties - public abstract bool HasTracklist{owned get; set;} - public abstract bool CanQuit{owned get; set;} - public abstract bool CanRaise{owned get; set;} - public abstract string Identity{owned get; set;} - public abstract string DesktopEntry{owned get; set;} - // methods - public abstract async void Quit() throws IOError; - public abstract async void Raise() throws IOError; + // properties + public abstract bool HasTracklist{owned get; set;} + public abstract bool CanQuit{owned get; set;} + public abstract bool CanRaise{owned get; set;} + public abstract string Identity{owned get; set;} + public abstract string DesktopEntry{owned get; set;} + // methods + public abstract async void Quit() throws IOError; + public abstract async void Raise() throws IOError; } [DBus (name = "org.mpris.MediaPlayer2.Player")] public interface MprisPlayer : Object { - // properties - public abstract HashTable Metadata{owned get; set;} - public abstract int32 Position{owned get; set;} - public abstract string PlaybackStatus{owned get; set;} - // methods - public abstract async void PlayPause() throws IOError; - public abstract async void Next() throws IOError; - public abstract async void Previous() throws IOError; - // signals - public signal void Seeked(int64 new_position); + // properties + public abstract HashTable Metadata{owned get; set;} + public abstract int32 Position{owned get; set;} + public abstract string PlaybackStatus{owned get; set;} + // methods + public abstract async void PlayPause() throws IOError; + public abstract async void Next() throws IOError; + public abstract async void Previous() throws IOError; + // signals + public signal void Seeked(int64 new_position); } diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index d1c2334..5133770 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -73,14 +73,14 @@ public class MusicPlayerBridge : GLib.Object } } - /*public void on_server_added(Indicate.ListenerServer object, string type) + /*public void on_server_added(Indicate.ListenerServer object, string type) { debug("MusicPlayerBridge -> on_server_added with value %s", type); - if(server_is_not_of_interest(type)) return; - if ( this.root_menu != null ){ - listener_get_server_property_cb cb = (listener_get_server_property_cb)desktop_info_callback; - this.listener.server_get_desktop(object, cb, this); - } + if(server_is_not_of_interest(type)) return; + if ( this.root_menu != null ){ + listener_get_server_property_cb cb = (listener_get_server_property_cb)desktop_info_callback; + this.listener.server_get_desktop(object, cb, this); + } }*/ public void client_has_become_available ( string desktop_file_name ) @@ -105,7 +105,7 @@ public class MusicPlayerBridge : GLib.Object this.calculate_menu_position(), PlayerController.state.READY ); this.registered_clients.set ( mpris_key, ctrl ); - debug ( "successfully created appinfo and instance from path and set it on the respective instance" ); + debug ( "successfully created appinfo and instance from path and set it on the respective instance" ); } else{ this.registered_clients[mpris_key].update_state ( PlayerController.state.READY ); diff --git a/src/player-controller.vala b/src/player-controller.vala index 3c9b0ff..0b540f9 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -23,147 +23,147 @@ using Gee; public class PlayerController : GLib.Object { - public const int WIDGET_QUANTITY = 4; - - public static enum widget_order{ - SEPARATOR, - TITLE, - METADATA, - TRANSPORT, - } - - public enum state{ - OFFLINE, - INSTANTIATING, - READY, - CONNECTED, - DISCONNECTED - } - - public int current_state = state.OFFLINE; - - private Dbusmenu.Menuitem root_menu; - public string name { get; set;} - public string mpris_name { get; set;} - public ArrayList custom_items; - public Mpris2Controller mpris_bridge; - public AppInfo? app_info { get; set;} - public int menu_offset { get; set;} + public const int WIDGET_QUANTITY = 4; + + public static enum widget_order{ + SEPARATOR, + TITLE, + METADATA, + TRANSPORT, + } + + public enum state{ + OFFLINE, + INSTANTIATING, + READY, + CONNECTED, + DISCONNECTED + } + + public int current_state = state.OFFLINE; + + private Dbusmenu.Menuitem root_menu; + public string name { get; set;} + public string mpris_name { get; set;} + public ArrayList custom_items; + public Mpris2Controller mpris_bridge; + public AppInfo? app_info { get; set;} + public int menu_offset { get; set;} public string icon_name { get; set; } - - public PlayerController(Dbusmenu.Menuitem root, + + public PlayerController(Dbusmenu.Menuitem root, GLib.AppInfo app, string mpris_name, string icon_name, - int offset, - state initial_state) - { - this.root_menu = root; + int offset, + state initial_state) + { + this.root_menu = root; this.app_info = app; - this.name = format_player_name(this.app_info.get_name()); + this.name = format_player_name(this.app_info.get_name()); this.mpris_name = mpris_name; this.icon_name = icon_name; - this.custom_items = new ArrayList(); - this.current_state = initial_state; - this.menu_offset = offset; - construct_widgets(); - establish_mpris_connection(); - this.update_layout(); - } - - public void update_state(state new_state) - { - debug("update_state - player controller %s : new state %i", this.name, new_state); - this.current_state = new_state; - this.update_layout(); - } - - public void activate() - { - this.establish_mpris_connection(); - } - - /* - instantiate() - The user should be able to start the app from the transport bar when in an offline state - There is a need to wait before the application is on DBus before attempting to access its mpris address - Hence only when the it has registered with us via libindicate do we attempt to kick off mpris communication - */ - public void instantiate() - { - debug("instantiate in player controller for %s", this.name); - try{ - this.app_info.launch(null, null); - this.update_state(state.INSTANTIATING); - } - catch(GLib.Error error){ - warning("Failed to launch app %s with error message: %s", this.name, error.message); - } - } - - private void establish_mpris_connection() - { - if(this.current_state != state.READY){ - debug("establish_mpris_connection - Not ready to connect"); - return; - } - this.mpris_bridge = new Mpris2Controller(this); - this.determine_state(); - } - - public void vanish() - { - foreach(Dbusmenu.Menuitem item in this.custom_items){ - root_menu.child_delete(item); - } - } - - public void hibernate() - { - update_state(PlayerController.state.OFFLINE); - this.custom_items[widget_order.TRANSPORT].reset(TransportMenuitem.attributes_format()); - this.custom_items[widget_order.METADATA].reset(MetadataMenuitem.attributes_format()); - TitleMenuitem title = this.custom_items[widget_order.TITLE] as TitleMenuitem; - title.toggle_active_triangle(false); - } - - public void update_layout() - { - if(this.current_state != state.CONNECTED){ - this.custom_items[widget_order.TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE, - false); - this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, - false); - return; - } - this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, - this.custom_items[widget_order.METADATA].populated(MetadataMenuitem.attributes_format())); - this.custom_items[widget_order.TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE, - true); - } - - private void construct_widgets() - { - // 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(); - this.custom_items.add(metadata_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)); - } - } - + this.custom_items = new ArrayList(); + this.current_state = initial_state; + this.menu_offset = offset; + construct_widgets(); + establish_mpris_connection(); + this.update_layout(); + } + + public void update_state(state new_state) + { + debug("update_state - player controller %s : new state %i", this.name, new_state); + this.current_state = new_state; + this.update_layout(); + } + + public void activate() + { + this.establish_mpris_connection(); + } + + /* + instantiate() + The user should be able to start the app from the transport bar when in an offline state + There is a need to wait before the application is on DBus before attempting to access its mpris address + Hence only when the it has registered with us via libindicate do we attempt to kick off mpris communication + */ + public void instantiate() + { + debug("instantiate in player controller for %s", this.name); + try{ + this.app_info.launch(null, null); + this.update_state(state.INSTANTIATING); + } + catch(GLib.Error error){ + warning("Failed to launch app %s with error message: %s", this.name, error.message); + } + } + + private void establish_mpris_connection() + { + if(this.current_state != state.READY){ + debug("establish_mpris_connection - Not ready to connect"); + return; + } + this.mpris_bridge = new Mpris2Controller(this); + this.determine_state(); + } + + public void vanish() + { + foreach(Dbusmenu.Menuitem item in this.custom_items){ + root_menu.child_delete(item); + } + } + + public void hibernate() + { + update_state(PlayerController.state.OFFLINE); + this.custom_items[widget_order.TRANSPORT].reset(TransportMenuitem.attributes_format()); + this.custom_items[widget_order.METADATA].reset(MetadataMenuitem.attributes_format()); + TitleMenuitem title = this.custom_items[widget_order.TITLE] as TitleMenuitem; + title.toggle_active_triangle(false); + } + + public void update_layout() + { + if(this.current_state != state.CONNECTED){ + this.custom_items[widget_order.TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE, + false); + this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, + false); + return; + } + this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, + this.custom_items[widget_order.METADATA].populated(MetadataMenuitem.attributes_format())); + this.custom_items[widget_order.TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE, + true); + } + + private void construct_widgets() + { + // 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(); + this.custom_items.add(metadata_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)); + } + } + private static string format_player_name(owned string app_info_name) { string result = app_info_name.down().strip(); @@ -172,22 +172,22 @@ public class PlayerController : GLib.Object result = tokens[0]; } if(result.length > 1){ - result = result.up(1).concat(result.slice(1, result.length)); - debug("PlayerController->format_player_name - : %s", result); - } + result = result.up(1).concat(result.slice(1, result.length)); + debug("PlayerController->format_player_name - : %s", result); + } return result; } - public void determine_state() - { - 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); + public void determine_state() + { + 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); this.mpris_bridge.initial_update(); - } - else{ - this.update_state(state.DISCONNECTED); - } - } + } + else{ + this.update_state(state.DISCONNECTED); + } + } } diff --git a/src/player-item.vala b/src/player-item.vala index 54d0d89..c80a17d 100644 --- a/src/player-item.vala +++ b/src/player-item.vala @@ -22,86 +22,86 @@ using Gee; public class PlayerItem : Dbusmenu.Menuitem { - public PlayerController owner {get; construct;} - public string item_type { get; construct; } - private const int EMPTY = -1; + public PlayerController owner {get; construct;} + public string item_type { get; construct; } + private const int EMPTY = -1; - public PlayerItem(string type) - { - Object(item_type: type); - } - - construct { - this.property_set(MENUITEM_PROP_TYPE, item_type); - } + public PlayerItem(string type) + { + Object(item_type: type); + } + + construct { + this.property_set(MENUITEM_PROP_TYPE, item_type); + } - public void reset(HashSet attrs){ - foreach(string s in attrs){ - debug("attempting to set prop %s to EMPTY", s); - this.property_set_int(s, EMPTY); - } - } - - /** - * update() - * Base update method for playeritems, takes the attributes and the incoming updates - * and attmepts to update the appropriate props on the object. - * Album art is handled separately to deal with remote and local file paths. - */ - public void update(HashTable data, HashSet attributes) - { - debug("PlayerItem::update()"); - if(data == null){ - debug("PlayerItem::Update -> The hashtable was null - 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]; - debug("search key = %s", search_key); - Variant? v = data.lookup(search_key); - - if (v.is_of_type ( VariantType.STRING )){ - string update = v.get_string().strip(); - debug("with value : %s", update); - if(property.contains("mpris:artUrl")){ - // We know its a metadata instance because thats the only - // object with the arturl prop - MetadataMenuitem metadata = this as MetadataMenuitem; - metadata.fetch_art ( update, property ); - continue; - } - this.property_set(property, update); - } - else if (v.is_of_type (VariantType.INT32 )){ - debug("with value : %i", v.get_int32()); - this.property_set_int(property, v.get_int32()); - } - else if (v.is_of_type (VariantType.INT64 )){ - debug("with value : %i", (int)v.get_int64()); - this.property_set_int(property, (int)v.get_int64()); - } - else if(v.is_of_type ( VariantType.BOOLEAN )){ - debug("with value : %s", v.get_boolean().to_string()); - this.property_set_bool(property, v.get_boolean()); - } - } + public void reset(HashSet attrs){ + foreach(string s in attrs){ + debug("attempting to set prop %s to EMPTY", s); + this.property_set_int(s, EMPTY); + } + } + + /** + * update() + * Base update method for playeritems, takes the attributes and the incoming updates + * and attmepts to update the appropriate props on the object. + * Album art is handled separately to deal with remote and local file paths. + */ + public void update(HashTable data, HashSet attributes) + { + debug("PlayerItem::update()"); + if(data == null){ + debug("PlayerItem::Update -> The hashtable was null - 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]; + debug("search key = %s", search_key); + Variant? v = data.lookup(search_key); + + if (v.is_of_type ( VariantType.STRING )){ + string update = v.get_string().strip(); + debug("with value : %s", update); + if(property.contains("mpris:artUrl")){ + // We know its a metadata instance because thats the only + // object with the arturl prop + MetadataMenuitem metadata = this as MetadataMenuitem; + metadata.fetch_art ( update, property ); + continue; + } + this.property_set(property, update); + } + else if (v.is_of_type (VariantType.INT32 )){ + debug("with value : %i", v.get_int32()); + this.property_set_int(property, v.get_int32()); + } + else if (v.is_of_type (VariantType.INT64 )){ + debug("with value : %i", (int)v.get_int64()); + this.property_set_int(property, (int)v.get_int64()); + } + else if(v.is_of_type ( VariantType.BOOLEAN )){ + debug("with value : %s", v.get_boolean().to_string()); + this.property_set_bool(property, v.get_boolean()); + } + } this.property_set_bool(MENUITEM_PROP_VISIBLE, populated(attributes)); - } - - public bool populated(HashSet attrs) - { - foreach(string prop in attrs){ - debug("populated ? - prop: %s", prop); - int value_int = property_get_int(prop); - if(property_get_int(prop) != EMPTY){ - debug("populated - prop %s and value %i", prop, value_int); - return true; - } - } - return false; - } + } + + public bool populated(HashSet attrs) + { + foreach(string prop in attrs){ + debug("populated ? - prop: %s", prop); + int value_int = property_get_int(prop); + if(property_get_int(prop) != EMPTY){ + debug("populated - prop %s and value %i", prop, value_int); + return true; + } + } + return false; + } } diff --git a/src/pulse-manager.c b/src/pulse-manager.c index 14633fe..b002094 100644 --- a/src/pulse-manager.c +++ b/src/pulse-manager.c @@ -131,7 +131,7 @@ void close_pulse_activites() { if (pulse_context != NULL) { /* g_debug("freeing the pulse context");*/ - pa_context_unref(pulse_context); + pa_context_unref(pulse_context); pulse_context = NULL; } g_hash_table_destroy(sink_hash); @@ -223,7 +223,7 @@ static void mute_each_sink(gpointer key, gpointer value, gpointer user_data) if (GPOINTER_TO_INT(user_data) == 1) { sound_service_dbus_update_sink_mute(dbus_service, TRUE); } else { - dbus_menu_manager_update_volume(get_default_sink_volume()); + dbus_menu_manager_update_volume(get_default_sink_volume()); } /* g_debug("in the pulse manager: mute each sink %i", GPOINTER_TO_INT(user_data));*/ @@ -364,7 +364,7 @@ static void pulse_sink_input_info_callback(pa_context *c, const pa_sink_input_in /* g_warning("\n Sink input info callback : SINK INPUT INFO IS NULL BUT EOL was not POSITIVE!!!");*/ return; } - /* g_debug("\n SINK INPUT INFO sink index : %d \n", info->sink);*/ + /* g_debug("\n SINK INPUT INFO sink index : %d \n", info->sink);*/ check_sink_input_while_muted_event(info->sink); } } @@ -419,7 +419,7 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v pa_volume_t vol = pa_cvolume_max(&s->volume); gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; /* g_debug("Updating volume from PA manager with volume = %f", volume_percent);*/ - dbus_menu_manager_update_volume(volume_percent); + dbus_menu_manager_update_volume(volume_percent); } } } @@ -505,12 +505,12 @@ static void subscribed_events_callback(pa_context *c, enum pa_subscription_event } /* g_debug("subscribed_events_callback - Now what is our default sink : %i", DEFAULT_SINK_INDEX); */ } else { - /* g_debug("subscribed_events_callback - PA_SUBSCRIPTION_EVENT_SINK: a generic sink event - will trigger an update"); */ + /* g_debug("subscribed_events_callback - PA_SUBSCRIPTION_EVENT_SINK: a generic sink event - will trigger an update"); */ pa_operation_unref(pa_context_get_sink_info_by_index(c, index, update_sink_info, userdata)); } break; case PA_SUBSCRIPTION_EVENT_SINK_INPUT: - /* g_debug("subscribed_events_callback - PA_SUBSCRIPTION_EVENT_SINK_INPUT event triggered!!");*/ + /* g_debug("subscribed_events_callback - PA_SUBSCRIPTION_EVENT_SINK_INPUT event triggered!!");*/ if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { //handle the sink input remove event - not relevant for current design } else { @@ -534,16 +534,16 @@ static void context_state_callback(pa_context *c, void *userdata) { switch (pa_context_get_state(c)) { case PA_CONTEXT_UNCONNECTED: - g_debug("unconnected"); + g_debug("unconnected"); break; case PA_CONTEXT_CONNECTING: - g_debug("connecting - waiting for the server to become available"); + g_debug("connecting - waiting for the server to become available"); break; case PA_CONTEXT_AUTHORIZING: - /* g_debug("authorizing");*/ + /* g_debug("authorizing");*/ break; case PA_CONTEXT_SETTING_NAME: - /* g_debug("context setting name");*/ + /* g_debug("context setting name");*/ break; case PA_CONTEXT_FAILED: g_warning("PA_CONTEXT_FAILED - Is PulseAudio Daemon running ?"); @@ -560,7 +560,7 @@ static void context_state_callback(pa_context *c, void *userdata) } break; case PA_CONTEXT_TERMINATED: - /* g_debug("context terminated");*/ + /* g_debug("context terminated");*/ break; case PA_CONTEXT_READY: g_debug("PA_CONTEXT_READY"); diff --git a/src/scrub-menu-item.vala b/src/scrub-menu-item.vala index d7b60a0..e300050 100644 --- a/src/scrub-menu-item.vala +++ b/src/scrub-menu-item.vala @@ -23,34 +23,34 @@ using Gee; public class ScrubMenuitem : PlayerItem { - public ScrubMenuitem(PlayerController parent) - { - Object(item_type: MENUITEM_TYPE, owner: parent); - reset(attributes_format()); - } - - 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_bridge.set_track_position(input_value.get_double()); - } - - public void update_position(int32 new_position) - { - this.property_set_int(MENUITEM_POSITION, new_position); - } - - public void update_playstate(int state) - { - this.property_set_int(MENUITEM_PLAY_STATE, state); - } - - public static HashSet attributes_format() - { - HashSet attrs = new HashSet(); - attrs.add(MENUITEM_DURATION); - attrs.add(MENUITEM_POSITION); - attrs.add(MENUITEM_PLAY_STATE); - return attrs; - } + public ScrubMenuitem(PlayerController parent) + { + Object(item_type: MENUITEM_TYPE, owner: parent); + reset(attributes_format()); + } + + 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_bridge.set_track_position(input_value.get_double()); + } + + public void update_position(int32 new_position) + { + this.property_set_int(MENUITEM_POSITION, new_position); + } + + public void update_playstate(int state) + { + this.property_set_int(MENUITEM_PLAY_STATE, state); + } + + public static HashSet attributes_format() + { + HashSet attrs = new HashSet(); + attrs.add(MENUITEM_DURATION); + attrs.add(MENUITEM_POSITION); + attrs.add(MENUITEM_PLAY_STATE); + return attrs; + } } \ No newline at end of file diff --git a/src/scrub-widget.c b/src/scrub-widget.c index a1d45d5..edc65de 100644 --- a/src/scrub-widget.c +++ b/src/scrub-widget.c @@ -31,10 +31,10 @@ typedef struct _ScrubWidgetPrivate ScrubWidgetPrivate; struct _ScrubWidgetPrivate { - DbusmenuMenuitem* twin_item; - GtkWidget* ido_scrub_bar; - IdoTimeline* time_line; - gboolean scrubbing; + DbusmenuMenuitem* twin_item; + GtkWidget* ido_scrub_bar; + IdoTimeline* time_line; + gboolean scrubbing; }; #define SCRUB_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SCRUB_WIDGET_TYPE, ScrubWidgetPrivate)) @@ -45,25 +45,25 @@ 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); + 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); + GtkScrollType scroll, + gdouble value, + gpointer user_data); static void scrub_widget_timeline_frame_cb(IdoTimeline *timeline, - gdouble progress, - gpointer userdata); + gdouble progress, + gpointer userdata); static void scrub_widget_timeline_started_cb(IdoTimeline *timeline, - gpointer userdata); + gpointer userdata); static void scrub_widget_timeline_finished_cb(IdoTimeline *timeline, - gpointer userdata); + gpointer userdata); static gdouble scrub_widget_calculate_progress(ScrubWidget* widget); static void scrub_widget_check_play_state(ScrubWidget* self); static void scrub_widget_slider_grabbed(GtkWidget *widget, gpointer user_data); @@ -76,190 +76,190 @@ 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)); + 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; + 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); + 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", IDO_RANGE_STYLE_SMALL, 0, 0, 100, 1); - priv->time_line = ido_timeline_new(0); - - ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM(priv->ido_scrub_bar), IDO_SCALE_MENU_ITEM_STYLE_LABEL); + priv->time_line = ido_timeline_new(0); + + 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); - priv->scrubbing = FALSE; + g_object_set(priv->ido_scrub_bar, "reverse-scroll-events", TRUE, NULL); + priv->scrubbing = FALSE; - gtk_widget_set_size_request(GTK_WIDGET(priv->ido_scrub_bar), 100, 25); + gtk_widget_set_size_request(GTK_WIDGET(priv->ido_scrub_bar), 100, 25); // 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); - g_signal_connect(priv->time_line, "frame", G_CALLBACK(scrub_widget_timeline_frame_cb), self); - g_signal_connect(priv->time_line, "started", G_CALLBACK(scrub_widget_timeline_started_cb), self); - g_signal_connect(priv->time_line, "finished", G_CALLBACK(scrub_widget_timeline_finished_cb), self); + 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); + g_signal_connect(priv->time_line, "frame", G_CALLBACK(scrub_widget_timeline_frame_cb), self); + g_signal_connect(priv->time_line, "started", G_CALLBACK(scrub_widget_timeline_started_cb), self); + g_signal_connect(priv->time_line, "finished", G_CALLBACK(scrub_widget_timeline_finished_cb), self); g_signal_connect(priv->ido_scrub_bar, "slider-grabbed", G_CALLBACK(scrub_widget_slider_grabbed), self); g_signal_connect(priv->ido_scrub_bar, "slider-released", G_CALLBACK(scrub_widget_slider_released), self); - + } static void scrub_widget_dispose (GObject *object) { - G_OBJECT_CLASS (scrub_widget_parent_class)->dispose (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); + 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)); + 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))); - - ido_timeline_set_duration(priv->time_line, g_value_get_int(value) * 1000); - ido_timeline_rewind(priv->time_line); - scrub_widget_check_play_state(mitem); - //g_debug("timeline is running: %i", (gint)ido_timeline_is_running(priv->time_line)); - //g_debug("timeline duration = %i", ido_timeline_get_duration(priv->time_line)); - - 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)); - } - else if(g_ascii_strcasecmp(DBUSMENU_SCRUB_MENUITEM_POSITION, property) == 0){ - g_debug("scrub-widget::update position = %i", g_value_get_int(value)); - ido_timeline_pause(priv->time_line); - 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)); - - g_debug("scrub-widget::update progress = %f", scrub_widget_calculate_progress(mitem)*100); - - ido_timeline_set_progress(priv->time_line, scrub_widget_calculate_progress(mitem)); - scrub_widget_set_ido_position(mitem, g_value_get_int(value)/1000, - dbusmenu_menuitem_property_get_int(priv->twin_item, DBUSMENU_SCRUB_MENUITEM_DURATION)); - - scrub_widget_check_play_state(mitem); - } - else if(g_ascii_strcasecmp(DBUSMENU_SCRUB_MENUITEM_PLAY_STATE, property) == 0){ - scrub_widget_check_play_state(mitem); - } + scrub_widget_format_time(g_value_get_int(value))); + + ido_timeline_set_duration(priv->time_line, g_value_get_int(value) * 1000); + ido_timeline_rewind(priv->time_line); + scrub_widget_check_play_state(mitem); + //g_debug("timeline is running: %i", (gint)ido_timeline_is_running(priv->time_line)); + //g_debug("timeline duration = %i", ido_timeline_get_duration(priv->time_line)); + + 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)); + } + else if(g_ascii_strcasecmp(DBUSMENU_SCRUB_MENUITEM_POSITION, property) == 0){ + g_debug("scrub-widget::update position = %i", g_value_get_int(value)); + ido_timeline_pause(priv->time_line); + 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)); + + g_debug("scrub-widget::update progress = %f", scrub_widget_calculate_progress(mitem)*100); + + ido_timeline_set_progress(priv->time_line, scrub_widget_calculate_progress(mitem)); + scrub_widget_set_ido_position(mitem, g_value_get_int(value)/1000, + dbusmenu_menuitem_property_get_int(priv->twin_item, DBUSMENU_SCRUB_MENUITEM_DURATION)); + + scrub_widget_check_play_state(mitem); + } + else if(g_ascii_strcasecmp(DBUSMENU_SCRUB_MENUITEM_PLAY_STATE, property) == 0){ + scrub_widget_check_play_state(mitem); + } } static void scrub_widget_check_play_state(ScrubWidget* self) { - ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(self); - gint play_state = dbusmenu_menuitem_property_get_int(priv->twin_item, - DBUSMENU_SCRUB_MENUITEM_PLAY_STATE); - g_debug("play-state = %i", play_state); - if(play_state == 0){ - g_debug("START TIMELINE"); - ido_timeline_start(priv->time_line); - } - else{ - g_debug("PAUSE TIMELINE"); - ido_timeline_pause(priv->time_line); - } + ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(self); + gint play_state = dbusmenu_menuitem_property_get_int(priv->twin_item, + DBUSMENU_SCRUB_MENUITEM_PLAY_STATE); + g_debug("play-state = %i", play_state); + if(play_state == 0){ + g_debug("START TIMELINE"); + ido_timeline_start(priv->time_line); + } + else{ + g_debug("PAUSE TIMELINE"); + ido_timeline_pause(priv->time_line); + } } 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); + 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) + 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); + g_return_val_if_fail (IS_SCRUB_WIDGET (user_data), FALSE); + ScrubWidget* mitem = SCRUB_WIDGET(user_data); + ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(mitem); // Don't bother when the slider is grabbed if(priv->scrubbing == TRUE) return FALSE; - GValue value = {0}; + GValue value = {0}; g_value_init(&value, G_TYPE_DOUBLE); - gdouble clamped = CLAMP(new_value, 0, 100); + gdouble clamped = CLAMP(new_value, 0, 100); g_value_set_double(&value, clamped); dbusmenu_menuitem_handle_event (priv->twin_item, "scrubbing", &value, 0); - return TRUE; + return TRUE; } GtkWidget* scrub_widget_get_ido_bar(ScrubWidget* self) { - ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(self); - return priv->ido_scrub_bar; + 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 ... - gchar* prefix = "-"; - gchar* seconds_prefix = "-"; - - if(time != DBUSMENU_PROPERTY_EMPTY){ - gint minutes = time/60; - gint seconds = time % 60; - prefix="0"; - 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); - - } - else{ - return g_strdup_printf("%s-:%s-", prefix, seconds_prefix); - } + gchar* prefix = "-"; + gchar* seconds_prefix = "-"; + + if(time != DBUSMENU_PROPERTY_EMPTY){ + gint minutes = time/60; + gint seconds = time % 60; + prefix="0"; + 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); + + } + else{ + return g_strdup_printf("%s-:%s-", prefix, seconds_prefix); + } } static void @@ -267,74 +267,74 @@ 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); + 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); + if(duration == 0) + ido_position = 0.0; + gtk_range_set_value(range, ido_position); } static gdouble scrub_widget_calculate_progress(ScrubWidget* widget) { - ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(widget); - gint position = dbusmenu_menuitem_property_get_int(priv->twin_item, - DBUSMENU_SCRUB_MENUITEM_POSITION)/1000; - gint duration = dbusmenu_menuitem_property_get_int(priv->twin_item, - DBUSMENU_SCRUB_MENUITEM_DURATION); - gdouble ido_position = position/(gdouble)duration; - g_debug("scrub_widget_calculate_progress %f", ido_position); - - return ido_position; + ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(widget); + gint position = dbusmenu_menuitem_property_get_int(priv->twin_item, + DBUSMENU_SCRUB_MENUITEM_POSITION)/1000; + gint duration = dbusmenu_menuitem_property_get_int(priv->twin_item, + DBUSMENU_SCRUB_MENUITEM_DURATION); + gdouble ido_position = position/(gdouble)duration; + g_debug("scrub_widget_calculate_progress %f", ido_position); + + return ido_position; } static void -scrub_widget_timeline_frame_cb( IdoTimeline *timeline, - gdouble progress, - gpointer user_data) +scrub_widget_timeline_frame_cb( IdoTimeline *timeline, + gdouble progress, + gpointer user_data) { - - //g_debug("Timeline CB : %f", progress); - g_return_if_fail (IS_SCRUB_WIDGET (user_data)); - ScrubWidget* mitem = SCRUB_WIDGET(user_data); - ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(mitem); - if(priv->scrubbing == TRUE) - { - g_debug("don't update the slider or timeline, slider is being scrubbed"); - return; - } - gint position = progress * dbusmenu_menuitem_property_get_int(priv->twin_item, - DBUSMENU_SCRUB_MENUITEM_DURATION); - gchar* left_text = scrub_widget_format_time(position); - ido_scale_menu_item_set_primary_label(IDO_SCALE_MENU_ITEM(priv->ido_scrub_bar), left_text); + + //g_debug("Timeline CB : %f", progress); + g_return_if_fail (IS_SCRUB_WIDGET (user_data)); + ScrubWidget* mitem = SCRUB_WIDGET(user_data); + ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(mitem); + if(priv->scrubbing == TRUE) + { + g_debug("don't update the slider or timeline, slider is being scrubbed"); + return; + } + gint position = progress * dbusmenu_menuitem_property_get_int(priv->twin_item, + DBUSMENU_SCRUB_MENUITEM_DURATION); + gchar* left_text = scrub_widget_format_time(position); + ido_scale_menu_item_set_primary_label(IDO_SCALE_MENU_ITEM(priv->ido_scrub_bar), left_text); GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_scrub_bar); GtkRange *range = (GtkRange*)slider; gtk_range_set_value(range, progress * 100); - /*g_debug("position in seconds %i and in words %s", position, left_text); - g_debug("timeline is running: %i", (gint)ido_timeline_is_running(priv->time_line)); - g_debug("timeline duration = %i", ido_timeline_get_duration(priv->time_line)); - */ - //g_debug("timeline-update - progress = %f", progress); - g_free(left_text); + /*g_debug("position in seconds %i and in words %s", position, left_text); + g_debug("timeline is running: %i", (gint)ido_timeline_is_running(priv->time_line)); + g_debug("timeline duration = %i", ido_timeline_get_duration(priv->time_line)); + */ + //g_debug("timeline-update - progress = %f", progress); + g_free(left_text); } static void scrub_widget_slider_released(GtkWidget *widget, gpointer user_data) { - ScrubWidget* mitem = SCRUB_WIDGET(user_data); - ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(mitem); - priv->scrubbing = FALSE; - GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_scrub_bar); + ScrubWidget* mitem = SCRUB_WIDGET(user_data); + ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(mitem); + priv->scrubbing = FALSE; + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_scrub_bar); gdouble new_value = gtk_range_get_value(GTK_RANGE(slider)); - g_debug("okay set the scrub position with %f", new_value); - GValue value = {0}; + g_debug("okay set the scrub position with %f", new_value); + GValue value = {0}; g_value_init(&value, G_TYPE_DOUBLE); - gdouble clamped = CLAMP(new_value, 0, 100); + gdouble clamped = CLAMP(new_value, 0, 100); g_value_set_double(&value, clamped); dbusmenu_menuitem_handle_event (priv->twin_item, "scrubbing", &value, 0); } @@ -342,23 +342,23 @@ scrub_widget_slider_released(GtkWidget *widget, gpointer user_data) static void scrub_widget_slider_grabbed(GtkWidget *widget, gpointer user_data) { - ScrubWidget* mitem = SCRUB_WIDGET(user_data); - ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(mitem); - priv->scrubbing = TRUE; + ScrubWidget* mitem = SCRUB_WIDGET(user_data); + ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(mitem); + priv->scrubbing = TRUE; } static void -scrub_widget_timeline_started_cb( IdoTimeline *timeline, - gpointer user_data) +scrub_widget_timeline_started_cb( IdoTimeline *timeline, + gpointer user_data) { - g_debug("Timeline Started!"); + g_debug("Timeline Started!"); } static void scrub_widget_timeline_finished_cb(IdoTimeline *timeline, - gpointer user_data) + gpointer user_data) { - g_debug("Timeline Finished!"); + g_debug("Timeline Finished!"); } /** @@ -368,9 +368,9 @@ scrub_widget_timeline_finished_cb(IdoTimeline *timeline, 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; + 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 index e518a80..cf6cc5e 100644 --- a/src/scrub-widget.h +++ b/src/scrub-widget.h @@ -32,15 +32,15 @@ G_BEGIN_DECLS #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; +typedef struct _ScrubWidget ScrubWidget; +typedef struct _ScrubWidgetClass ScrubWidgetClass; struct _ScrubWidgetClass { GObjectClass parent_class; }; struct _ScrubWidget { - GObject parent; + GObject parent; }; GType scrub_widget_get_type (void) G_GNUC_CONST; diff --git a/src/slider-menu-item.c b/src/slider-menu-item.c index c850cdc..d0d2050 100644 --- a/src/slider-menu-item.c +++ b/src/slider-menu-item.c @@ -88,11 +88,11 @@ handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, g SliderMenuItem* slider_menu_item_new(gboolean sinks_available, gdouble start_volume) -{ +{ SliderMenuItem *self = g_object_new(SLIDER_MENU_ITEM_TYPE, NULL); dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_VOLUME_MENUITEM_TYPE); - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_ENABLED, sinks_available); + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_ENABLED, sinks_available); dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_VISIBLE, sinks_available); return self; } diff --git a/src/title-menu-item.vala b/src/title-menu-item.vala index 64ddebf..d782e84 100644 --- a/src/title-menu-item.vala +++ b/src/title-menu-item.vala @@ -23,37 +23,37 @@ using Gee; public class TitleMenuitem : PlayerItem { - public TitleMenuitem(PlayerController parent) - { - Object(item_type: MENUITEM_TYPE, owner: parent); - this.property_set(MENUITEM_NAME, parent.name); + public TitleMenuitem(PlayerController parent) + { + Object(item_type: MENUITEM_TYPE, owner: parent); + this.property_set(MENUITEM_NAME, parent.name); debug("title init - icon name = %s", parent.icon_name); this.property_set(MENUITEM_ICON, parent.icon_name); - this.property_set_bool(MENUITEM_RUNNING, false); - } - - public override void handle_event(string name, GLib.Value 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 toggle_active_triangle(bool update) - { - this.property_set_bool(MENUITEM_RUNNING, update); - } - - public static HashSet attributes_format() - { - HashSet attrs = new HashSet(); - attrs.add(MENUITEM_NAME); - attrs.add(MENUITEM_RUNNING); - attrs.add(MENUITEM_ICON); + this.property_set_bool(MENUITEM_RUNNING, false); + } + + public override void handle_event(string name, GLib.Value 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 toggle_active_triangle(bool update) + { + this.property_set_bool(MENUITEM_RUNNING, update); + } + + public static HashSet attributes_format() + { + HashSet attrs = new HashSet(); + 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 index 1524a4a..cbdf28e 100644 --- a/src/title-widget.c +++ b/src/title-widget.c @@ -32,7 +32,7 @@ typedef struct _TitleWidgetPrivate TitleWidgetPrivate; struct _TitleWidgetPrivate { - DbusmenuMenuitem* twin_item; + DbusmenuMenuitem* twin_item; }; #define TITLE_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TITLE_WIDGET_TYPE, TitleWidgetPrivate)) @@ -45,12 +45,12 @@ static void title_widget_finalize (GObject *object); // keyevent consumers static gboolean title_widget_button_press_event (GtkWidget *menuitem, - GdkEventButton *event); + GdkEventButton *event); // Dbusmenuitem properties update callback static void title_widget_property_update(DbusmenuMenuitem* item, gchar* property, GValue* value, gpointer userdata); -static void title_widget_set_twin_item( TitleWidget* self, +static void title_widget_set_twin_item( TitleWidget* self, DbusmenuMenuitem* twin_item); static gboolean title_widget_triangle_draw_cb (GtkWidget *widget, GdkEventExpose *event, @@ -61,7 +61,7 @@ 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); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); widget_class->button_press_event = title_widget_button_press_event; @@ -75,7 +75,7 @@ title_widget_class_init (TitleWidgetClass *klass) static void title_widget_init (TitleWidget *self) { - //g_debug("TitleWidget::title_widget_init"); + //g_debug("TitleWidget::title_widget_init"); } static void @@ -84,9 +84,9 @@ 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); + 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), @@ -98,7 +98,7 @@ title_widget_set_icon(TitleWidget *self) 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, + icon = gtk_image_new_from_icon_name ( app_panel->str, GTK_ICON_SIZE_MENU ); } else{ @@ -112,22 +112,22 @@ title_widget_set_icon(TitleWidget *self) + 5 /* ref triangle is 5x9 pixels */ + 1 /* padding */, height); - gtk_misc_set_alignment(GTK_MISC(icon), 0.5 /* right aligned */, 0); + 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); + gtk_widget_show(icon); } static void title_widget_dispose (GObject *object) { - G_OBJECT_CLASS (title_widget_parent_class)->dispose (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); + G_OBJECT_CLASS (title_widget_parent_class)->finalize (object); } /* Suppress/consume keyevents */ @@ -135,37 +135,37 @@ static gboolean title_widget_button_press_event (GtkWidget *menuitem, GdkEventButton *event) { - //g_debug("TitleWidget::menu_press_event"); - TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(menuitem); - - GValue value = {0}; + //g_debug("TitleWidget::menu_press_event"); + TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(menuitem); + + GValue value = {0}; g_value_init(&value, G_TYPE_BOOLEAN); - g_value_set_boolean(&value, TRUE); - dbusmenu_menuitem_handle_event (priv->twin_item, "Title menu event", &value, 0); - - return FALSE; + g_value_set_boolean(&value, TRUE); + dbusmenu_menuitem_handle_event (priv->twin_item, "Title menu event", &value, 0); + + return FALSE; } static void title_widget_property_update(DbusmenuMenuitem* item, gchar* property, GValue* value, gpointer userdata) { - g_return_if_fail (IS_TITLE_WIDGET (userdata)); - TitleWidget* mitem = TITLE_WIDGET(userdata); + g_return_if_fail (IS_TITLE_WIDGET (userdata)); + TitleWidget* mitem = TITLE_WIDGET(userdata); g_debug("PROPERTY UPDATE FOR THE TITLE"); - if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_NAME, property) == 0){ + if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_NAME, property) == 0){ gtk_menu_item_set_label (GTK_MENU_ITEM(mitem), g_value_get_string(value)); - } - else if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_ICON, property) == 0){ + } + else if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_ICON, property) == 0){ g_debug("changing the icon data on the title - %s", g_value_get_string(value)); - GtkWidget * icon = gtk_image_new_from_icon_name(g_value_get_string(value), + GtkWidget * icon = gtk_image_new_from_icon_name(g_value_get_string(value), GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mitem), GTK_WIDGET(icon)); - } + } } static void @@ -194,48 +194,48 @@ title_widget_set_twin_item(TitleWidget* 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; + 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; } /** @@ -245,11 +245,11 @@ title_widget_triangle_draw_cb (GtkWidget *widget, GdkEventExpose *event, gpointe GtkWidget* title_widget_new(DbusmenuMenuitem *item) { - GtkWidget* widget = g_object_new (TITLE_WIDGET_TYPE, + 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); + title_widget_set_twin_item((TitleWidget*)widget, item); - return widget; + return widget; } diff --git a/src/title-widget.h b/src/title-widget.h index 029aba4..2be904a 100644 --- a/src/title-widget.h +++ b/src/title-widget.h @@ -36,11 +36,11 @@ typedef struct _TitleWidget TitleWidget; typedef struct _TitleWidgetClass TitleWidgetClass; struct _TitleWidgetClass { - GtkImageMenuItemClass parent_class; + GtkImageMenuItemClass parent_class; }; struct _TitleWidget { - GtkImageMenuItem parent; + GtkImageMenuItem parent; }; GType title_widget_get_type (void); diff --git a/src/transport-menu-item.vala b/src/transport-menu-item.vala index 36429e8..57eb67b 100644 --- a/src/transport-menu-item.vala +++ b/src/transport-menu-item.vala @@ -23,43 +23,43 @@ using DbusmenuTransport; public class TransportMenuitem : PlayerItem { - public enum action{ - PREVIOUS, - PLAY_PAUSE, - NEXT - } + public enum action{ + PREVIOUS, + PLAY_PAUSE, + NEXT + } - public enum state{ - PLAYING, - PAUSED - } - - public TransportMenuitem(PlayerController parent) + public enum state{ + PLAYING, + PAUSED + } + + public TransportMenuitem(PlayerController parent) { - Object(item_type: MENUITEM_TYPE, owner: parent); - this.property_set_int(MENUITEM_PLAY_STATE, 1); - } + Object(item_type: MENUITEM_TYPE, owner: parent); + this.property_set_int(MENUITEM_PLAY_STATE, 1); + } - public void change_play_state(state update) - { + public void change_play_state(state update) + { debug("UPDATING THE TRANSPORT DBUSMENUITEM PLAY STATE WITH VALUE %i", (int)update); - this.property_set_int(MENUITEM_PLAY_STATE, update); - } - - public override void handle_event(string name, GLib.Value input_value, uint timestamp) - { - int input = input_value.get_int(); - debug("handle_event with value %s", input.to_string()); - debug("transport owner name = %s", this.owner.name); - this.owner.mpris_bridge.transport_update((action)input); - } + this.property_set_int(MENUITEM_PLAY_STATE, update); + } + + public override void handle_event(string name, GLib.Value input_value, uint timestamp) + { + int input = input_value.get_int(); + debug("handle_event with value %s", input.to_string()); + debug("transport owner name = %s", this.owner.name); + this.owner.mpris_bridge.transport_update((action)input); + } - public static HashSet attributes_format() - { - HashSet attrs = new HashSet(); - attrs.add(MENUITEM_PLAY_STATE); - return attrs; - } + public static HashSet attributes_format() + { + HashSet attrs = new HashSet(); + attrs.add(MENUITEM_PLAY_STATE); + return attrs; + } } \ No newline at end of file diff --git a/src/transport-widget.c b/src/transport-widget.c index 5be9d4a..d9c499d 100644 --- a/src/transport-widget.c +++ b/src/transport-widget.c @@ -33,12 +33,12 @@ Uses code from ctk #define Y 7.0f #define X 80.0f #define INNER_RADIUS 12.5 -#define MIDDLE_RADIUS 13.0f +#define MIDDLE_RADIUS 13.0f #define OUTER_RADIUS 14.5f #define CIRCLE_RADIUS 21.0f #define PREV_WIDTH 25.0f #define PREV_HEIGHT 17.0f -#define NEXT_WIDTH 25.0f //PREV_WIDTH +#define NEXT_WIDTH 25.0f //PREV_WIDTH #define NEXT_HEIGHT 17.0f //PREV_HEIGHT #define TRI_WIDTH 11.0f #define TRI_HEIGHT 13.0f @@ -53,7 +53,7 @@ Uses code from ctk #define BAR_HEIGHT 24.0f #define BAR_OFFSET 10.0f #define PAUSE_X 121.0f -#define PAUSE_Y 7.0f +#define PAUSE_Y 7.0f #define PLAY_WIDTH 28.0f #define PLAY_HEIGHT 29.0f #define PLAY_PADDING 5.0f @@ -76,12 +76,12 @@ typedef struct _TransportWidgetPrivate TransportWidgetPrivate; struct _TransportWidgetPrivate { - TransportWidgetEvent current_command; - TransportWidgetEvent key_event; - TransportWidgetEvent motion_event; - TransportWidgetState current_state; - GHashTable* command_coordinates; - DbusmenuMenuitem* twin_item; + TransportWidgetEvent current_command; + TransportWidgetEvent key_event; + TransportWidgetEvent motion_event; + TransportWidgetState current_state; + GHashTable* command_coordinates; + DbusmenuMenuitem* twin_item; gboolean has_focus; }; @@ -101,18 +101,18 @@ static gboolean transport_widget_expose ( GtkWidget *button, GdkEventExpose *eve static void draw (GtkWidget* button, cairo_t *cr); /* UI and dbusmenu callbacks */ -static gboolean transport_widget_button_press_event (GtkWidget *menuitem, - GdkEventButton *event); +static gboolean transport_widget_button_press_event (GtkWidget *menuitem, + GdkEventButton *event); static gboolean transport_widget_button_release_event (GtkWidget *menuitem, - GdkEventButton *event); + GdkEventButton *event); static gboolean transport_widget_motion_notify_event (GtkWidget *menuitem, - GdkEventMotion *event); + GdkEventMotion *event); static gboolean transport_widget_leave_notify_event (GtkWidget *menuitem, - GdkEventCrossing *event); + GdkEventCrossing *event); static void transport_widget_property_update ( DbusmenuMenuitem* item, - gchar * property, - GValue * value, - gpointer userdata ); + gchar * property, + GValue * value, + gpointer userdata ); static void transport_widget_menu_hidden ( GtkWidget *menu, TransportWidget *transport); static void transport_widget_notify ( GObject *item, @@ -134,64 +134,64 @@ static void transport_widget_deselect (GtkItem* menu, gpointer Userdata); static void transport_widget_class_init (TransportWidgetClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); - g_type_class_add_private (klass, sizeof (TransportWidgetPrivate)); + g_type_class_add_private (klass, sizeof (TransportWidgetPrivate)); widget_class->button_press_event = transport_widget_button_press_event; widget_class->button_release_event = transport_widget_button_release_event; widget_class->motion_notify_event = transport_widget_motion_notify_event; widget_class->leave_notify_event = transport_widget_leave_notify_event; - widget_class->expose_event = transport_widget_expose; + widget_class->expose_event = transport_widget_expose; - gobject_class->dispose = transport_widget_dispose; + gobject_class->dispose = transport_widget_dispose; gobject_class->finalize = transport_widget_finalize; } static void transport_widget_init (TransportWidget *self) { - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(self); - priv->current_command = TRANSPORT_NADA; - priv->current_state = PAUSE; - priv->key_event = TRANSPORT_NADA; - priv->motion_event = TRANSPORT_NADA; + TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(self); + priv->current_command = TRANSPORT_NADA; + priv->current_state = PAUSE; + priv->key_event = TRANSPORT_NADA; + priv->motion_event = TRANSPORT_NADA; priv->has_focus = FALSE; - priv->command_coordinates = g_hash_table_new_full(g_direct_hash, - g_direct_equal, - NULL, - (GDestroyNotify)g_list_free); - GList* previous_list = NULL; - previous_list = g_list_insert(previous_list, GINT_TO_POINTER(15), 0); - previous_list = g_list_insert(previous_list, GINT_TO_POINTER(5), 1); - previous_list = g_list_insert(previous_list, GINT_TO_POINTER(60), 2); - previous_list = g_list_insert(previous_list, GINT_TO_POINTER(34), 3); + priv->command_coordinates = g_hash_table_new_full(g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify)g_list_free); + GList* previous_list = NULL; + previous_list = g_list_insert(previous_list, GINT_TO_POINTER(15), 0); + previous_list = g_list_insert(previous_list, GINT_TO_POINTER(5), 1); + previous_list = g_list_insert(previous_list, GINT_TO_POINTER(60), 2); + previous_list = g_list_insert(previous_list, GINT_TO_POINTER(34), 3); g_hash_table_insert(priv->command_coordinates, GINT_TO_POINTER(TRANSPORT_PREVIOUS), previous_list); - GList* play_list = NULL; - play_list = g_list_insert(play_list, GINT_TO_POINTER(58), 0); - play_list = g_list_insert(play_list, GINT_TO_POINTER(0), 1); - play_list = g_list_insert(play_list, GINT_TO_POINTER(50), 2); - play_list = g_list_insert(play_list, GINT_TO_POINTER(43), 3); + GList* play_list = NULL; + play_list = g_list_insert(play_list, GINT_TO_POINTER(58), 0); + play_list = g_list_insert(play_list, GINT_TO_POINTER(0), 1); + play_list = g_list_insert(play_list, GINT_TO_POINTER(50), 2); + play_list = g_list_insert(play_list, GINT_TO_POINTER(43), 3); - g_hash_table_insert(priv->command_coordinates, + g_hash_table_insert(priv->command_coordinates, GINT_TO_POINTER(TRANSPORT_PLAY_PAUSE), play_list); - GList* next_list = NULL; - next_list = g_list_insert(next_list, GINT_TO_POINTER(100), 0); - next_list = g_list_insert(next_list, GINT_TO_POINTER(5), 1); - next_list = g_list_insert(next_list, GINT_TO_POINTER(60), 2); - next_list = g_list_insert(next_list, GINT_TO_POINTER(34), 3); + GList* next_list = NULL; + next_list = g_list_insert(next_list, GINT_TO_POINTER(100), 0); + next_list = g_list_insert(next_list, GINT_TO_POINTER(5), 1); + next_list = g_list_insert(next_list, GINT_TO_POINTER(60), 2); + next_list = g_list_insert(next_list, GINT_TO_POINTER(34), 3); - g_hash_table_insert(priv->command_coordinates, + g_hash_table_insert(priv->command_coordinates, GINT_TO_POINTER(TRANSPORT_NEXT), next_list); - gtk_widget_set_size_request(GTK_WIDGET(self), 200, 43); + gtk_widget_set_size_request(GTK_WIDGET(self), 200, 43); g_signal_connect (G_OBJECT(self), "notify", G_CALLBACK (transport_widget_notify), @@ -211,37 +211,37 @@ transport_widget_init (TransportWidget *self) static void transport_widget_dispose (GObject *object) { - G_OBJECT_CLASS (transport_widget_parent_class)->dispose (object); + G_OBJECT_CLASS (transport_widget_parent_class)->dispose (object); } static void transport_widget_finalize (GObject *object) { - G_OBJECT_CLASS (transport_widget_parent_class)->finalize (object); + G_OBJECT_CLASS (transport_widget_parent_class)->finalize (object); } static gboolean transport_widget_expose (GtkWidget *button, GdkEventExpose *event) { - cairo_t *cr; - cr = gdk_cairo_create (button->window); + cairo_t *cr; + cr = gdk_cairo_create (button->window); //g_debug("In the playbutton's expose method, x = %i, y=%i and width: %i and height: %i'"); - cairo_rectangle (cr, + cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height); - cairo_clip(cr); + cairo_clip(cr); draw (button, cr); - cairo_destroy (cr); - return FALSE; + cairo_destroy (cr); + return FALSE; } gboolean transport_widget_is_selected ( TransportWidget* widget ) { - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(widget); + TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(widget); return priv->has_focus; } @@ -249,10 +249,10 @@ static void transport_widget_toggle_play_pause(TransportWidget* button, TransportWidgetState update) { - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button); - priv->current_state = update; - //g_debug("TransportWidget::toggle play state : %i", priv->current_state); - gtk_widget_queue_draw (GTK_WIDGET(button)); + TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button); + priv->current_state = update; + //g_debug("TransportWidget::toggle play state : %i", priv->current_state); + gtk_widget_queue_draw (GTK_WIDGET(button)); } static void @@ -274,62 +274,62 @@ static void transport_widget_menu_hidden ( GtkWidget *menu, TransportWidget *transport) { - g_return_if_fail(IS_TRANSPORT_WIDGET(transport)); - transport_widget_react_to_button_release(transport, TRANSPORT_NADA); + g_return_if_fail(IS_TRANSPORT_WIDGET(transport)); + transport_widget_react_to_button_release(transport, TRANSPORT_NADA); } static gboolean transport_widget_motion_notify_event (GtkWidget *menuitem, - GdkEventMotion *event) + GdkEventMotion *event) { - g_return_val_if_fail ( IS_TRANSPORT_WIDGET(menuitem), FALSE ); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE ( TRANSPORT_WIDGET(menuitem) ); - TransportWidgetEvent result = transport_widget_determine_motion_event ( TRANSPORT_WIDGET(menuitem), + g_return_val_if_fail ( IS_TRANSPORT_WIDGET(menuitem), FALSE ); + TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE ( TRANSPORT_WIDGET(menuitem) ); + TransportWidgetEvent result = transport_widget_determine_motion_event ( TRANSPORT_WIDGET(menuitem), event); - priv->motion_event = result; + priv->motion_event = result; cairo_t *cr; cr = gdk_cairo_create (menuitem->window); draw ( menuitem, cr ); cairo_destroy ( cr ); - return TRUE; + return TRUE; } static gboolean transport_widget_leave_notify_event (GtkWidget *menuitem, GdkEventCrossing *event) { - g_return_val_if_fail ( IS_TRANSPORT_WIDGET(menuitem), FALSE ); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE ( TRANSPORT_WIDGET(menuitem) ); - - priv->motion_event = TRANSPORT_NADA; + g_return_val_if_fail ( IS_TRANSPORT_WIDGET(menuitem), FALSE ); + TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE ( TRANSPORT_WIDGET(menuitem) ); + + priv->motion_event = TRANSPORT_NADA; cairo_t *cr; cr = gdk_cairo_create (menuitem->window); draw ( menuitem, cr ); cairo_destroy ( cr ); - return TRUE; + return TRUE; } /* keyevents */ static gboolean transport_widget_button_press_event (GtkWidget *menuitem, - GdkEventButton *event) + GdkEventButton *event) { - g_return_val_if_fail ( IS_TRANSPORT_WIDGET(menuitem), FALSE ); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE ( TRANSPORT_WIDGET(menuitem) ); + g_return_val_if_fail ( IS_TRANSPORT_WIDGET(menuitem), FALSE ); + TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE ( TRANSPORT_WIDGET(menuitem) ); TransportWidgetEvent result = transport_widget_determine_button_event ( TRANSPORT_WIDGET(menuitem), event); - if(result != TRANSPORT_NADA){ + if(result != TRANSPORT_NADA){ priv->current_command = result; cairo_t *cr; cr = gdk_cairo_create (menuitem->window); draw ( menuitem, cr ); cairo_destroy ( cr ); } - return TRUE; + return TRUE; } static gboolean @@ -339,14 +339,14 @@ transport_widget_button_release_event (GtkWidget *menuitem, //g_debug("TransportWidget::menu_release_event"); g_return_val_if_fail(IS_TRANSPORT_WIDGET(menuitem), FALSE); TransportWidget* transport = TRANSPORT_WIDGET(menuitem); - TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); + TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); TransportWidgetEvent result = transport_widget_determine_button_event ( transport, event ); if(result != TRANSPORT_NADA){ GValue value = {0}; g_value_init(&value, G_TYPE_INT); //g_debug("TransportWidget::menu_press_event - going to send value %i", (int)result); - g_value_set_int(&value, (int)result); + g_value_set_int(&value, (int)result); dbusmenu_menuitem_handle_event ( priv->twin_item, "Transport state change", &value, @@ -361,7 +361,7 @@ static void transport_widget_select (GtkItem* item, gpointer Userdata) { TransportWidget* transport = TRANSPORT_WIDGET(item); - TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); + TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); priv->has_focus = TRUE; } @@ -369,7 +369,7 @@ static void transport_widget_deselect (GtkItem* item, gpointer Userdata) { TransportWidget* transport = TRANSPORT_WIDGET(item); - TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); + TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); priv->has_focus = FALSE; } @@ -391,7 +391,7 @@ transport_widget_react_to_key_press_event ( TransportWidget* transport, printf("transport_widget_react_to_key_press_event: before drawing\n"); cr = gdk_cairo_create ( GTK_WIDGET(transport)->window ); draw ( GTK_WIDGET(transport), cr ); - cairo_destroy (cr); + cairo_destroy (cr); } } @@ -400,11 +400,11 @@ transport_widget_react_to_key_release_event ( TransportWidget* transport, TransportWidgetEvent transport_event ) { if(transport_event != TRANSPORT_NADA){ - TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); + TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); GValue value = {0}; g_value_init(&value, G_TYPE_INT); //g_debug("TransportWidget::menu_press_event - going to send value %i", (int)result); - g_value_set_int(&value, (int)transport_event); + g_value_set_int(&value, (int)transport_event); dbusmenu_menuitem_handle_event ( priv->twin_item, "Transport state change", &value, @@ -417,7 +417,7 @@ transport_widget_react_to_key_release_event ( TransportWidget* transport, void transport_widget_focus_update ( TransportWidget* transport, gboolean focus ) { - TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); + TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); priv->has_focus = focus; g_debug("new focus update = %i", focus); } @@ -426,65 +426,65 @@ static TransportWidgetEvent transport_widget_determine_button_event( TransportWidget* button, GdkEventButton* event ) { - //g_debug("event x coordinate = %f", event->x); - //g_debug("event y coordinate = %f", event->y); - TransportWidgetEvent button_event = TRANSPORT_NADA; - // For now very simple rectangular collision detection - if(event->x > 67 && event->x < 112 - && event->y > 12 && event->y < 40){ - button_event = TRANSPORT_PREVIOUS; - } - else if(event->x > 111 && event->x < 153 - && event->y > 5 && event->y < 47){ - button_event = TRANSPORT_PLAY_PAUSE; - } - else if(event->x > 152 && event->x < 197 - && event->y > 12 && event->y < 40){ - button_event = TRANSPORT_NEXT; - } - return button_event; + //g_debug("event x coordinate = %f", event->x); + //g_debug("event y coordinate = %f", event->y); + TransportWidgetEvent button_event = TRANSPORT_NADA; + // For now very simple rectangular collision detection + if(event->x > 67 && event->x < 112 + && event->y > 12 && event->y < 40){ + button_event = TRANSPORT_PREVIOUS; + } + else if(event->x > 111 && event->x < 153 + && event->y > 5 && event->y < 47){ + button_event = TRANSPORT_PLAY_PAUSE; + } + else if(event->x > 152 && event->x < 197 + && event->y > 12 && event->y < 40){ + button_event = TRANSPORT_NEXT; + } + return button_event; } static TransportWidgetEvent transport_widget_determine_motion_event( TransportWidget* button, GdkEventMotion* event ) { -/* g_debug("event x coordinate = %f", event->x);*/ -/* g_debug("event y coordinate = %f", event->y);*/ - TransportWidgetEvent motion_event = TRANSPORT_NADA; - // For now very simple rectangular collision detection - if(event->x > 67 && event->x < 112 - && event->y > 12 && event->y < 40){ - motion_event = TRANSPORT_PREVIOUS; - } - else if(event->x > 111 && event->x < 153 - && event->y > 5 && event->y < 47){ - motion_event = TRANSPORT_PLAY_PAUSE; - } - else if(event->x > 152 && event->x < 197 - && event->y > 12 && event->y < 40){ - motion_event = TRANSPORT_NEXT; - } - return motion_event; +/* g_debug("event x coordinate = %f", event->x);*/ +/* g_debug("event y coordinate = %f", event->y);*/ + TransportWidgetEvent motion_event = TRANSPORT_NADA; + // For now very simple rectangular collision detection + if(event->x > 67 && event->x < 112 + && event->y > 12 && event->y < 40){ + motion_event = TRANSPORT_PREVIOUS; + } + else if(event->x > 111 && event->x < 153 + && event->y > 5 && event->y < 47){ + motion_event = TRANSPORT_PLAY_PAUSE; + } + else if(event->x > 152 && event->x < 197 + && event->y > 12 && event->y < 40){ + motion_event = TRANSPORT_NEXT; + } + return motion_event; } static void transport_widget_react_to_button_release ( TransportWidget* button, TransportWidgetEvent command ) { - g_return_if_fail(IS_TRANSPORT_WIDGET(button)); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button); - if(priv->current_command != TRANSPORT_NADA && - command != TRANSPORT_NADA){ - priv->current_command = command; - } - cairo_t *cr; - cr = gdk_cairo_create ( GTK_WIDGET(button)->window ); - - priv->current_command = TRANSPORT_NADA; + g_return_if_fail(IS_TRANSPORT_WIDGET(button)); + TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button); + if(priv->current_command != TRANSPORT_NADA && + command != TRANSPORT_NADA){ + priv->current_command = command; + } + cairo_t *cr; + cr = gdk_cairo_create ( GTK_WIDGET(button)->window ); + + priv->current_command = TRANSPORT_NADA; priv->key_event = TRANSPORT_NADA; - draw ( GTK_WIDGET(button), cr ); - cairo_destroy (cr); + draw ( GTK_WIDGET(button), cr ); + cairo_destroy (cr); } /// internal helper functions ////////////////////////////////////////////////// @@ -498,182 +498,182 @@ draw_gradient (cairo_t* cr, double* rgba_start, double* rgba_end) { - cairo_pattern_t* pattern = NULL; - - cairo_move_to (cr, x, y); - cairo_line_to (cr, x + w - 2.0f * r, y); - cairo_arc (cr, - x + w - 2.0f * r, - y + r, - r, - -90.0f * G_PI / 180.0f, - 90.0f * G_PI / 180.0f); - cairo_line_to (cr, x, y + 2.0f * r); - cairo_arc (cr, - x, - y + r, - r, - 90.0f * G_PI / 180.0f, - 270.0f * G_PI / 180.0f); - cairo_close_path (cr); - - pattern = cairo_pattern_create_linear (x, y, x, y + 2.0f * r); - cairo_pattern_add_color_stop_rgba (pattern, - 0.0f, - rgba_start[0], - rgba_start[1], - rgba_start[2], - rgba_start[3]); - cairo_pattern_add_color_stop_rgba (pattern, - 1.0f, - rgba_end[0], - rgba_end[1], - rgba_end[2], - rgba_end[3]); - cairo_set_source (cr, pattern); - cairo_fill (cr); - cairo_pattern_destroy (pattern); + cairo_pattern_t* pattern = NULL; + + cairo_move_to (cr, x, y); + cairo_line_to (cr, x + w - 2.0f * r, y); + cairo_arc (cr, + x + w - 2.0f * r, + y + r, + r, + -90.0f * G_PI / 180.0f, + 90.0f * G_PI / 180.0f); + cairo_line_to (cr, x, y + 2.0f * r); + cairo_arc (cr, + x, + y + r, + r, + 90.0f * G_PI / 180.0f, + 270.0f * G_PI / 180.0f); + cairo_close_path (cr); + + pattern = cairo_pattern_create_linear (x, y, x, y + 2.0f * r); + cairo_pattern_add_color_stop_rgba (pattern, + 0.0f, + rgba_start[0], + rgba_start[1], + rgba_start[2], + rgba_start[3]); + cairo_pattern_add_color_stop_rgba (pattern, + 1.0f, + rgba_end[0], + rgba_end[1], + rgba_end[2], + rgba_end[3]); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); } static void draw_circle (cairo_t* cr, - double x, - double y, - double r, - double* rgba_start, - double* rgba_end) + double x, + double y, + double r, + double* rgba_start, + double* rgba_end) { - cairo_pattern_t* pattern = NULL; - - cairo_move_to (cr, x, y); - cairo_arc (cr, - x + r, - y + r, - r, - 0.0f * G_PI / 180.0f, - 360.0f * G_PI / 180.0f); - - pattern = cairo_pattern_create_linear (x, y, x, y + 2.0f * r); - cairo_pattern_add_color_stop_rgba (pattern, - 0.0f, - rgba_start[0], - rgba_start[1], - rgba_start[2], - rgba_start[3]); - cairo_pattern_add_color_stop_rgba (pattern, - 1.0f, - rgba_end[0], - rgba_end[1], - rgba_end[2], - rgba_end[3]); - cairo_set_source (cr, pattern); - cairo_fill (cr); - cairo_pattern_destroy (pattern); + cairo_pattern_t* pattern = NULL; + + cairo_move_to (cr, x, y); + cairo_arc (cr, + x + r, + y + r, + r, + 0.0f * G_PI / 180.0f, + 360.0f * G_PI / 180.0f); + + pattern = cairo_pattern_create_linear (x, y, x, y + 2.0f * r); + cairo_pattern_add_color_stop_rgba (pattern, + 0.0f, + rgba_start[0], + rgba_start[1], + rgba_start[2], + rgba_start[3]); + cairo_pattern_add_color_stop_rgba (pattern, + 1.0f, + rgba_end[0], + rgba_end[1], + rgba_end[2], + rgba_end[3]); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); } static void _setup (cairo_t** cr, - cairo_surface_t** surf, - gint width, - gint height) + cairo_surface_t** surf, + gint width, + gint height) { - if (!cr || !surf) - return; - - *surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); - *cr = cairo_create (*surf); - cairo_scale (*cr, 1.0f, 1.0f); - cairo_set_operator (*cr, CAIRO_OPERATOR_CLEAR); - cairo_paint (*cr); - cairo_set_operator (*cr, CAIRO_OPERATOR_OVER); + if (!cr || !surf) + return; + + *surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + *cr = cairo_create (*surf); + cairo_scale (*cr, 1.0f, 1.0f); + cairo_set_operator (*cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (*cr); + cairo_set_operator (*cr, CAIRO_OPERATOR_OVER); } static void _mask_prev (cairo_t* cr, - double x, - double y, - double tri_width, - double tri_height, - double tri_offset) + double x, + double y, + double tri_width, + double tri_height, + double tri_offset) { - if (!cr) - return; - - cairo_move_to (cr, x, y + tri_height / 2.0f); - cairo_line_to (cr, x + tri_width, y); - cairo_line_to (cr, x + tri_width, y + tri_height); - x += tri_offset; - cairo_move_to (cr, x, y + tri_height / 2.0f); - cairo_line_to (cr, x + tri_width, y); - cairo_line_to (cr, x + tri_width, y + tri_height); - x -= tri_offset; - cairo_rectangle (cr, x, y, 2.5f, tri_height); - cairo_close_path (cr); + if (!cr) + return; + + cairo_move_to (cr, x, y + tri_height / 2.0f); + cairo_line_to (cr, x + tri_width, y); + cairo_line_to (cr, x + tri_width, y + tri_height); + x += tri_offset; + cairo_move_to (cr, x, y + tri_height / 2.0f); + cairo_line_to (cr, x + tri_width, y); + cairo_line_to (cr, x + tri_width, y + tri_height); + x -= tri_offset; + cairo_rectangle (cr, x, y, 2.5f, tri_height); + cairo_close_path (cr); } static void _mask_next (cairo_t* cr, - double x, - double y, - double tri_width, - double tri_height, - double tri_offset) + double x, + double y, + double tri_width, + double tri_height, + double tri_offset) { - if (!cr) - return; - - cairo_move_to (cr, x, y); - cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); - cairo_line_to (cr, x, y + tri_height); - x += tri_offset; - cairo_move_to (cr, x, y); - cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); - cairo_line_to (cr, x, y + tri_height); - x -= tri_offset; - x += 2.0f * tri_width - tri_offset - 1.0f; - cairo_rectangle (cr, x, y, 2.5f, tri_height); - - cairo_close_path (cr); + if (!cr) + return; + + cairo_move_to (cr, x, y); + cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); + cairo_line_to (cr, x, y + tri_height); + x += tri_offset; + cairo_move_to (cr, x, y); + cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); + cairo_line_to (cr, x, y + tri_height); + x -= tri_offset; + x += 2.0f * tri_width - tri_offset - 1.0f; + cairo_rectangle (cr, x, y, 2.5f, tri_height); + + cairo_close_path (cr); } static void _mask_pause (cairo_t* cr, - double x, - double y, - double bar_width, - double bar_height, - double bar_offset) + double x, + double y, + double bar_width, + double bar_height, + double bar_offset) { - if (!cr) - return; + if (!cr) + return; - cairo_set_line_width (cr, bar_width); - cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_width (cr, bar_width); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); - x += bar_width; - y += bar_width; - cairo_move_to (cr, x, y); - cairo_line_to (cr, x, y + bar_height); - cairo_move_to (cr, x + bar_offset, y); - cairo_line_to (cr, x + bar_offset, y + bar_height); + x += bar_width; + y += bar_width; + cairo_move_to (cr, x, y); + cairo_line_to (cr, x, y + bar_height); + cairo_move_to (cr, x + bar_offset, y); + cairo_line_to (cr, x + bar_offset, y + bar_height); } static void _mask_play (cairo_t* cr, - double x, - double y, - double tri_width, - double tri_height) + double x, + double y, + double tri_width, + double tri_height) { - if (!cr) - return; - - cairo_move_to (cr, x, y); - cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); - cairo_line_to (cr, x, y + tri_height); - cairo_close_path (cr); - + if (!cr) + return; + + cairo_move_to (cr, x, y); + cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); + cairo_line_to (cr, x, y + tri_height); + cairo_close_path (cr); + } static void @@ -686,68 +686,68 @@ _fill (cairo_t* cr, double* rgba_end, gboolean stroke) { - cairo_pattern_t* pattern = NULL; - - if (!cr || !rgba_start || !rgba_end) - return; - - pattern = cairo_pattern_create_linear (x_start, y_start, x_end, y_end); - cairo_pattern_add_color_stop_rgba (pattern, - 0.0f, - rgba_start[0], - rgba_start[1], - rgba_start[2], - rgba_start[3]); - cairo_pattern_add_color_stop_rgba (pattern, - 1.0f, - rgba_end[0], - rgba_end[1], - rgba_end[2], - rgba_end[3]); - cairo_set_source (cr, pattern); - if (stroke) - cairo_stroke (cr); - else - cairo_fill (cr); - cairo_pattern_destroy (pattern); + cairo_pattern_t* pattern = NULL; + + if (!cr || !rgba_start || !rgba_end) + return; + + pattern = cairo_pattern_create_linear (x_start, y_start, x_end, y_end); + cairo_pattern_add_color_stop_rgba (pattern, + 0.0f, + rgba_start[0], + rgba_start[1], + rgba_start[2], + rgba_start[3]); + cairo_pattern_add_color_stop_rgba (pattern, + 1.0f, + rgba_end[0], + rgba_end[1], + rgba_end[2], + rgba_end[3]); + cairo_set_source (cr, pattern); + if (stroke) + cairo_stroke (cr); + else + cairo_fill (cr); + cairo_pattern_destroy (pattern); } static void _finalize (cairo_t* cr, - cairo_t** cr_surf, - cairo_surface_t** surf, - double x, - double y) + cairo_t** cr_surf, + cairo_surface_t** surf, + double x, + double y) { - if (!cr || !cr_surf || !surf) - return; + if (!cr || !cr_surf || !surf) + return; - cairo_set_source_surface (cr, *surf, x, y); - cairo_paint (cr); - cairo_surface_destroy (*surf); - cairo_destroy (*cr_surf); + cairo_set_source_surface (cr, *surf, x, y); + cairo_paint (cr); + cairo_surface_destroy (*surf); + cairo_destroy (*cr_surf); } static void _finalize_repaint (cairo_t* cr, - cairo_t** cr_surf, - cairo_surface_t** surf, - double x, - double y, - int repaints) + cairo_t** cr_surf, + cairo_surface_t** surf, + double x, + double y, + int repaints) { - if (!cr || !cr_surf || !surf) - return; - - while (repaints > 0) - { - cairo_set_source_surface (cr, *surf, x, y); - cairo_paint (cr); - repaints--; - } - - cairo_surface_destroy (*surf); - cairo_destroy (*cr_surf); + if (!cr || !cr_surf || !surf) + return; + + while (repaints > 0) + { + cairo_set_source_surface (cr, *surf, x, y); + cairo_paint (cr); + repaints--; + } + + cairo_surface_destroy (*surf); + cairo_destroy (*cr_surf); } static void @@ -755,74 +755,74 @@ _color_rgb_to_hls (gdouble *r, gdouble *g, gdouble *b) { - gdouble min; - gdouble max; - gdouble red; - gdouble green; - gdouble blue; - gdouble h, l, s; - gdouble delta; - - red = *r; - green = *g; - blue = *b; - - if (red > green) - { - if (red > blue) - max = red; - else - max = blue; - - if (green < blue) - min = green; - else - min = blue; - } - else - { - if (green > blue) - max = green; - else - max = blue; - - if (red < blue) - min = red; - else - min = blue; - } - l = (max+min)/2; + gdouble min; + gdouble max; + gdouble red; + gdouble green; + gdouble blue; + gdouble h, l, s; + gdouble delta; + + red = *r; + green = *g; + blue = *b; + + if (red > green) + { + if (red > blue) + max = red; + else + max = blue; + + if (green < blue) + min = green; + else + min = blue; + } + else + { + if (green > blue) + max = green; + else + max = blue; + + if (red < blue) + min = red; + else + min = blue; + } + l = (max+min)/2; if (fabs (max-min) < 0.0001) { - h = 0; - s = 0; - } - else + h = 0; + s = 0; + } + else { - if (l <= 0.5) - s = (max-min)/(max+min); - else - s = (max-min)/(2-max-min); + if (l <= 0.5) + s = (max-min)/(max+min); + else + s = (max-min)/(2-max-min); - delta = (max -min) != 0 ? (max -min) : 1; + delta = (max -min) != 0 ? (max -min) : 1; if(delta == 0) delta = 1; - if (red == max) - h = (green-blue)/delta; - else if (green == max) - h = 2+(blue-red)/delta; - else if (blue == max) - h = 4+(red-green)/delta; - - h *= 60; - if (h < 0.0) - h += 360; - } - - *r = h; - *g = l; - *b = s; + if (red == max) + h = (green-blue)/delta; + else if (green == max) + h = 2+(blue-red)/delta; + else if (blue == max) + h = 4+(red-green)/delta; + + h *= 60; + if (h < 0.0) + h += 360; + } + + *r = h; + *g = l; + *b = s; } static void @@ -830,866 +830,866 @@ _color_hls_to_rgb (gdouble *h, gdouble *l, gdouble *s) { - gdouble hue; - gdouble lightness; - gdouble saturation; - gdouble m1, m2; - gdouble r, g, b; - - lightness = *l; - saturation = *s; - - if (lightness <= 0.5) - m2 = lightness*(1+saturation); - else - m2 = lightness+saturation-lightness*saturation; - - m1 = 2*lightness-m2; - - if (saturation == 0) - { - *h = lightness; - *l = lightness; - *s = lightness; - } - else - { - hue = *h+120; - while (hue > 360) - hue -= 360; - while (hue < 0) - hue += 360; - - if (hue < 60) - r = m1+(m2-m1)*hue/60; - else if (hue < 180) - r = m2; - else if (hue < 240) - r = m1+(m2-m1)*(240-hue)/60; - else - r = m1; - - hue = *h; - while (hue > 360) - hue -= 360; - while (hue < 0) - hue += 360; - - if (hue < 60) - g = m1+(m2-m1)*hue/60; - else if (hue < 180) - g = m2; - else if (hue < 240) - g = m1+(m2-m1)*(240-hue)/60; - else - g = m1; - - hue = *h-120; - while (hue > 360) - hue -= 360; - while (hue < 0) - hue += 360; - - if (hue < 60) - b = m1+(m2-m1)*hue/60; - else if (hue < 180) - b = m2; - else if (hue < 240) - b = m1+(m2-m1)*(240-hue)/60; - else - b = m1; - - *h = r; - *l = g; - *s = b; - } + gdouble hue; + gdouble lightness; + gdouble saturation; + gdouble m1, m2; + gdouble r, g, b; + + lightness = *l; + saturation = *s; + + if (lightness <= 0.5) + m2 = lightness*(1+saturation); + else + m2 = lightness+saturation-lightness*saturation; + + m1 = 2*lightness-m2; + + if (saturation == 0) + { + *h = lightness; + *l = lightness; + *s = lightness; + } + else + { + hue = *h+120; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + r = m1+(m2-m1)*hue/60; + else if (hue < 180) + r = m2; + else if (hue < 240) + r = m1+(m2-m1)*(240-hue)/60; + else + r = m1; + + hue = *h; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + g = m1+(m2-m1)*hue/60; + else if (hue < 180) + g = m2; + else if (hue < 240) + g = m1+(m2-m1)*(240-hue)/60; + else + g = m1; + + hue = *h-120; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + b = m1+(m2-m1)*hue/60; + else if (hue < 180) + b = m2; + else if (hue < 240) + b = m1+(m2-m1)*(240-hue)/60; + else + b = m1; + + *h = r; + *l = g; + *s = b; + } } void _color_shade (const CairoColorRGB *a, float k, CairoColorRGB *b) { - double red; - double green; - double blue; - - red = a->r; - green = a->g; - blue = a->b; - - if (k == 1.0) - { - b->r = red; - b->g = green; - b->b = blue; - return; - } - - _color_rgb_to_hls (&red, &green, &blue); - - green *= k; - if (green > 1.0) - green = 1.0; - else if (green < 0.0) - green = 0.0; - - blue *= k; - if (blue > 1.0) - blue = 1.0; - else if (blue < 0.0) - blue = 0.0; - - _color_hls_to_rgb (&red, &green, &blue); - - b->r = red; - b->g = green; - b->b = blue; + double red; + double green; + double blue; + + red = a->r; + green = a->g; + blue = a->b; + + if (k == 1.0) + { + b->r = red; + b->g = green; + b->b = blue; + return; + } + + _color_rgb_to_hls (&red, &green, &blue); + + green *= k; + if (green > 1.0) + green = 1.0; + else if (green < 0.0) + green = 0.0; + + blue *= k; + if (blue > 1.0) + blue = 1.0; + else if (blue < 0.0) + blue = 0.0; + + _color_hls_to_rgb (&red, &green, &blue); + + b->r = red; + b->g = green; + b->b = blue; } static inline void _blurinner (guchar* pixel, - gint* zR, - gint* zG, - gint* zB, - gint* zA, - gint alpha, - gint aprec, - gint zprec) + gint* zR, + gint* zG, + gint* zB, + gint* zA, + gint alpha, + gint aprec, + gint zprec) { - gint R; - gint G; - gint B; - guchar A; - - R = *pixel; - G = *(pixel + 1); - B = *(pixel + 2); - A = *(pixel + 3); - - *zR += (alpha * ((R << zprec) - *zR)) >> aprec; - *zG += (alpha * ((G << zprec) - *zG)) >> aprec; - *zB += (alpha * ((B << zprec) - *zB)) >> aprec; - *zA += (alpha * ((A << zprec) - *zA)) >> aprec; - - *pixel = *zR >> zprec; - *(pixel + 1) = *zG >> zprec; - *(pixel + 2) = *zB >> zprec; - *(pixel + 3) = *zA >> zprec; + gint R; + gint G; + gint B; + guchar A; + + R = *pixel; + G = *(pixel + 1); + B = *(pixel + 2); + A = *(pixel + 3); + + *zR += (alpha * ((R << zprec) - *zR)) >> aprec; + *zG += (alpha * ((G << zprec) - *zG)) >> aprec; + *zB += (alpha * ((B << zprec) - *zB)) >> aprec; + *zA += (alpha * ((A << zprec) - *zA)) >> aprec; + + *pixel = *zR >> zprec; + *(pixel + 1) = *zG >> zprec; + *(pixel + 2) = *zB >> zprec; + *(pixel + 3) = *zA >> zprec; } static inline void _blurrow (guchar* pixels, - gint width, - gint height, - gint channels, - gint line, - gint alpha, - gint aprec, - gint zprec) + gint width, + gint height, + gint channels, + gint line, + gint alpha, + gint aprec, + gint zprec) { - gint zR; - gint zG; - gint zB; - gint zA; - gint index; - guchar* scanline; - - scanline = &(pixels[line * width * channels]); - - zR = *scanline << zprec; - zG = *(scanline + 1) << zprec; - zB = *(scanline + 2) << zprec; - zA = *(scanline + 3) << zprec; - - for (index = 0; index < width; index ++) - _blurinner (&scanline[index * channels], - &zR, - &zG, - &zB, - &zA, - alpha, - aprec, - zprec); - - for (index = width - 2; index >= 0; index--) - _blurinner (&scanline[index * channels], - &zR, - &zG, - &zB, - &zA, - alpha, - aprec, - zprec); + gint zR; + gint zG; + gint zB; + gint zA; + gint index; + guchar* scanline; + + scanline = &(pixels[line * width * channels]); + + zR = *scanline << zprec; + zG = *(scanline + 1) << zprec; + zB = *(scanline + 2) << zprec; + zA = *(scanline + 3) << zprec; + + for (index = 0; index < width; index ++) + _blurinner (&scanline[index * channels], + &zR, + &zG, + &zB, + &zA, + alpha, + aprec, + zprec); + + for (index = width - 2; index >= 0; index--) + _blurinner (&scanline[index * channels], + &zR, + &zG, + &zB, + &zA, + alpha, + aprec, + zprec); } static inline void _blurcol (guchar* pixels, - gint width, - gint height, - gint channels, - gint x, - gint alpha, - gint aprec, - gint zprec) + gint width, + gint height, + gint channels, + gint x, + gint alpha, + gint aprec, + gint zprec) { - gint zR; - gint zG; - gint zB; - gint zA; - gint index; - guchar* ptr; - - ptr = pixels; - - ptr += x * channels; - - zR = *((guchar*) ptr ) << zprec; - zG = *((guchar*) ptr + 1) << zprec; - zB = *((guchar*) ptr + 2) << zprec; - zA = *((guchar*) ptr + 3) << zprec; - - for (index = width; index < (height - 1) * width; index += width) - _blurinner ((guchar*) &ptr[index * channels], - &zR, - &zG, - &zB, - &zA, - alpha, - aprec, - zprec); - - for (index = (height - 2) * width; index >= 0; index -= width) - _blurinner ((guchar*) &ptr[index * channels], - &zR, - &zG, - &zB, - &zA, - alpha, - aprec, - zprec); + gint zR; + gint zG; + gint zB; + gint zA; + gint index; + guchar* ptr; + + ptr = pixels; + + ptr += x * channels; + + zR = *((guchar*) ptr ) << zprec; + zG = *((guchar*) ptr + 1) << zprec; + zB = *((guchar*) ptr + 2) << zprec; + zA = *((guchar*) ptr + 3) << zprec; + + for (index = width; index < (height - 1) * width; index += width) + _blurinner ((guchar*) &ptr[index * channels], + &zR, + &zG, + &zB, + &zA, + alpha, + aprec, + zprec); + + for (index = (height - 2) * width; index >= 0; index -= width) + _blurinner ((guchar*) &ptr[index * channels], + &zR, + &zG, + &zB, + &zA, + alpha, + aprec, + zprec); } void _expblur (guchar* pixels, - gint width, - gint height, - gint channels, - gint radius, - gint aprec, - gint zprec) + gint width, + gint height, + gint channels, + gint radius, + gint aprec, + gint zprec) { - gint alpha; - gint row = 0; - gint col = 0; - - if (radius < 1) - return; - - // calculate the alpha such that 90% of - // the kernel is within the radius. - // (Kernel extends to infinity) - alpha = (gint) ((1 << aprec) * (1.0f - expf (-2.3f / (radius + 1.f)))); - - for (; row < height; row++) - _blurrow (pixels, - width, - height, - channels, - row, - alpha, - aprec, - zprec); - - for(; col < width; col++) - _blurcol (pixels, - width, - height, - channels, - col, - alpha, - aprec, - zprec); - - return; + gint alpha; + gint row = 0; + gint col = 0; + + if (radius < 1) + return; + + // calculate the alpha such that 90% of + // the kernel is within the radius. + // (Kernel extends to infinity) + alpha = (gint) ((1 << aprec) * (1.0f - expf (-2.3f / (radius + 1.f)))); + + for (; row < height; row++) + _blurrow (pixels, + width, + height, + channels, + row, + alpha, + aprec, + zprec); + + for(; col < width; col++) + _blurcol (pixels, + width, + height, + channels, + col, + alpha, + aprec, + zprec); + + return; } void _surface_blur (cairo_surface_t* surface, guint radius) { - guchar* pixels; - guint width; - guint height; - cairo_format_t format; - - // before we mess with the surface execute any pending drawing - cairo_surface_flush (surface); - - pixels = cairo_image_surface_get_data (surface); - width = cairo_image_surface_get_width (surface); - height = cairo_image_surface_get_height (surface); - format = cairo_image_surface_get_format (surface); - - switch (format) - { - case CAIRO_FORMAT_ARGB32: - _expblur (pixels, width, height, 4, radius, 16, 7); - break; - - case CAIRO_FORMAT_RGB24: - _expblur (pixels, width, height, 3, radius, 16, 7); - break; - - case CAIRO_FORMAT_A8: - _expblur (pixels, width, height, 1, radius, 16, 7); - break; - - default : - // do nothing - break; - } - - // inform cairo we altered the surfaces contents - cairo_surface_mark_dirty (surface); + guchar* pixels; + guint width; + guint height; + cairo_format_t format; + + // before we mess with the surface execute any pending drawing + cairo_surface_flush (surface); + + pixels = cairo_image_surface_get_data (surface); + width = cairo_image_surface_get_width (surface); + height = cairo_image_surface_get_height (surface); + format = cairo_image_surface_get_format (surface); + + switch (format) + { + case CAIRO_FORMAT_ARGB32: + _expblur (pixels, width, height, 4, radius, 16, 7); + break; + + case CAIRO_FORMAT_RGB24: + _expblur (pixels, width, height, 3, radius, 16, 7); + break; + + case CAIRO_FORMAT_A8: + _expblur (pixels, width, height, 1, radius, 16, 7); + break; + + default : + // do nothing + break; + } + + // inform cairo we altered the surfaces contents + cairo_surface_mark_dirty (surface); } static void draw (GtkWidget* button, cairo_t *cr) { - g_return_if_fail(IS_TRANSPORT_WIDGET(button)); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button); - - cairo_surface_t* surf = NULL; - cairo_t* cr_surf = NULL; - - cairo_translate (cr, button->allocation.x, button->allocation.y); - - //g_debug("button x allocation = %i", button->allocation.x); - //g_debug("button y allocation = %i", button->allocation.y); - - GtkStyle *style; - - CairoColorRGB bg_color, fg_color, bg_selected, bg_prelight; - CairoColorRGB color_middle[2], color_middle_prelight[2], color_outer[2], color_outer_prelight[2], - color_play_outer[2], color_play_outer_prelight[2], - color_button[4], color_button_shadow, color_inner[2], color_inner_compressed[2]; - - style = gtk_widget_get_style (button); - - bg_color.r = style->bg[0].red/65535.0; - bg_color.g = style->bg[0].green/65535.0; - bg_color.b = style->bg[0].blue/65535.0; - - bg_prelight.r = style->bg[GTK_STATE_PRELIGHT].red/65535.0; - bg_prelight.g = style->bg[GTK_STATE_PRELIGHT].green/65535.0; - bg_prelight.b = style->bg[GTK_STATE_PRELIGHT].blue/65535.0; - - bg_selected.r = style->bg[GTK_STATE_SELECTED].red/65535.0; - bg_selected.g = style->bg[GTK_STATE_SELECTED].green/65535.0; - bg_selected.b = style->bg[GTK_STATE_SELECTED].blue/65535.0; - - fg_color.r = style->fg[0].red/65535.0; - fg_color.g = style->fg[0].green/65535.0; - fg_color.b = style->fg[0].blue/65535.0; - - _color_shade (&bg_color, MIDDLE_START_SHADE, &color_middle[0]); - _color_shade (&bg_color, MIDDLE_END_SHADE, &color_middle[1]); - _color_shade (&bg_prelight, MIDDLE_START_SHADE, &color_middle_prelight[0]); - _color_shade (&bg_prelight, MIDDLE_END_SHADE, &color_middle_prelight[1]); - _color_shade (&bg_color, OUTER_START_SHADE, &color_outer[0]); - _color_shade (&bg_color, OUTER_END_SHADE, &color_outer[1]); - _color_shade (&bg_prelight, OUTER_START_SHADE, &color_outer_prelight[0]); - _color_shade (&bg_prelight, OUTER_END_SHADE, &color_outer_prelight[1]); - _color_shade (&bg_color, OUTER_PLAY_START_SHADE, &color_play_outer[0]); - _color_shade (&bg_color, OUTER_PLAY_END_SHADE, &color_play_outer[1]); - _color_shade (&bg_prelight, OUTER_PLAY_START_SHADE, &color_play_outer_prelight[0]); - _color_shade (&bg_prelight, OUTER_PLAY_END_SHADE, &color_play_outer_prelight[1]); - _color_shade (&bg_color, INNER_START_SHADE, &color_inner[0]); - _color_shade (&bg_color, INNER_END_SHADE, &color_inner[1]); - _color_shade (&fg_color, BUTTON_START_SHADE, &color_button[0]); - _color_shade (&fg_color, BUTTON_END_SHADE, &color_button[1]); - _color_shade (&bg_color, BUTTON_SHADOW_SHADE, &color_button[2]); - _color_shade (&bg_color, SHADOW_BUTTON_SHADE, &color_button_shadow); - _color_shade (&bg_selected, 1.0, &color_button[3]); - _color_shade (&bg_color, INNER_COMPRESSED_START_SHADE, &color_inner_compressed[0]); - _color_shade (&bg_color, INNER_COMPRESSED_END_SHADE, &color_inner_compressed[1]); - - double MIDDLE_END[] = {color_middle[0].r, color_middle[0].g, color_middle[0].b, 1.0f}; - double MIDDLE_START[] = {color_middle[1].r, color_middle[1].g, color_middle[1].b, 1.0f}; - double MIDDLE_END_PRELIGHT[] = {color_middle_prelight[0].r, color_middle_prelight[0].g, color_middle_prelight[0].b, 1.0f}; - double MIDDLE_START_PRELIGHT[] = {color_middle_prelight[1].r, color_middle_prelight[1].g, color_middle_prelight[1].b, 1.0f}; - double OUTER_END[] = {color_outer[0].r, color_outer[0].g, color_outer[0].b, 1.0f}; - double OUTER_START[] = {color_outer[1].r, color_outer[1].g, color_outer[1].b, 1.0f}; - double OUTER_END_PRELIGHT[] = {color_outer_prelight[0].r, color_outer_prelight[0].g, color_outer_prelight[0].b, 1.0f}; - double OUTER_START_PRELIGHT[] = {color_outer_prelight[1].r, color_outer_prelight[1].g, color_outer_prelight[1].b, 1.0f}; - double SHADOW_BUTTON[] = {color_button_shadow.r, color_button_shadow.g, color_button_shadow.b, 0.3f}; - double OUTER_PLAY_END[] = {color_play_outer[0].r, color_play_outer[0].g, color_play_outer[0].b, 1.0f}; - double OUTER_PLAY_START[] = {color_play_outer[1].r, color_play_outer[1].g, color_play_outer[1].b, 1.0f}; - double OUTER_PLAY_END_PRELIGHT[] = {color_play_outer_prelight[0].r, color_play_outer_prelight[0].g, color_play_outer_prelight[0].b, 1.0f}; - double OUTER_PLAY_START_PRELIGHT[] = {color_play_outer_prelight[1].r, color_play_outer_prelight[1].g, color_play_outer_prelight[1].b, 1.0f}; - double BUTTON_END[] = {color_button[0].r, color_button[0].g, color_button[0].b, 1.0f}; - double BUTTON_START[] = {color_button[1].r, color_button[1].g, color_button[1].b, 1.0f}; - double BUTTON_SHADOW[] = {color_button[2].r, color_button[2].g, color_button[2].b, 0.75f}; - double BUTTON_SHADOW_FOCUS[] = {color_button[3].r, color_button[3].g, color_button[3].b, 1.0f}; - double INNER_COMPRESSED_END[] = {color_inner_compressed[1].r, color_inner_compressed[1].g, color_inner_compressed[1].b, 1.0f}; - double INNER_COMPRESSED_START[] = {color_inner_compressed[0].r, color_inner_compressed[0].g, color_inner_compressed[0].b, 1.0f}; - - - draw_gradient (cr, - X, - Y, - RECT_WIDTH, - OUTER_RADIUS, - OUTER_START, - OUTER_END); - - draw_gradient (cr, - X, - Y + 1, - RECT_WIDTH - 2, - MIDDLE_RADIUS, - MIDDLE_START, - MIDDLE_END); - - draw_gradient (cr, - X, - Y + 2, - RECT_WIDTH - 4, - MIDDLE_RADIUS, - MIDDLE_START, - MIDDLE_END); - - //prev/next button - if(priv->current_command == TRANSPORT_PREVIOUS) - { - draw_gradient (cr, - X, - Y, - RECT_WIDTH/2, - OUTER_RADIUS, - OUTER_END, - OUTER_START); - - draw_gradient (cr, - X, - Y + 1, - RECT_WIDTH/2, - MIDDLE_RADIUS, - INNER_COMPRESSED_START, - INNER_COMPRESSED_END); - - draw_gradient (cr, - X, - Y + 2, - RECT_WIDTH/2, - MIDDLE_RADIUS, - INNER_COMPRESSED_START, - INNER_COMPRESSED_END); - } - else if(priv->current_command == TRANSPORT_NEXT) - { - draw_gradient (cr, - RECT_WIDTH / 2 + X, - Y, - RECT_WIDTH/2, - OUTER_RADIUS, - OUTER_END, - OUTER_START); - - draw_gradient (cr, - RECT_WIDTH / 2 + X, - Y + 1, - (RECT_WIDTH - 7)/2, - MIDDLE_RADIUS, - INNER_COMPRESSED_START, - INNER_COMPRESSED_END); - - draw_gradient (cr, - RECT_WIDTH / 2 + X, - Y + 2, - (RECT_WIDTH - 7)/2, - MIDDLE_RADIUS, - INNER_COMPRESSED_START, - INNER_COMPRESSED_END); - } - else if (priv->motion_event == TRANSPORT_PREVIOUS) - { - draw_gradient (cr, - X, - Y, - RECT_WIDTH/2, - OUTER_RADIUS, - OUTER_START_PRELIGHT, - OUTER_END_PRELIGHT); - - draw_gradient (cr, - X, - Y + 1, - RECT_WIDTH/2, - MIDDLE_RADIUS, - MIDDLE_START_PRELIGHT, - MIDDLE_END_PRELIGHT); - - draw_gradient (cr, - X, - Y + 2, - RECT_WIDTH/2, - MIDDLE_RADIUS, - MIDDLE_START_PRELIGHT, - MIDDLE_END_PRELIGHT); - } - else if (priv->motion_event == TRANSPORT_NEXT) - { - draw_gradient (cr, - RECT_WIDTH / 2 + X, - Y, - RECT_WIDTH/2, - OUTER_RADIUS, - OUTER_START_PRELIGHT, - OUTER_END_PRELIGHT); - - draw_gradient (cr, - RECT_WIDTH / 2 + X, - Y + 1, - (RECT_WIDTH - 7)/2, - MIDDLE_RADIUS, - MIDDLE_START_PRELIGHT, - MIDDLE_END_PRELIGHT); - - draw_gradient (cr, - RECT_WIDTH / 2 + X, - Y + 2, - (RECT_WIDTH - 7)/2, - MIDDLE_RADIUS, - MIDDLE_START_PRELIGHT, - MIDDLE_END_PRELIGHT); - } - - // play/pause shadow - if(priv->current_command != TRANSPORT_PLAY_PAUSE) - { - cairo_save (cr); - cairo_rectangle (cr, X, Y, RECT_WIDTH, MIDDLE_RADIUS*2); - cairo_clip (cr); - - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f - 1.0f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) - 1.0f, - CIRCLE_RADIUS + 1.0f, - SHADOW_BUTTON, - SHADOW_BUTTON); - - cairo_restore (cr); - } - - // play/pause button - if(priv->current_command == TRANSPORT_PLAY_PAUSE) - { - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) , - CIRCLE_RADIUS, - OUTER_PLAY_END, - OUTER_PLAY_START); - - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, - CIRCLE_RADIUS - 1.25, - INNER_COMPRESSED_START, - INNER_COMPRESSED_END); - } - else if (priv->motion_event == TRANSPORT_PLAY_PAUSE) - { - /* this subtle offset is to fix alpha borders, should be removed once this draw routine will be refactored */ - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 0.1, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 0.1, - CIRCLE_RADIUS - 0.1, - OUTER_PLAY_START_PRELIGHT, - OUTER_PLAY_END_PRELIGHT); - - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, - CIRCLE_RADIUS - 1.25, - MIDDLE_START_PRELIGHT, - MIDDLE_END_PRELIGHT); - } - else - { - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)), - CIRCLE_RADIUS, - OUTER_PLAY_START, - OUTER_PLAY_END); - - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, - CIRCLE_RADIUS - 1.25, - MIDDLE_START, - MIDDLE_END); - } - - // draw previous-button drop-shadow - if (priv->has_focus && priv->key_event == TRANSPORT_PREVIOUS) - { - _setup (&cr_surf, &surf, PREV_WIDTH+6, PREV_HEIGHT+6); - _mask_prev (cr_surf, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, - TRI_WIDTH, - TRI_HEIGHT, - TRI_OFFSET); - _fill (cr_surf, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (double) TRI_HEIGHT, - BUTTON_SHADOW_FOCUS, - BUTTON_SHADOW_FOCUS, - FALSE); - _surface_blur (surf, 3); - _finalize_repaint (cr, &cr_surf, &surf, PREV_X, PREV_Y + 0.5f, 3); - } - else - { - _setup (&cr_surf, &surf, PREV_WIDTH, PREV_HEIGHT); - _mask_prev (cr_surf, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, - TRI_WIDTH, - TRI_HEIGHT, - TRI_OFFSET); - _fill (cr_surf, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (double) TRI_HEIGHT, - BUTTON_SHADOW, - BUTTON_SHADOW, - FALSE); - _surface_blur (surf, 1); - _finalize (cr, &cr_surf, &surf, PREV_X, PREV_Y + 1.0f); - } - - // draw previous-button - _setup (&cr_surf, &surf, PREV_WIDTH, PREV_HEIGHT); - _mask_prev (cr_surf, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, - TRI_WIDTH, - TRI_HEIGHT, - TRI_OFFSET); - _fill (cr_surf, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (double) TRI_HEIGHT, - BUTTON_START, - BUTTON_END, - FALSE); - _finalize (cr, &cr_surf, &surf, PREV_X, PREV_Y); - - // draw next-button drop-shadow - if (priv->has_focus && priv->key_event == TRANSPORT_NEXT) - { - _setup (&cr_surf, &surf, NEXT_WIDTH+6, NEXT_HEIGHT+6); - _mask_next (cr_surf, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, - TRI_WIDTH, - TRI_HEIGHT, - TRI_OFFSET); - _fill (cr_surf, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (double) TRI_HEIGHT, - BUTTON_SHADOW_FOCUS, - BUTTON_SHADOW_FOCUS, - FALSE); - _surface_blur (surf, 3); - _finalize_repaint (cr, &cr_surf, &surf, NEXT_X, NEXT_Y + 0.5f, 3); - } - else - { - _setup (&cr_surf, &surf, NEXT_WIDTH, NEXT_HEIGHT); - _mask_next (cr_surf, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, - TRI_WIDTH, - TRI_HEIGHT, - TRI_OFFSET); - _fill (cr_surf, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (double) TRI_HEIGHT, - BUTTON_SHADOW, - BUTTON_SHADOW, - FALSE); - _surface_blur (surf, 1); - _finalize (cr, &cr_surf, &surf, NEXT_X, NEXT_Y + 1.0f); - } - - // draw next-button - _setup (&cr_surf, &surf, NEXT_WIDTH, NEXT_HEIGHT); - _mask_next (cr_surf, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, - TRI_WIDTH, - TRI_HEIGHT, - TRI_OFFSET); - _fill (cr_surf, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (double) TRI_HEIGHT, - BUTTON_START, - BUTTON_END, - FALSE); - _finalize (cr, &cr_surf, &surf, NEXT_X, NEXT_Y); - - // draw pause-button drop-shadow - if(priv->current_state == PLAY) - { - if (priv->has_focus && (priv->key_event == TRANSPORT_NADA || priv->key_event == TRANSPORT_PLAY_PAUSE)) - { - _setup (&cr_surf, &surf, PAUSE_WIDTH+6, PAUSE_HEIGHT+6); - _mask_pause (cr_surf, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, - BAR_WIDTH, - BAR_HEIGHT - 2.0f * BAR_WIDTH, - BAR_OFFSET); - _fill (cr_surf, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (double) BAR_HEIGHT, - BUTTON_SHADOW_FOCUS, - BUTTON_SHADOW_FOCUS, - TRUE); - _surface_blur (surf, 3); - _finalize_repaint (cr, &cr_surf, &surf, PAUSE_X, PAUSE_Y + 0.5f, 3); - } - else - { - _setup (&cr_surf, &surf, PAUSE_WIDTH, PAUSE_HEIGHT); - _mask_pause (cr_surf, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, - BAR_WIDTH, - BAR_HEIGHT - 2.0f * BAR_WIDTH, - BAR_OFFSET); - _fill (cr_surf, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (double) BAR_HEIGHT, - BUTTON_SHADOW, - BUTTON_SHADOW, - TRUE); - _surface_blur (surf, 1); - _finalize (cr, &cr_surf, &surf, PAUSE_X, PAUSE_Y + 1.0f); - } - - // draw pause-button - _setup (&cr_surf, &surf, PAUSE_WIDTH, PAUSE_HEIGHT); - _mask_pause (cr_surf, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, - BAR_WIDTH, - BAR_HEIGHT - 2.0f * BAR_WIDTH, - BAR_OFFSET); - _fill (cr_surf, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (double) BAR_HEIGHT, - BUTTON_START, - BUTTON_END, - TRUE); - _finalize (cr, &cr_surf, &surf, PAUSE_X, PAUSE_Y); - } - else if(priv->current_state == PAUSE) - { - if (priv->has_focus && (priv->key_event == TRANSPORT_NADA || priv->key_event == TRANSPORT_PLAY_PAUSE)) - { - _setup (&cr_surf, &surf, PLAY_WIDTH+6, PLAY_HEIGHT+6); - _mask_play (cr_surf, - PLAY_PADDING, - PLAY_PADDING, - PLAY_WIDTH - (2*PLAY_PADDING), - PLAY_HEIGHT - (2*PLAY_PADDING)); - _fill (cr_surf, - PLAY_PADDING, - PLAY_PADDING, - PLAY_WIDTH - (2*PLAY_PADDING), - PLAY_HEIGHT - (2*PLAY_PADDING), - BUTTON_SHADOW_FOCUS, - BUTTON_SHADOW_FOCUS, - FALSE); - _surface_blur (surf, 3); - _finalize_repaint (cr, &cr_surf, &surf, PAUSE_X-0.5f, PAUSE_Y + 0.5f, 3); - } - else - { - _setup (&cr_surf, &surf, PLAY_WIDTH, PLAY_HEIGHT); - _mask_play (cr_surf, - PLAY_PADDING, - PLAY_PADDING, - PLAY_WIDTH - (2*PLAY_PADDING), - PLAY_HEIGHT - (2*PLAY_PADDING)); - _fill (cr_surf, - PLAY_PADDING, - PLAY_PADDING, - PLAY_WIDTH - (2*PLAY_PADDING), - PLAY_HEIGHT - (2*PLAY_PADDING), - BUTTON_SHADOW, - BUTTON_SHADOW, - FALSE); - _surface_blur (surf, 1); - _finalize (cr, &cr_surf, &surf, PAUSE_X-0.75f, PAUSE_Y + 1.0f); - } - - // draw play-button - _setup (&cr_surf, &surf, PLAY_WIDTH, PLAY_HEIGHT); - cairo_set_line_width (cr, 10.5); - cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); - cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); - _mask_play (cr_surf, - PLAY_PADDING, - PLAY_PADDING, - PLAY_WIDTH - (2*PLAY_PADDING), - PLAY_HEIGHT - (2*PLAY_PADDING)); - _fill (cr_surf, - PLAY_PADDING, - PLAY_PADDING, - PLAY_WIDTH - (2*PLAY_PADDING), - PLAY_HEIGHT - (2*PLAY_PADDING), - BUTTON_START, - BUTTON_END, - FALSE); - _finalize (cr, &cr_surf, &surf, PAUSE_X-0.5f, PAUSE_Y); - } + g_return_if_fail(IS_TRANSPORT_WIDGET(button)); + TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button); + + cairo_surface_t* surf = NULL; + cairo_t* cr_surf = NULL; + + cairo_translate (cr, button->allocation.x, button->allocation.y); + + //g_debug("button x allocation = %i", button->allocation.x); + //g_debug("button y allocation = %i", button->allocation.y); + + GtkStyle *style; + + CairoColorRGB bg_color, fg_color, bg_selected, bg_prelight; + CairoColorRGB color_middle[2], color_middle_prelight[2], color_outer[2], color_outer_prelight[2], + color_play_outer[2], color_play_outer_prelight[2], + color_button[4], color_button_shadow, color_inner[2], color_inner_compressed[2]; + + style = gtk_widget_get_style (button); + + bg_color.r = style->bg[0].red/65535.0; + bg_color.g = style->bg[0].green/65535.0; + bg_color.b = style->bg[0].blue/65535.0; + + bg_prelight.r = style->bg[GTK_STATE_PRELIGHT].red/65535.0; + bg_prelight.g = style->bg[GTK_STATE_PRELIGHT].green/65535.0; + bg_prelight.b = style->bg[GTK_STATE_PRELIGHT].blue/65535.0; + + bg_selected.r = style->bg[GTK_STATE_SELECTED].red/65535.0; + bg_selected.g = style->bg[GTK_STATE_SELECTED].green/65535.0; + bg_selected.b = style->bg[GTK_STATE_SELECTED].blue/65535.0; + + fg_color.r = style->fg[0].red/65535.0; + fg_color.g = style->fg[0].green/65535.0; + fg_color.b = style->fg[0].blue/65535.0; + + _color_shade (&bg_color, MIDDLE_START_SHADE, &color_middle[0]); + _color_shade (&bg_color, MIDDLE_END_SHADE, &color_middle[1]); + _color_shade (&bg_prelight, MIDDLE_START_SHADE, &color_middle_prelight[0]); + _color_shade (&bg_prelight, MIDDLE_END_SHADE, &color_middle_prelight[1]); + _color_shade (&bg_color, OUTER_START_SHADE, &color_outer[0]); + _color_shade (&bg_color, OUTER_END_SHADE, &color_outer[1]); + _color_shade (&bg_prelight, OUTER_START_SHADE, &color_outer_prelight[0]); + _color_shade (&bg_prelight, OUTER_END_SHADE, &color_outer_prelight[1]); + _color_shade (&bg_color, OUTER_PLAY_START_SHADE, &color_play_outer[0]); + _color_shade (&bg_color, OUTER_PLAY_END_SHADE, &color_play_outer[1]); + _color_shade (&bg_prelight, OUTER_PLAY_START_SHADE, &color_play_outer_prelight[0]); + _color_shade (&bg_prelight, OUTER_PLAY_END_SHADE, &color_play_outer_prelight[1]); + _color_shade (&bg_color, INNER_START_SHADE, &color_inner[0]); + _color_shade (&bg_color, INNER_END_SHADE, &color_inner[1]); + _color_shade (&fg_color, BUTTON_START_SHADE, &color_button[0]); + _color_shade (&fg_color, BUTTON_END_SHADE, &color_button[1]); + _color_shade (&bg_color, BUTTON_SHADOW_SHADE, &color_button[2]); + _color_shade (&bg_color, SHADOW_BUTTON_SHADE, &color_button_shadow); + _color_shade (&bg_selected, 1.0, &color_button[3]); + _color_shade (&bg_color, INNER_COMPRESSED_START_SHADE, &color_inner_compressed[0]); + _color_shade (&bg_color, INNER_COMPRESSED_END_SHADE, &color_inner_compressed[1]); + + double MIDDLE_END[] = {color_middle[0].r, color_middle[0].g, color_middle[0].b, 1.0f}; + double MIDDLE_START[] = {color_middle[1].r, color_middle[1].g, color_middle[1].b, 1.0f}; + double MIDDLE_END_PRELIGHT[] = {color_middle_prelight[0].r, color_middle_prelight[0].g, color_middle_prelight[0].b, 1.0f}; + double MIDDLE_START_PRELIGHT[] = {color_middle_prelight[1].r, color_middle_prelight[1].g, color_middle_prelight[1].b, 1.0f}; + double OUTER_END[] = {color_outer[0].r, color_outer[0].g, color_outer[0].b, 1.0f}; + double OUTER_START[] = {color_outer[1].r, color_outer[1].g, color_outer[1].b, 1.0f}; + double OUTER_END_PRELIGHT[] = {color_outer_prelight[0].r, color_outer_prelight[0].g, color_outer_prelight[0].b, 1.0f}; + double OUTER_START_PRELIGHT[] = {color_outer_prelight[1].r, color_outer_prelight[1].g, color_outer_prelight[1].b, 1.0f}; + double SHADOW_BUTTON[] = {color_button_shadow.r, color_button_shadow.g, color_button_shadow.b, 0.3f}; + double OUTER_PLAY_END[] = {color_play_outer[0].r, color_play_outer[0].g, color_play_outer[0].b, 1.0f}; + double OUTER_PLAY_START[] = {color_play_outer[1].r, color_play_outer[1].g, color_play_outer[1].b, 1.0f}; + double OUTER_PLAY_END_PRELIGHT[] = {color_play_outer_prelight[0].r, color_play_outer_prelight[0].g, color_play_outer_prelight[0].b, 1.0f}; + double OUTER_PLAY_START_PRELIGHT[] = {color_play_outer_prelight[1].r, color_play_outer_prelight[1].g, color_play_outer_prelight[1].b, 1.0f}; + double BUTTON_END[] = {color_button[0].r, color_button[0].g, color_button[0].b, 1.0f}; + double BUTTON_START[] = {color_button[1].r, color_button[1].g, color_button[1].b, 1.0f}; + double BUTTON_SHADOW[] = {color_button[2].r, color_button[2].g, color_button[2].b, 0.75f}; + double BUTTON_SHADOW_FOCUS[] = {color_button[3].r, color_button[3].g, color_button[3].b, 1.0f}; + double INNER_COMPRESSED_END[] = {color_inner_compressed[1].r, color_inner_compressed[1].g, color_inner_compressed[1].b, 1.0f}; + double INNER_COMPRESSED_START[] = {color_inner_compressed[0].r, color_inner_compressed[0].g, color_inner_compressed[0].b, 1.0f}; + + + draw_gradient (cr, + X, + Y, + RECT_WIDTH, + OUTER_RADIUS, + OUTER_START, + OUTER_END); + + draw_gradient (cr, + X, + Y + 1, + RECT_WIDTH - 2, + MIDDLE_RADIUS, + MIDDLE_START, + MIDDLE_END); + + draw_gradient (cr, + X, + Y + 2, + RECT_WIDTH - 4, + MIDDLE_RADIUS, + MIDDLE_START, + MIDDLE_END); + + //prev/next button + if(priv->current_command == TRANSPORT_PREVIOUS) + { + draw_gradient (cr, + X, + Y, + RECT_WIDTH/2, + OUTER_RADIUS, + OUTER_END, + OUTER_START); + + draw_gradient (cr, + X, + Y + 1, + RECT_WIDTH/2, + MIDDLE_RADIUS, + INNER_COMPRESSED_START, + INNER_COMPRESSED_END); + + draw_gradient (cr, + X, + Y + 2, + RECT_WIDTH/2, + MIDDLE_RADIUS, + INNER_COMPRESSED_START, + INNER_COMPRESSED_END); + } + else if(priv->current_command == TRANSPORT_NEXT) + { + draw_gradient (cr, + RECT_WIDTH / 2 + X, + Y, + RECT_WIDTH/2, + OUTER_RADIUS, + OUTER_END, + OUTER_START); + + draw_gradient (cr, + RECT_WIDTH / 2 + X, + Y + 1, + (RECT_WIDTH - 7)/2, + MIDDLE_RADIUS, + INNER_COMPRESSED_START, + INNER_COMPRESSED_END); + + draw_gradient (cr, + RECT_WIDTH / 2 + X, + Y + 2, + (RECT_WIDTH - 7)/2, + MIDDLE_RADIUS, + INNER_COMPRESSED_START, + INNER_COMPRESSED_END); + } + else if (priv->motion_event == TRANSPORT_PREVIOUS) + { + draw_gradient (cr, + X, + Y, + RECT_WIDTH/2, + OUTER_RADIUS, + OUTER_START_PRELIGHT, + OUTER_END_PRELIGHT); + + draw_gradient (cr, + X, + Y + 1, + RECT_WIDTH/2, + MIDDLE_RADIUS, + MIDDLE_START_PRELIGHT, + MIDDLE_END_PRELIGHT); + + draw_gradient (cr, + X, + Y + 2, + RECT_WIDTH/2, + MIDDLE_RADIUS, + MIDDLE_START_PRELIGHT, + MIDDLE_END_PRELIGHT); + } + else if (priv->motion_event == TRANSPORT_NEXT) + { + draw_gradient (cr, + RECT_WIDTH / 2 + X, + Y, + RECT_WIDTH/2, + OUTER_RADIUS, + OUTER_START_PRELIGHT, + OUTER_END_PRELIGHT); + + draw_gradient (cr, + RECT_WIDTH / 2 + X, + Y + 1, + (RECT_WIDTH - 7)/2, + MIDDLE_RADIUS, + MIDDLE_START_PRELIGHT, + MIDDLE_END_PRELIGHT); + + draw_gradient (cr, + RECT_WIDTH / 2 + X, + Y + 2, + (RECT_WIDTH - 7)/2, + MIDDLE_RADIUS, + MIDDLE_START_PRELIGHT, + MIDDLE_END_PRELIGHT); + } + + // play/pause shadow + if(priv->current_command != TRANSPORT_PLAY_PAUSE) + { + cairo_save (cr); + cairo_rectangle (cr, X, Y, RECT_WIDTH, MIDDLE_RADIUS*2); + cairo_clip (cr); + + draw_circle (cr, + X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f - 1.0f, + Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) - 1.0f, + CIRCLE_RADIUS + 1.0f, + SHADOW_BUTTON, + SHADOW_BUTTON); + + cairo_restore (cr); + } + + // play/pause button + if(priv->current_command == TRANSPORT_PLAY_PAUSE) + { + draw_circle (cr, + X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f, + Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) , + CIRCLE_RADIUS, + OUTER_PLAY_END, + OUTER_PLAY_START); + + draw_circle (cr, + X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, + Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, + CIRCLE_RADIUS - 1.25, + INNER_COMPRESSED_START, + INNER_COMPRESSED_END); + } + else if (priv->motion_event == TRANSPORT_PLAY_PAUSE) + { + /* this subtle offset is to fix alpha borders, should be removed once this draw routine will be refactored */ + draw_circle (cr, + X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 0.1, + Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 0.1, + CIRCLE_RADIUS - 0.1, + OUTER_PLAY_START_PRELIGHT, + OUTER_PLAY_END_PRELIGHT); + + draw_circle (cr, + X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, + Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, + CIRCLE_RADIUS - 1.25, + MIDDLE_START_PRELIGHT, + MIDDLE_END_PRELIGHT); + } + else + { + draw_circle (cr, + X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f, + Y - ((CIRCLE_RADIUS - OUTER_RADIUS)), + CIRCLE_RADIUS, + OUTER_PLAY_START, + OUTER_PLAY_END); + + draw_circle (cr, + X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, + Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, + CIRCLE_RADIUS - 1.25, + MIDDLE_START, + MIDDLE_END); + } + + // draw previous-button drop-shadow + if (priv->has_focus && priv->key_event == TRANSPORT_PREVIOUS) + { + _setup (&cr_surf, &surf, PREV_WIDTH+6, PREV_HEIGHT+6); + _mask_prev (cr_surf, + (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, + TRI_WIDTH, + TRI_HEIGHT, + TRI_OFFSET); + _fill (cr_surf, + (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, + (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (double) TRI_HEIGHT, + BUTTON_SHADOW_FOCUS, + BUTTON_SHADOW_FOCUS, + FALSE); + _surface_blur (surf, 3); + _finalize_repaint (cr, &cr_surf, &surf, PREV_X, PREV_Y + 0.5f, 3); + } + else + { + _setup (&cr_surf, &surf, PREV_WIDTH, PREV_HEIGHT); + _mask_prev (cr_surf, + (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, + TRI_WIDTH, + TRI_HEIGHT, + TRI_OFFSET); + _fill (cr_surf, + (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, + (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (double) TRI_HEIGHT, + BUTTON_SHADOW, + BUTTON_SHADOW, + FALSE); + _surface_blur (surf, 1); + _finalize (cr, &cr_surf, &surf, PREV_X, PREV_Y + 1.0f); + } + + // draw previous-button + _setup (&cr_surf, &surf, PREV_WIDTH, PREV_HEIGHT); + _mask_prev (cr_surf, + (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, + TRI_WIDTH, + TRI_HEIGHT, + TRI_OFFSET); + _fill (cr_surf, + (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, + (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (double) TRI_HEIGHT, + BUTTON_START, + BUTTON_END, + FALSE); + _finalize (cr, &cr_surf, &surf, PREV_X, PREV_Y); + + // draw next-button drop-shadow + if (priv->has_focus && priv->key_event == TRANSPORT_NEXT) + { + _setup (&cr_surf, &surf, NEXT_WIDTH+6, NEXT_HEIGHT+6); + _mask_next (cr_surf, + (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, + TRI_WIDTH, + TRI_HEIGHT, + TRI_OFFSET); + _fill (cr_surf, + (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, + (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (double) TRI_HEIGHT, + BUTTON_SHADOW_FOCUS, + BUTTON_SHADOW_FOCUS, + FALSE); + _surface_blur (surf, 3); + _finalize_repaint (cr, &cr_surf, &surf, NEXT_X, NEXT_Y + 0.5f, 3); + } + else + { + _setup (&cr_surf, &surf, NEXT_WIDTH, NEXT_HEIGHT); + _mask_next (cr_surf, + (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, + TRI_WIDTH, + TRI_HEIGHT, + TRI_OFFSET); + _fill (cr_surf, + (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, + (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (double) TRI_HEIGHT, + BUTTON_SHADOW, + BUTTON_SHADOW, + FALSE); + _surface_blur (surf, 1); + _finalize (cr, &cr_surf, &surf, NEXT_X, NEXT_Y + 1.0f); + } + + // draw next-button + _setup (&cr_surf, &surf, NEXT_WIDTH, NEXT_HEIGHT); + _mask_next (cr_surf, + (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, + TRI_WIDTH, + TRI_HEIGHT, + TRI_OFFSET); + _fill (cr_surf, + (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, + (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, + (double) TRI_HEIGHT, + BUTTON_START, + BUTTON_END, + FALSE); + _finalize (cr, &cr_surf, &surf, NEXT_X, NEXT_Y); + + // draw pause-button drop-shadow + if(priv->current_state == PLAY) + { + if (priv->has_focus && (priv->key_event == TRANSPORT_NADA || priv->key_event == TRANSPORT_PLAY_PAUSE)) + { + _setup (&cr_surf, &surf, PAUSE_WIDTH+6, PAUSE_HEIGHT+6); + _mask_pause (cr_surf, + (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, + (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, + BAR_WIDTH, + BAR_HEIGHT - 2.0f * BAR_WIDTH, + BAR_OFFSET); + _fill (cr_surf, + (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, + (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, + (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, + (double) BAR_HEIGHT, + BUTTON_SHADOW_FOCUS, + BUTTON_SHADOW_FOCUS, + TRUE); + _surface_blur (surf, 3); + _finalize_repaint (cr, &cr_surf, &surf, PAUSE_X, PAUSE_Y + 0.5f, 3); + } + else + { + _setup (&cr_surf, &surf, PAUSE_WIDTH, PAUSE_HEIGHT); + _mask_pause (cr_surf, + (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, + (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, + BAR_WIDTH, + BAR_HEIGHT - 2.0f * BAR_WIDTH, + BAR_OFFSET); + _fill (cr_surf, + (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, + (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, + (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, + (double) BAR_HEIGHT, + BUTTON_SHADOW, + BUTTON_SHADOW, + TRUE); + _surface_blur (surf, 1); + _finalize (cr, &cr_surf, &surf, PAUSE_X, PAUSE_Y + 1.0f); + } + + // draw pause-button + _setup (&cr_surf, &surf, PAUSE_WIDTH, PAUSE_HEIGHT); + _mask_pause (cr_surf, + (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, + (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, + BAR_WIDTH, + BAR_HEIGHT - 2.0f * BAR_WIDTH, + BAR_OFFSET); + _fill (cr_surf, + (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, + (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, + (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, + (double) BAR_HEIGHT, + BUTTON_START, + BUTTON_END, + TRUE); + _finalize (cr, &cr_surf, &surf, PAUSE_X, PAUSE_Y); + } + else if(priv->current_state == PAUSE) + { + if (priv->has_focus && (priv->key_event == TRANSPORT_NADA || priv->key_event == TRANSPORT_PLAY_PAUSE)) + { + _setup (&cr_surf, &surf, PLAY_WIDTH+6, PLAY_HEIGHT+6); + _mask_play (cr_surf, + PLAY_PADDING, + PLAY_PADDING, + PLAY_WIDTH - (2*PLAY_PADDING), + PLAY_HEIGHT - (2*PLAY_PADDING)); + _fill (cr_surf, + PLAY_PADDING, + PLAY_PADDING, + PLAY_WIDTH - (2*PLAY_PADDING), + PLAY_HEIGHT - (2*PLAY_PADDING), + BUTTON_SHADOW_FOCUS, + BUTTON_SHADOW_FOCUS, + FALSE); + _surface_blur (surf, 3); + _finalize_repaint (cr, &cr_surf, &surf, PAUSE_X-0.5f, PAUSE_Y + 0.5f, 3); + } + else + { + _setup (&cr_surf, &surf, PLAY_WIDTH, PLAY_HEIGHT); + _mask_play (cr_surf, + PLAY_PADDING, + PLAY_PADDING, + PLAY_WIDTH - (2*PLAY_PADDING), + PLAY_HEIGHT - (2*PLAY_PADDING)); + _fill (cr_surf, + PLAY_PADDING, + PLAY_PADDING, + PLAY_WIDTH - (2*PLAY_PADDING), + PLAY_HEIGHT - (2*PLAY_PADDING), + BUTTON_SHADOW, + BUTTON_SHADOW, + FALSE); + _surface_blur (surf, 1); + _finalize (cr, &cr_surf, &surf, PAUSE_X-0.75f, PAUSE_Y + 1.0f); + } + + // draw play-button + _setup (&cr_surf, &surf, PLAY_WIDTH, PLAY_HEIGHT); + cairo_set_line_width (cr, 10.5); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); + _mask_play (cr_surf, + PLAY_PADDING, + PLAY_PADDING, + PLAY_WIDTH - (2*PLAY_PADDING), + PLAY_HEIGHT - (2*PLAY_PADDING)); + _fill (cr_surf, + PLAY_PADDING, + PLAY_PADDING, + PLAY_WIDTH - (2*PLAY_PADDING), + PLAY_HEIGHT - (2*PLAY_PADDING), + BUTTON_START, + BUTTON_END, + FALSE); + _finalize (cr, &cr_surf, &surf, PAUSE_X-0.5f, PAUSE_Y); + } } static void transport_widget_set_twin_item(TransportWidget* self, - DbusmenuMenuitem* twin_item) + DbusmenuMenuitem* twin_item) { TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(self); priv->twin_item = twin_item; g_signal_connect(G_OBJECT(priv->twin_item), "property-changed", G_CALLBACK(transport_widget_property_update), self); - gint initial_state = dbusmenu_menuitem_property_get_int( twin_item, + gint initial_state = dbusmenu_menuitem_property_get_int( twin_item, DBUSMENU_TRANSPORT_MENUITEM_PLAY_STATE ); //g_debug("TRANSPORT WIDGET - INITIAL UPDATE = %i", initial_state); - transport_widget_toggle_play_pause( self, - (TransportWidgetState)initial_state); + transport_widget_toggle_play_pause( self, + (TransportWidgetState)initial_state); } /** @@ -1700,16 +1700,16 @@ static void transport_widget_property_update(DbusmenuMenuitem* item, gchar* property, GValue* value, gpointer userdata) { - //g_debug("transport_widget_update_state - with property %s", property); - TransportWidget* bar = (TransportWidget*)userdata; - g_return_if_fail(IS_TRANSPORT_WIDGET(bar)); - - if(g_ascii_strcasecmp(DBUSMENU_TRANSPORT_MENUITEM_PLAY_STATE, property) == 0) - { - int update_value = g_value_get_int(value); - //g_debug("transport_widget_update_state - with value %i", update_value); - transport_widget_toggle_play_pause(bar, (TransportWidgetState)update_value); - } + //g_debug("transport_widget_update_state - with property %s", property); + TransportWidget* bar = (TransportWidget*)userdata; + g_return_if_fail(IS_TRANSPORT_WIDGET(bar)); + + if(g_ascii_strcasecmp(DBUSMENU_TRANSPORT_MENUITEM_PLAY_STATE, property) == 0) + { + int update_value = g_value_get_int(value); + //g_debug("transport_widget_update_state - with value %i", update_value); + transport_widget_toggle_play_pause(bar, (TransportWidgetState)update_value); + } } @@ -1719,10 +1719,10 @@ transport_widget_property_update(DbusmenuMenuitem* item, gchar* property, **/ GtkWidget* transport_widget_new ( DbusmenuMenuitem *item ) -{ - GtkWidget* widget = g_object_new(TRANSPORT_WIDGET_TYPE, NULL); - gtk_widget_set_app_paintable (widget, TRUE); - transport_widget_set_twin_item((TransportWidget*)widget, item); - return widget; +{ + GtkWidget* widget = g_object_new(TRANSPORT_WIDGET_TYPE, NULL); + gtk_widget_set_app_paintable (widget, TRUE); + transport_widget_set_twin_item((TransportWidget*)widget, item); + return widget; } diff --git a/src/transport-widget.h b/src/transport-widget.h index 70ce6aa..d02f59b 100644 --- a/src/transport-widget.h +++ b/src/transport-widget.h @@ -36,30 +36,30 @@ typedef struct _TransportWidget TransportWidget; typedef struct _TransportWidgetClass TransportWidgetClass; typedef enum { - TRANSPORT_PREVIOUS, - TRANSPORT_PLAY_PAUSE, - TRANSPORT_NEXT, - TRANSPORT_NADA + TRANSPORT_PREVIOUS, + TRANSPORT_PLAY_PAUSE, + TRANSPORT_NEXT, + TRANSPORT_NADA }TransportWidgetEvent; typedef enum { - PLAY, - PAUSE + PLAY, + PAUSE }TransportWidgetState; struct _TransportWidgetClass { - GtkMenuItemClass parent_class; + GtkMenuItemClass parent_class; }; struct _TransportWidget { - GtkMenuItem parent; + GtkMenuItem parent; }; typedef struct { - double r; - double g; - double b; + double r; + double g; + double b; } CairoColorRGB; diff --git a/src/volume-widget.c b/src/volume-widget.c index 6964741..c37f9c7 100644 --- a/src/volume-widget.c +++ b/src/volume-widget.c @@ -33,9 +33,9 @@ typedef struct _VolumeWidgetPrivate VolumeWidgetPrivate; struct _VolumeWidgetPrivate { - DbusmenuMenuitem* twin_item; - GtkWidget* ido_volume_slider; - gboolean grabbed; + DbusmenuMenuitem* twin_item; + GtkWidget* ido_volume_slider; + gboolean grabbed; }; #define VOLUME_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOLUME_WIDGET_TYPE, VolumeWidgetPrivate)) @@ -46,14 +46,14 @@ static void volume_widget_init (VolumeWidget *self); static void volume_widget_dispose (GObject *object); static void volume_widget_finalize (GObject *object); static void volume_widget_set_twin_item( VolumeWidget* self, - DbusmenuMenuitem* twin_item); + DbusmenuMenuitem* twin_item); static void volume_widget_property_update( DbusmenuMenuitem* item, gchar* property, - GValue* value, gpointer userdata); + GValue* value, gpointer userdata); static gboolean volume_widget_change_value_cb (GtkRange *range, - GtkScrollType scroll, - gdouble value, - gpointer user_data); + GtkScrollType scroll, + gdouble value, + gpointer user_data); static gboolean volume_widget_value_changed_cb(GtkRange *range, gpointer user_data); static void volume_widget_slider_grabbed(GtkWidget *widget, gpointer user_data); static void volume_widget_slider_released(GtkWidget *widget, gpointer user_data); @@ -65,33 +65,33 @@ G_DEFINE_TYPE (VolumeWidget, volume_widget, G_TYPE_OBJECT); static void volume_widget_class_init (VolumeWidgetClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (VolumeWidgetPrivate)); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (VolumeWidgetPrivate)); - gobject_class->dispose = volume_widget_dispose; - gobject_class->finalize = volume_widget_finalize; + gobject_class->dispose = volume_widget_dispose; + gobject_class->finalize = volume_widget_finalize; } static void volume_widget_init (VolumeWidget *self) { - //g_debug("VolumeWidget::volume_widget_init"); - VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); + //g_debug("VolumeWidget::volume_widget_init"); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); priv->ido_volume_slider = ido_scale_menu_item_new_with_range ("VOLUME", IDO_RANGE_STYLE_DEFAULT, 0, 0, 100, 1); - g_object_ref (priv->ido_volume_slider); - ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (priv->ido_volume_slider), IDO_SCALE_MENU_ITEM_STYLE_IMAGE); + g_object_ref (priv->ido_volume_slider); + ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (priv->ido_volume_slider), IDO_SCALE_MENU_ITEM_STYLE_IMAGE); g_object_set(priv->ido_volume_slider, "reverse-scroll-events", TRUE, NULL); g_signal_connect (priv->ido_volume_slider, "notify::parent", G_CALLBACK (volume_widget_parent_changed), NULL); - - GtkWidget* volume_widget = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); - - g_signal_connect(volume_widget, "change-value", G_CALLBACK(volume_widget_change_value_cb), self); - g_signal_connect(volume_widget, "value-changed", G_CALLBACK(volume_widget_value_changed_cb), self); + + GtkWidget* volume_widget = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); + + g_signal_connect(volume_widget, "change-value", G_CALLBACK(volume_widget_change_value_cb), self); + g_signal_connect(volume_widget, "value-changed", G_CALLBACK(volume_widget_value_changed_cb), self); g_signal_connect(priv->ido_volume_slider, "slider-grabbed", G_CALLBACK(volume_widget_slider_grabbed), self); g_signal_connect(priv->ido_volume_slider, "slider-released", G_CALLBACK(volume_widget_slider_released), self); @@ -112,64 +112,64 @@ volume_widget_init (VolumeWidget *self) static void volume_widget_dispose (GObject *object) { - G_OBJECT_CLASS (volume_widget_parent_class)->dispose (object); + G_OBJECT_CLASS (volume_widget_parent_class)->dispose (object); } static void volume_widget_finalize (GObject *object) { - G_OBJECT_CLASS (volume_widget_parent_class)->finalize (object); + G_OBJECT_CLASS (volume_widget_parent_class)->finalize (object); } static void volume_widget_property_update(DbusmenuMenuitem* item, gchar* property, GValue* value, gpointer userdata) -{ - g_return_if_fail (IS_VOLUME_WIDGET (userdata)); - VolumeWidget* mitem = VOLUME_WIDGET(userdata); - VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); - //g_debug("scrub-widget::property_update for prop %s", property); - if(g_ascii_strcasecmp(DBUSMENU_VOLUME_MENUITEM_LEVEL, property) == 0){ - if(priv->grabbed == FALSE){ - GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); - GtkRange *range = (GtkRange*)slider; - gdouble update = g_value_get_double (value); - //g_debug("volume-widget - update level with value %f", update); - gtk_range_set_value(range, update); - determine_state_from_volume(update); - } - } +{ + g_return_if_fail (IS_VOLUME_WIDGET (userdata)); + VolumeWidget* mitem = VOLUME_WIDGET(userdata); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); + //g_debug("scrub-widget::property_update for prop %s", property); + if(g_ascii_strcasecmp(DBUSMENU_VOLUME_MENUITEM_LEVEL, property) == 0){ + if(priv->grabbed == FALSE){ + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); + GtkRange *range = (GtkRange*)slider; + gdouble update = g_value_get_double (value); + //g_debug("volume-widget - update level with value %f", update); + gtk_range_set_value(range, update); + determine_state_from_volume(update); + } + } } static void volume_widget_set_twin_item(VolumeWidget* self, DbusmenuMenuitem* twin_item) { - VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); - priv->twin_item = twin_item; - g_object_ref(priv->twin_item); - g_signal_connect(G_OBJECT(twin_item), "property-changed", - G_CALLBACK(volume_widget_property_update), self); - gdouble initial_level = g_value_get_double (dbusmenu_menuitem_property_get_value(twin_item, - DBUSMENU_VOLUME_MENUITEM_LEVEL)); - //g_debug("volume_widget_set_twin_item initial level = %f", initial_level); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); + priv->twin_item = twin_item; + g_object_ref(priv->twin_item); + g_signal_connect(G_OBJECT(twin_item), "property-changed", + G_CALLBACK(volume_widget_property_update), self); + gdouble initial_level = g_value_get_double (dbusmenu_menuitem_property_get_value(twin_item, + DBUSMENU_VOLUME_MENUITEM_LEVEL)); + //g_debug("volume_widget_set_twin_item initial level = %f", initial_level); GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); GtkRange *range = (GtkRange*)slider; - gtk_range_set_value(range, initial_level); - determine_state_from_volume(initial_level); + gtk_range_set_value(range, initial_level); + determine_state_from_volume(initial_level); } static gboolean volume_widget_change_value_cb (GtkRange *range, - GtkScrollType scroll, - gdouble new_value, - gpointer user_data) + GtkScrollType scroll, + gdouble new_value, + gpointer user_data) { - g_return_val_if_fail (IS_VOLUME_WIDGET (user_data), FALSE); - VolumeWidget* mitem = VOLUME_WIDGET(user_data); - volume_widget_update(mitem, new_value); + g_return_val_if_fail (IS_VOLUME_WIDGET (user_data), FALSE); + VolumeWidget* mitem = VOLUME_WIDGET(user_data); + volume_widget_update(mitem, new_value); determine_state_from_volume(new_value); - return FALSE; + return FALSE; } /* @@ -179,25 +179,25 @@ volume_widget_change_value_cb (GtkRange *range, static gboolean volume_widget_value_changed_cb(GtkRange *range, gpointer user_data) { - g_return_val_if_fail (IS_VOLUME_WIDGET (user_data), FALSE); - VolumeWidget* mitem = VOLUME_WIDGET(user_data); - VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); - GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); + g_return_val_if_fail (IS_VOLUME_WIDGET (user_data), FALSE); + VolumeWidget* mitem = VOLUME_WIDGET(user_data); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); gdouble current_value = CLAMP(gtk_range_get_value(GTK_RANGE(slider)), 0, 100); - - if(current_value == 0 || current_value == 100){ - volume_widget_update(mitem, current_value); - } + + if(current_value == 0 || current_value == 100){ + volume_widget_update(mitem, current_value); + } return FALSE; } void volume_widget_update(VolumeWidget* self, gdouble update) { - VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); - GValue value = {0}; + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); + GValue value = {0}; g_value_init(&value, G_TYPE_DOUBLE); - gdouble clamped = CLAMP(update, 0, 100); + gdouble clamped = CLAMP(update, 0, 100); g_value_set_double(&value, clamped); dbusmenu_menuitem_handle_event (priv->twin_item, "update", &value, 0); } @@ -205,13 +205,13 @@ volume_widget_update(VolumeWidget* self, gdouble update) GtkWidget* volume_widget_get_ido_slider(VolumeWidget* self) { - VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); - return priv->ido_volume_slider; + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); + return priv->ido_volume_slider; } static void volume_widget_parent_changed (GtkWidget *widget, - gpointer user_data) + gpointer user_data) { gtk_widget_set_size_request (widget, 200, -1); //g_debug("volume_widget_parent_changed"); @@ -220,24 +220,24 @@ volume_widget_parent_changed (GtkWidget *widget, static void volume_widget_slider_grabbed(GtkWidget *widget, gpointer user_data) { - VolumeWidget* mitem = VOLUME_WIDGET(user_data); - VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); - priv->grabbed = TRUE; + VolumeWidget* mitem = VOLUME_WIDGET(user_data); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); + priv->grabbed = TRUE; } static void volume_widget_slider_released(GtkWidget *widget, gpointer user_data) { - VolumeWidget* mitem = VOLUME_WIDGET(user_data); - VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); - priv->grabbed = FALSE; + VolumeWidget* mitem = VOLUME_WIDGET(user_data); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); + priv->grabbed = FALSE; } void volume_widget_tidy_up (GtkWidget *widget) { VolumeWidget* mitem = VOLUME_WIDGET(widget); - VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); gtk_widget_destroy (priv->ido_volume_slider); } @@ -245,9 +245,9 @@ gdouble volume_widget_get_current_volume ( GtkWidget *widget ) { VolumeWidget* mitem = VOLUME_WIDGET(widget); - VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); gdouble vol = g_value_get_double ( dbusmenu_menuitem_property_get_value( priv->twin_item, - DBUSMENU_VOLUME_MENUITEM_LEVEL)); + DBUSMENU_VOLUME_MENUITEM_LEVEL)); return vol; } @@ -258,9 +258,9 @@ volume_widget_get_current_volume ( GtkWidget *widget ) GtkWidget* volume_widget_new(DbusmenuMenuitem *item) { - GtkWidget* widget = g_object_new(VOLUME_WIDGET_TYPE, NULL); - volume_widget_set_twin_item((VolumeWidget*)widget, item); - return widget; + GtkWidget* widget = g_object_new(VOLUME_WIDGET_TYPE, NULL); + volume_widget_set_twin_item((VolumeWidget*)widget, item); + return widget; } diff --git a/src/volume-widget.h b/src/volume-widget.h index 202bbb3..072cfde 100644 --- a/src/volume-widget.h +++ b/src/volume-widget.h @@ -32,15 +32,15 @@ G_BEGIN_DECLS #define IS_VOLUME_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VOLUME_WIDGET_TYPE)) #define VOLUME_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VOLUME_WIDGET_TYPE, VolumeWidgetClass)) -typedef struct _VolumeWidget VolumeWidget; -typedef struct _VolumeWidgetClass VolumeWidgetClass; +typedef struct _VolumeWidget VolumeWidget; +typedef struct _VolumeWidgetClass VolumeWidgetClass; struct _VolumeWidgetClass { GObjectClass parent_class; }; struct _VolumeWidget { - GObject parent; + GObject parent; }; GType volume_widget_get_type (void) G_GNUC_CONST; -- cgit v1.2.3 From ee3cc0d34b7f64412a9298fc7f9160641d887a83 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 10 Dec 2010 18:35:35 +0000 Subject: correct startup behaviour implemented --- src/mpris2-watcher.vala | 56 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index 1cf8baa..d154fcb 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -19,7 +19,8 @@ with this program. If not, see . [DBus (name = "org.freedesktop.DBus")] public interface FreeDesktopObject: Object { - public abstract signal void name_owner_changed (string name, + public abstract async string[] list_names() throws IOError; + public abstract signal void name_owner_changed (string name, string old_owner, string new_owner); } @@ -48,6 +49,7 @@ public class Mpris2Watcher : GLib.Object FREEDESKTOP_OBJECT, DBusProxyFlags.DO_NOT_LOAD_PROPERTIES ); this.fdesktop_obj.name_owner_changed.connect (this.name_changes_detected); + this.check_for_active_clients.begin(); } catch ( IOError e ){ warning( "Mpris2watcher could not set up a watch for mpris clients appearing on the bus: %s", @@ -58,8 +60,24 @@ public class Mpris2Watcher : GLib.Object private void name_changes_detected ( FreeDesktopObject dbus_obj, string name, string previous_owner, - string current_owner ) { - MprisRoot mpris2_root; + string current_owner ) + { + MprisRoot? mpris2_root = this.create_mpris_root(name); + + if (mpris2_root == null) return; + + if (previous_owner != "" && current_owner == "") { + debug ("Client '%s' gone down", name); + client_disappeared (name); + } + else if (previous_owner == "" && current_owner != "") { + debug ("Client '%s' has appeared", name); + client_appeared (mpris2_root.DesktopEntry); + } + } + + private MprisRoot? create_mpris_root(string name){ + MprisRoot mpris2_root = null; if ( name.has_prefix (MPRIS_PREFIX) ){ try { mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, @@ -69,16 +87,30 @@ public class Mpris2Watcher : GLib.Object catch (IOError e){ warning( "Mpris2watcher could not create a root interface: %s", e.message ); - return; - } - if (previous_owner != "" && current_owner == "") { - debug ("Client '%s' gone down", name); - client_disappeared (name); - } - else if (previous_owner == "" && current_owner != "") { - debug ("Client '%s' has appeared", name); - client_appeared (mpris2_root.DesktopEntry); } } + return mpris2_root; } + + // At startup check to see if there are clients up that we are interested in + // More relevant for development and daemon's like mpd. + private async void check_for_active_clients() + { + string[] interfaces; + try{ + interfaces = yield this.fdesktop_obj.list_names(); + } + catch ( IOError e) { + warning( "Mpris2watcher could fetch active interfaces at startup: %s", + e.message ); + return; + } + foreach (var address in interfaces) { + if (address.has_prefix (MPRIS_PREFIX)){ + MprisRoot? mpris2_root = this.create_mpris_root(address); + if (mpris2_root == null) return; + client_appeared (mpris2_root.DesktopEntry); + } + } + } } \ No newline at end of file -- cgit v1.2.3 From 2a35f9b78b75cd95090142b891c401a46eec9bf3 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Mon, 13 Dec 2010 17:46:42 +0000 Subject: started along the road of removing the familiar db backend and replacing with the g-settings entry approach --- src/familiar-players-db.vala | 24 ------------- src/metadata-menu-item.vala | 6 ++-- src/metadata-widget.c | 10 +++--- src/mpris2-controller.vala | 12 +++---- src/mpris2-watcher.vala | 16 ++++----- src/music-player-bridge.vala | 84 +++++++++++++++++++++++++++----------------- src/player-controller.vala | 14 ++++---- src/sound-service.c | 4 +-- 8 files changed, 84 insertions(+), 86 deletions(-) diff --git a/src/familiar-players-db.vala b/src/familiar-players-db.vala index 7012b5a..96d690a 100644 --- a/src/familiar-players-db.vala +++ b/src/familiar-players-db.vala @@ -160,29 +160,5 @@ public class FamiliarPlayersDB : GLib.Object return this.players_DB.keys; } - public static string? fetch_icon_name(string desktop_path) - { - KeyFile desktop_keyfile = new KeyFile (); - try{ - desktop_keyfile.load_from_file (desktop_path, KeyFileFlags.NONE); - } - catch(GLib.FileError error){ - warning("Error loading keyfile - FileError"); - return null; - } - catch(GLib.KeyFileError error){ - warning("Error loading keyfile - KeyFileError"); - return null; - } - - try{ - return desktop_keyfile.get_string (KeyFileDesktop.GROUP, - KeyFileDesktop.KEY_ICON); - } - catch(GLib.KeyFileError error){ - warning("Error trying to fetch the icon name from the keyfile"); - return null; - } - } } \ No newline at end of file diff --git a/src/metadata-menu-item.vala b/src/metadata-menu-item.vala index e84e902..741bb9f 100644 --- a/src/metadata-menu-item.vala +++ b/src/metadata-menu-item.vala @@ -99,10 +99,10 @@ public class MetadataMenuitem : PlayerItem { File art_file = File.new_for_uri(uri); if(art_file.is_native() == true){ - string path; + string path; try{ - path = Filename.from_uri(uri.strip()); - this.property_set(prop, path); + path = Filename.from_uri ( uri.strip() ); + this.property_set ( prop, path ); } catch(ConvertError e){ warning("Problem converting URI %s to file path", diff --git a/src/metadata-widget.c b/src/metadata-widget.c index 1e2c891..191e134 100644 --- a/src/metadata-widget.c +++ b/src/metadata-widget.c @@ -194,21 +194,23 @@ metadata_image_expose (GtkWidget *metadata, GdkEventExpose *event, gpointer user if(g_string_equal(priv->image_path, priv->old_image_path) == FALSE || priv->theme_change_occured == TRUE){ priv->theme_change_occured = FALSE; - GdkPixbuf* pixbuf; - pixbuf = gdk_pixbuf_new_from_file(priv->image_path->str, NULL); + GdkPixbuf* orig_pixbuf; + orig_pixbuf = gdk_pixbuf_new_from_file(priv->image_path->str, NULL); //g_debug("metadata_load_new_image -> pixbuf from %s", // priv->image_path->str); - if(GDK_IS_PIXBUF(pixbuf) == FALSE){ + if(GDK_IS_PIXBUF(orig_pixbuf) == FALSE){ //g_debug("problem loading the downloaded image just use the placeholder instead"); draw_album_art_placeholder(metadata); return TRUE; } - pixbuf = gdk_pixbuf_scale_simple(pixbuf,60, 60, GDK_INTERP_BILINEAR); + GdkPixbuf* pixbuf; + pixbuf = gdk_pixbuf_scale_simple(orig_pixbuf,60, 60, GDK_INTERP_BILINEAR); gtk_image_set_from_pixbuf(GTK_IMAGE(priv->album_art), pixbuf); g_string_erase(priv->old_image_path, 0, -1); g_string_overwrite(priv->old_image_path, 0, priv->image_path->str); g_object_unref(pixbuf); + g_object_unref(orig_pixbuf); } return FALSE; } diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 59e3122..42d08c9 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -31,7 +31,6 @@ using Dbusmenu; */ public class Mpris2Controller : GLib.Object { - public static const string root_interface = "org.mpris.MediaPlayer2" ; public MprisRoot mpris2_root {get; construct;} public MprisPlayer player {get; construct;} public FreeDesktopProperties properties_interface {get; construct;} @@ -46,16 +45,16 @@ public class Mpris2Controller : GLib.Object construct{ try { this.mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, - root_interface.concat(".").concat(this.owner.mpris_name), + this.owner.dbus_name, "/org/mpris/MediaPlayer2"); this.player = Bus.get_proxy_sync ( BusType.SESSION, - root_interface.concat(".").concat(this.owner.mpris_name), + this.owner.dbus_name, "/org/mpris/MediaPlayer2" ); this.properties_interface = Bus.get_proxy_sync ( BusType.SESSION, "org.freedesktop.Properties.PropertiesChanged", "/org/mpris/MediaPlayer2" ); - this.properties_interface.PropertiesChanged += property_changed_cb; + this.properties_interface.PropertiesChanged.connect ( property_changed_cb ); } catch (IOError e) { error("Problems connecting to the session bus - %s", e.message); @@ -66,8 +65,9 @@ public class Mpris2Controller : GLib.Object HashTable changed_properties, string[] invalid ) { - debug("properties-changed for interface %s and owner %s", interface_source, this.owner.mpris_name); - if(changed_properties == null || interface_source.has_prefix(this.root_interface) == false ){ + debug("properties-changed for interface %s and owner %s", interface_source, this.owner.dbus_name); + if ( changed_properties == null || + interface_source.has_prefix ( Mpris2Watcher.MPRIS_PREFIX ) == false ){ warning("Property-changed hash is null or this is an interface that doesn't concerns us"); return; } diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index d154fcb..7814975 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -20,22 +20,22 @@ with this program. If not, see . [DBus (name = "org.freedesktop.DBus")] public interface FreeDesktopObject: Object { public abstract async string[] list_names() throws IOError; - public abstract signal void name_owner_changed (string name, - string old_owner, - string new_owner); + public abstract signal void name_owner_changed ( string name, + string old_owner, + string new_owner ); } public class Mpris2Watcher : GLib.Object { private const string FREEDESKTOP_SERVICE = "org.freedesktop.DBus"; private const string FREEDESKTOP_OBJECT = "/org/freedesktop/DBus"; - private const string MPRIS_PREFIX = "org.mpris.MediaPlayer2."; + public const string MPRIS_PREFIX = "org.mpris.MediaPlayer2."; private const string MPRIS_MEDIA_PLAYER_PATH = "/org/mpris/MediaPlayer2"; FreeDesktopObject fdesktop_obj; - public signal void client_appeared ( string desktop_name ); - public signal void client_disappeared ( string mpris_root_interface ); + public signal void client_appeared ( string desktop_file_name, string dbus_name ); + public signal void client_disappeared ( string dbus_name ); public Mpris2Watcher () { @@ -72,7 +72,7 @@ public class Mpris2Watcher : GLib.Object } else if (previous_owner == "" && current_owner != "") { debug ("Client '%s' has appeared", name); - client_appeared (mpris2_root.DesktopEntry); + client_appeared (mpris2_root.DesktopEntry, name); } } @@ -109,7 +109,7 @@ public class Mpris2Watcher : GLib.Object if (address.has_prefix (MPRIS_PREFIX)){ MprisRoot? mpris2_root = this.create_mpris_root(address); if (mpris2_root == null) return; - client_appeared (mpris2_root.DesktopEntry); + client_appeared (mpris2_root.DesktopEntry, address); } } } diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 5133770..0d1b0e4 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -25,17 +25,15 @@ public class MusicPlayerBridge : GLib.Object { private Dbusmenu.Menuitem root_menu; private HashMap registered_clients; - private FamiliarPlayersDB playersDB; private Mpris2Watcher watcher; private const string DESKTOP_PREFIX = "/usr/share/applications/"; public MusicPlayerBridge() { - playersDB = new FamiliarPlayersDB(); registered_clients = new HashMap (); } - private void try_to_add_inactive_familiar_clients(){ + /*private void try_to_add_inactive_familiar_clients(){ foreach(string app in this.playersDB.records()){ if(app == null){ warning("App string in keyfile is null therefore moving on to next player"); @@ -61,7 +59,7 @@ public class MusicPlayerBridge : GLib.Object PlayerController.state.OFFLINE); this.registered_clients.set(mpris_key, ctrl); } - } + }*/ private int calculate_menu_position() { @@ -73,20 +71,15 @@ public class MusicPlayerBridge : GLib.Object } } - /*public void on_server_added(Indicate.ListenerServer object, string type) + public void client_has_become_available ( string desktop, string dbus_name ) { - debug("MusicPlayerBridge -> on_server_added with value %s", type); - if(server_is_not_of_interest(type)) return; - if ( this.root_menu != null ){ - listener_get_server_property_cb cb = (listener_get_server_property_cb)desktop_info_callback; - this.listener.server_get_desktop(object, cb, this); + if (desktop == null || desktop == ""){ + warning("Client %s attempting to register without desktop entry being set on the mpris root", + dbus_name); + return; } - }*/ - - public void client_has_become_available ( string desktop_file_name ) - { - debug ( "client_has_become_available %s", desktop_file_name ); - string path = DESKTOP_PREFIX.concat ( desktop_file_name.concat( ".desktop" ) ); + debug ( "client_has_become_available %s", desktop ); + string path = DESKTOP_PREFIX.concat ( desktop.concat( ".desktop" ) ); AppInfo? app_info = create_app_info ( path ); if ( app_info == null ){ warning ( "Could not create app_info for path %s \n Getting out of here ", path); @@ -94,25 +87,24 @@ public class MusicPlayerBridge : GLib.Object } var mpris_key = determine_key ( path ); - - if ( this.playersDB.already_familiar ( path ) == false ){ - debug("New client has registered that we have not seen before: %s", desktop_file_name ); - this.playersDB.insert ( path ); + // Are we sure clients will appear like this with the new registration method in place. + if ( this.registered_clients.has_key (mpris_key) == false ){ + debug("New client has registered that we have not seen before: %s", desktop ); PlayerController ctrl = new PlayerController ( this.root_menu, app_info, - mpris_key, - playersDB.fetch_icon_name(path), + dbus_name, + this.fetch_icon_name(path), this.calculate_menu_position(), PlayerController.state.READY ); - this.registered_clients.set ( mpris_key, ctrl ); + this.registered_clients.set ( mpris_key, ctrl ); debug ( "successfully created appinfo and instance from path and set it on the respective instance" ); - } - else{ - this.registered_clients[mpris_key].update_state ( PlayerController.state.READY ); - this.registered_clients[mpris_key].activate ( ); - debug("Ignoring desktop file path callback because the db cache file has it already: %s \n", path); - } } + else{ + this.registered_clients[mpris_key].update_state ( PlayerController.state.READY ); + this.registered_clients[mpris_key].activate ( ); + debug("Ignoring desktop file path callback because the db cache file has it already: %s \n", path); + } + } public void client_has_vanished ( string mpris_root_interface ) { @@ -127,16 +119,15 @@ public class MusicPlayerBridge : GLib.Object } } - public void set_root_menu_item(Dbusmenu.Menuitem menu) + public void set_root_menu_item ( Dbusmenu.Menuitem menu ) { this.root_menu = menu; - this.try_to_add_inactive_familiar_clients(); this.watcher = new Mpris2Watcher (); this.watcher.client_appeared += this.client_has_become_available; this.watcher.client_disappeared += this.client_has_vanished; } - public static AppInfo? create_app_info ( string path ) + private static AppInfo? create_app_info ( string path ) { DesktopAppInfo info = new DesktopAppInfo.from_filename ( path ) ; if ( path == null || info == null ){ @@ -147,6 +138,35 @@ public class MusicPlayerBridge : GLib.Object return app_info; } + private static string? fetch_icon_name(string desktop_path) + { + KeyFile desktop_keyfile = new KeyFile (); + try{ + desktop_keyfile.load_from_file (desktop_path, KeyFileFlags.NONE); + } + catch(GLib.FileError error){ + warning("Error loading keyfile - FileError"); + return null; + } + catch(GLib.KeyFileError error){ + warning("Error loading keyfile - KeyFileError"); + return null; + } + + try{ + return desktop_keyfile.get_string (KeyFileDesktop.GROUP, + KeyFileDesktop.KEY_ICON); + } + catch(GLib.KeyFileError error){ + warning("Error trying to fetch the icon name from the keyfile"); + return null; + } + } + + /* + Messy but necessary method to consolidate desktop filesnames and mpris dbus names + into the one single word string (used as the key in the players hash). + */ private static string? determine_key(owned string path) { var tokens = path.split( "/" ); diff --git a/src/player-controller.vala b/src/player-controller.vala index 0b540f9..9e00258 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -44,7 +44,7 @@ public class PlayerController : GLib.Object private Dbusmenu.Menuitem root_menu; public string name { get; set;} - public string mpris_name { get; set;} + public string dbus_name { get; set;} public ArrayList custom_items; public Mpris2Controller mpris_bridge; public AppInfo? app_info { get; set;} @@ -53,21 +53,21 @@ public class PlayerController : GLib.Object public PlayerController(Dbusmenu.Menuitem root, GLib.AppInfo app, - string mpris_name, + string dbus_name, string icon_name, int offset, state initial_state) { this.root_menu = root; this.app_info = app; + this.dbus_name = dbus_name; this.name = format_player_name(this.app_info.get_name()); - this.mpris_name = mpris_name; this.icon_name = icon_name; this.custom_items = new ArrayList(); this.current_state = initial_state; this.menu_offset = offset; - construct_widgets(); - establish_mpris_connection(); + this.construct_widgets(); + this.establish_mpris_connection(); this.update_layout(); } @@ -162,7 +162,7 @@ public class PlayerController : GLib.Object foreach(PlayerItem item in this.custom_items){ root_menu.child_add_position(item, this.menu_offset + this.custom_items.index_of(item)); } - } + } private static string format_player_name(owned string app_info_name) { @@ -173,8 +173,8 @@ public class PlayerController : GLib.Object } if(result.length > 1){ result = result.up(1).concat(result.slice(1, result.length)); - debug("PlayerController->format_player_name - : %s", result); } + debug("PlayerController->format_player_name - : %s", result); return result; } diff --git a/src/sound-service.c b/src/sound-service.c index 98f1881..defcb94 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,8 +40,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); - close_pulse_activites(); - g_main_loop_quit(mainloop); + //close_pulse_activites(); + //g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3 From 8396e05ce716296377f2e4550e0c929dca30518e Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 14 Dec 2010 16:41:10 +0000 Subject: gsettings all the way --- data/Makefile.am | 41 ++++++++----------------- data/com.canonical.indicators.sound.gschema.xml | 20 ++++++++++++ data/indicator-sound.schemas.in | 16 ---------- src/music-player-bridge.vala | 10 ++++-- 4 files changed, 40 insertions(+), 47 deletions(-) create mode 100644 data/com.canonical.indicators.sound.gschema.xml delete mode 100644 data/indicator-sound.schemas.in diff --git a/data/Makefile.am b/data/Makefile.am index aaa6ca4..730f166 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -5,39 +5,22 @@ service_in_files = indicator-sound.service.in dbus_services_DATA = $(service_in_files:.service.in=.service) %.service: %.service.in - sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ + sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ ############################## -# GConf Schema +# GSettings Schema ############################## -schemadir = \ - $(GCONF_SCHEMA_FILE_DIR) +gsettings_SCHEMAS = \ + com.canonical.indicators.sound.gschema.xml +@GSETTINGS_RULES@ -schema_in_files = \ - indicator-sound.schemas.in - -schema_DATA = \ - $(schema_in_files:.schemas.in=.schemas) - -@INTLTOOL_SCHEMAS_RULE@ - - -#$(dbus_services_DATA): $(service_in_files) Makefile -# sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ - -EXTRA_DIST = \ - $(service_in_files) \ - $(schema_in_files) +############################## -CLEANFILES = \ - $(dbus_services_DATA) \ - $(schema_DATA) +EXTRA_DIST = \ + $(service_in_files) \ + $(gsettings_SCHEMAS) -if GCONF_SCHEMAS_INSTALL -install-data-local: - GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) \ - gconftool-2 --makefile-install-rule $(schema_DATA) -else -install-data-local: -endif +CLEANFILES = \ + $(dbus_services_DATA) + \ No newline at end of file diff --git a/data/com.canonical.indicators.sound.gschema.xml b/data/com.canonical.indicators.sound.gschema.xml new file mode 100644 index 0000000..4284527 --- /dev/null +++ b/data/com.canonical.indicators.sound.gschema.xml @@ -0,0 +1,20 @@ + + + + + A list of applications blacklisted from the sound menu + + Each media player which abides by the MPRIS2 spec will automatically appear in the menu. + This array should contain the desktop file names (minus .desktop suffix) of applications which + do not want to be included in the sound menu. + + + + FALSE + Initial setting for global mute (mute all) on the menu + + On start up volume should not be muted. + + + + diff --git a/data/indicator-sound.schemas.in b/data/indicator-sound.schemas.in deleted file mode 100644 index 9ad0f39..0000000 --- a/data/indicator-sound.schemas.in +++ /dev/null @@ -1,16 +0,0 @@ - - - - - /schemas/apps/indicator-sound/volume_mute - /apps/indicator-sound/volume_mute - indicator-sound - bool - FALSE - - Volume is not muted by default - On start up volume should not be muted. - - - - diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 0d1b0e4..51ecc4c 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -27,12 +27,18 @@ public class MusicPlayerBridge : GLib.Object private HashMap registered_clients; private Mpris2Watcher watcher; private const string DESKTOP_PREFIX = "/usr/share/applications/"; - + private Settings settings; + public MusicPlayerBridge() { - registered_clients = new HashMap (); } + construct{ + this.registered_clients = new HashMap (); + this.settings = new Settings("com.canonical.indicators.sound"); + } + + /*private void try_to_add_inactive_familiar_clients(){ foreach(string app in this.playersDB.records()){ if(app == null){ -- cgit v1.2.3 From 7ef502c18c6ccf850c83fabebfb1884c458320b4 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 14 Dec 2010 17:04:46 +0000 Subject: autofoo in order for gsettings --- data/Makefile.am | 24 +++++++++--------------- data/indicator-sound.service.in | 2 ++ 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/data/Makefile.am b/data/Makefile.am index 730f166..3f54f64 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,26 +1,20 @@ SUBDIRS = icons +gsettings_SCHEMAS = \ + com.canonical.indicators.sound.gschema.xml +@GSETTINGS_RULES@ + dbus_servicesdir = $(DBUSSERVICEDIR) -service_in_files = indicator-sound.service.in -dbus_services_DATA = $(service_in_files:.service.in=.service) +dbus_services_DATA = indicator-sound.service %.service: %.service.in sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ -############################## -# GSettings Schema -############################## - -gsettings_SCHEMAS = \ - com.canonical.indicators.sound.gschema.xml -@GSETTINGS_RULES@ - -############################## -EXTRA_DIST = \ - $(service_in_files) \ - $(gsettings_SCHEMAS) +EXTRA_DIST = \ + $(gsettings_SCHEMAS) \ + indicator-sound.service.in -CLEANFILES = \ +CLEANFILES = \ $(dbus_services_DATA) \ No newline at end of file diff --git a/data/indicator-sound.service.in b/data/indicator-sound.service.in index 883d31d..7a957cb 100644 --- a/data/indicator-sound.service.in +++ b/data/indicator-sound.service.in @@ -1,3 +1,5 @@ [D-BUS Service] Name=org.ayatana.indicator.sound Exec=@libexecdir@/indicator-sound-service + + -- cgit v1.2.3 From 37eb76fbc08dad63341a4deff3bcaf433e1082ab Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 14 Dec 2010 17:29:49 +0000 Subject: added glib macro necessaries to configure.ac --- configure.ac | 6 ++++++ data/Makefile.am | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index c8ae871..ea4ab45 100644 --- a/configure.ac +++ b/configure.ac @@ -89,6 +89,12 @@ fi AC_SUBST(INDICATORDIR) AC_SUBST(INDICATORICONSDIR) +########################### +# Grab the GSettings Macros +########################### + +GLIB_GSETTINGS + ########################### # DBus Service Info ########################### diff --git a/data/Makefile.am b/data/Makefile.am index 3f54f64..6f2ac61 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -10,7 +10,6 @@ dbus_services_DATA = indicator-sound.service %.service: %.service.in sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ - EXTRA_DIST = \ $(gsettings_SCHEMAS) \ indicator-sound.service.in -- cgit v1.2.3 From 7e7fa1765dc095f441d7290f50c5a773ba531b02 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 14 Dec 2010 17:53:47 +0000 Subject: changed the name of the dbus address to be used between the indicator and service --- data/indicator-sound.service.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/indicator-sound.service.in b/data/indicator-sound.service.in index 7a957cb..8059216 100644 --- a/data/indicator-sound.service.in +++ b/data/indicator-sound.service.in @@ -1,5 +1,5 @@ [D-BUS Service] -Name=org.ayatana.indicator.sound +Name=com.canonical.indicators.sound Exec=@libexecdir@/indicator-sound-service -- cgit v1.2.3 From 02b6109a523fdf2236788628447186682a9adf1b Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 14 Dec 2010 18:00:36 +0000 Subject: fixed annoying autofoo issues --- data/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/Makefile.am b/data/Makefile.am index 6f2ac61..f33b470 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -8,7 +8,7 @@ dbus_servicesdir = $(DBUSSERVICEDIR) dbus_services_DATA = indicator-sound.service %.service: %.service.in - sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ + sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ EXTRA_DIST = \ $(gsettings_SCHEMAS) \ -- cgit v1.2.3 From 57e6249df95fd120eee8ed4013210d359cdeee97 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 14 Dec 2010 18:27:45 +0000 Subject: changed over dbus internal names --- src/dbus-shared-names.h | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/src/dbus-shared-names.h b/src/dbus-shared-names.h index 3062ac5..a62238b 100644 --- a/src/dbus-shared-names.h +++ b/src/dbus-shared-names.h @@ -23,26 +23,12 @@ with this program. If not, see . #ifndef __DBUS_SHARED_NAMES_H__ -#define __DBUS_SHARED_NAMES_H__ 1 - -#define INDICATOR_STATUS_DBUS_NAME "org.ayatana.indicator.status" -#define INDICATOR_STATUS_DBUS_OBJECT "/org/ayatana/indicator/status/menu" -#define INDICATOR_STATUS_SERVICE_DBUS_OBJECT "/org/ayatana/indicator/status/service" -#define INDICATOR_STATUS_SERVICE_DBUS_INTERFACE "org.ayatana.indicator.status.service" - -#define INDICATOR_USERS_DBUS_NAME "org.ayatana.indicator.users" -#define INDICATOR_USERS_DBUS_OBJECT "/org/ayatana/indicator/users/menu" -#define INDICATOR_USERS_SERVICE_DBUS_OBJECT "/org/gnome/DisplayManager/UserManager" -#define INDICATOR_USERS_SERVICE_DBUS_INTERFACE "org.gnome.DisplayManager.UserManager" - -#define INDICATOR_SESSION_DBUS_NAME "org.ayatana.indicator.session" -#define INDICATOR_SESSION_DBUS_OBJECT "/org/ayatana/indicator/session/menu" -#define INDICATOR_SESSION_DBUS_VERSION 0 - -#define INDICATOR_SOUND_DBUS_NAME "org.ayatana.indicator.sound" -#define INDICATOR_SOUND_DBUS_OBJECT "/org/ayatana/indicator/sound/menu" -#define INDICATOR_SOUND_SERVICE_DBUS_OBJECT "/org/ayatana/indicator/sound/service" -#define INDICATOR_SOUND_SERVICE_DBUS_INTERFACE "org.ayatana.indicator.sound" +#define __DBUS_SHARED_NAMES_H__ + +#define INDICATOR_SOUND_DBUS_NAME "com.canonical.indicators.sound" +#define INDICATOR_SOUND_DBUS_OBJECT "/com/canonical/indicators/sound/menu" +#define INDICATOR_SOUND_SERVICE_DBUS_OBJECT "/com/canonical/indicators/sound/service" +#define INDICATOR_SOUND_SERVICE_DBUS_INTERFACE "com.canonical.indicators.sound" #define INDICATOR_SOUND_DBUS_VERSION 0 #endif /* __DBUS_SHARED_NAMES_H__ */ -- cgit v1.2.3 From aaf57407f00aa59df3699794496fd42a731ad7db Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 15 Dec 2010 14:32:27 +0000 Subject: settings schema defined and handling code wrote --- data/com.canonical.indicators.sound.gschema.xml | 25 +++++++---- src/Makefile.am | 2 +- src/music-player-bridge.vala | 10 ++++- src/settings-manager.vala | 55 +++++++++++++++++++++++++ src/sound-service-dbus.c | 1 - 5 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 src/settings-manager.vala diff --git a/data/com.canonical.indicators.sound.gschema.xml b/data/com.canonical.indicators.sound.gschema.xml index 4284527..e8e4c86 100644 --- a/data/com.canonical.indicators.sound.gschema.xml +++ b/data/com.canonical.indicators.sound.gschema.xml @@ -1,19 +1,28 @@ - - + A list of applications blacklisted from the sound menu + [] - Each media player which abides by the MPRIS2 spec will automatically appear in the menu. - This array should contain the desktop file names (minus .desktop suffix) of applications which - do not want to be included in the sound menu. + Each media player which abides by the MPRIS2 spec will automatically appear in the menu. + This array should contain the desktop file names (minus .desktop suffix) of applications which + do not want to be included in the sound menu. - - FALSE + + A list of applications which at some point have registered with the sound menu + [] + + Each media player which abides by the MPRIS2 spec will automatically appear in the menu. + This array should contain the desktop file names (minus .desktop suffix) of applications which + have at some point appeared in the menU. This allows the menu remember and display offlined applications. + + + + false Initial setting for global mute (mute all) on the menu - On start up volume should not be muted. + On start up volume should not be muted. diff --git a/src/Makefile.am b/src/Makefile.am index 1c381f5..5ef9ef0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,7 +64,7 @@ music_bridge_VALASOURCES = \ mpris2-watcher.vala \ mpris2-controller.vala \ player-item.vala \ - familiar-players-db.vala \ + settings-manager.vala \ fetch-file.vala diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 51ecc4c..6a45d0c 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -23,6 +23,7 @@ using GLib; public class MusicPlayerBridge : GLib.Object { + private SettingsManager settings_manager; private Dbusmenu.Menuitem root_menu; private HashMap registered_clients; private Mpris2Watcher watcher; @@ -35,9 +36,14 @@ public class MusicPlayerBridge : GLib.Object construct{ this.registered_clients = new HashMap (); - this.settings = new Settings("com.canonical.indicators.sound"); + this.settings_manager = new SettingsManager(); + this.settings_manager.connect.blacklist_updates (on_blacklist_update); } + private void on_black_list_updated ( string[] blacklist ) + { + debug("some blacklist update"); + } /*private void try_to_add_inactive_familiar_clients(){ foreach(string app in this.playersDB.records()){ @@ -143,7 +149,7 @@ public class MusicPlayerBridge : GLib.Object GLib.AppInfo app_info = info as GLib.AppInfo; return app_info; } - + private static string? fetch_icon_name(string desktop_path) { KeyFile desktop_keyfile = new KeyFile (); diff --git a/src/settings-manager.vala b/src/settings-manager.vala new file mode 100644 index 0000000..9068c05 --- /dev/null +++ b/src/settings-manager.vala @@ -0,0 +1,55 @@ +/* +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +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 . +*/ +using Gee; + +public class SettingsManager : GLib.Object +{ + private Settings settings; + public signal void blacklist_updates ( string[] new_blacklist ); + + public SettingsManager ( ){ + } + construct{ + this.settings = new Settings ("com.canonical.indicators.sound"); + settings.changed["blacklisted-media-players"].connect (on_blacklist_event); + this.fetch_entries.begin(); + } + + public string[] fetch_blacklist() + { + return this.blacklist_updates(this.settings.get_strv ("blacklisted-media-players")); + } + + public string[] fetch_interested() + { + return this.interested_updates(this.settings.get_strv ("interested-media-players")); + } + + public bool add_interested(string app_desktop_name) + { + string[] already_interested = fetch_interested(); + already_interested.append ( app_desktop_name ); + return this.settings.set_strv( already_interested ); + } + + private on_blacklist_event() + { + this.blacklist_updates(this.settings.get_strv ("blacklisted-media-players")); + } +} \ No newline at end of file diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index d553285..0760247 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -42,7 +42,6 @@ struct _SoundServiceDbusPrivate { gboolean sink_availability; }; - /* Signals */ enum { SINK_INPUT_WHILE_MUTED, -- cgit v1.2.3 From bb13f9134c42480ada8128cfbd3b19ec2d68865b Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 15 Dec 2010 16:23:15 +0000 Subject: clients properly remembered using gsettings --- data/com.canonical.indicators.sound.gschema.xml | 2 +- src/music-player-bridge.vala | 62 ++++++++++++------------- src/settings-manager.vala | 12 ++--- 3 files changed, 37 insertions(+), 39 deletions(-) diff --git a/data/com.canonical.indicators.sound.gschema.xml b/data/com.canonical.indicators.sound.gschema.xml index e8e4c86..43cc645 100644 --- a/data/com.canonical.indicators.sound.gschema.xml +++ b/data/com.canonical.indicators.sound.gschema.xml @@ -1,5 +1,5 @@ - + A list of applications blacklisted from the sound menu [] diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 6a45d0c..b13b7f3 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -37,42 +37,35 @@ public class MusicPlayerBridge : GLib.Object construct{ this.registered_clients = new HashMap (); this.settings_manager = new SettingsManager(); - this.settings_manager.connect.blacklist_updates (on_blacklist_update); + this.settings_manager.blacklist_updates.connect ( this.on_blacklist_update ); } - private void on_black_list_updated ( string[] blacklist ) + private void on_blacklist_update ( string[] blacklist ) { debug("some blacklist update"); } - - /*private void try_to_add_inactive_familiar_clients(){ - foreach(string app in this.playersDB.records()){ - if(app == null){ - warning("App string in keyfile is null therefore moving on to next player"); - continue; - } - debug("attempting to make an app info from %s", app); - - DesktopAppInfo info = new DesktopAppInfo.from_filename(app); - - if(info == null){ - warning("Could not create a desktopappinfo instance from app,: %s , moving on to the next client", app); + private void try_to_add_inactive_familiar_clients() + { + foreach ( string desktop in this.settings_manager.fetch_interested()){ + debug ( "interested client found : %s", desktop ); + string path = DESKTOP_PREFIX.concat ( desktop.concat( ".desktop" ) ); + AppInfo? app_info = create_app_info ( path ); + if ( app_info == null ){ + warning ( "Could not create app_info for path %s \n Getting out of here ", path); continue; } - - GLib.AppInfo app_info = info as GLib.AppInfo; - var mpris_key = determine_key ( app ); - PlayerController ctrl = new PlayerController(this.root_menu, - app_info, - mpris_key, - playersDB.fetch_icon_name(app), - calculate_menu_position(), - PlayerController.state.OFFLINE); - this.registered_clients.set(mpris_key, ctrl); - } - }*/ - + var mpris_key = determine_key ( path ); + PlayerController ctrl = new PlayerController ( this.root_menu, + app_info, + mpris_key, + this.fetch_icon_name(path), + calculate_menu_position(), + PlayerController.state.OFFLINE ); + this.registered_clients.set(mpris_key, ctrl); + } + } + private int calculate_menu_position() { if(this.registered_clients.size == 0){ @@ -109,12 +102,14 @@ public class MusicPlayerBridge : GLib.Object this.calculate_menu_position(), PlayerController.state.READY ); this.registered_clients.set ( mpris_key, ctrl ); - debug ( "successfully created appinfo and instance from path and set it on the respective instance" ); + debug ( "Have not seen this %s before, new controller created.", desktop ); + this.settings_manager.add_interested ( desktop ); + debug ( "application added to the interested list" ); } else{ this.registered_clients[mpris_key].update_state ( PlayerController.state.READY ); this.registered_clients[mpris_key].activate ( ); - debug("Ignoring desktop file path callback because the db cache file has it already: %s \n", path); + debug("Application has already registered - awaken the hibernation: %s \n", path); } } @@ -137,6 +132,7 @@ public class MusicPlayerBridge : GLib.Object this.watcher = new Mpris2Watcher (); this.watcher.client_appeared += this.client_has_become_available; this.watcher.client_disappeared += this.client_has_vanished; + this.try_to_add_inactive_familiar_clients(); } private static AppInfo? create_app_info ( string path ) @@ -176,8 +172,10 @@ public class MusicPlayerBridge : GLib.Object } /* - Messy but necessary method to consolidate desktop filesnames and mpris dbus names - into the one single word string (used as the key in the players hash). + Messy but necessary method to consolidate desktop filesnames and mpris dbus names + into the one single word string (used as the key in the players hash). + So this means that we can determine the key for the players_hash from the + dbus interface name or the desktop file name. */ private static string? determine_key(owned string path) { diff --git a/src/settings-manager.vala b/src/settings-manager.vala index 9068c05..05db430 100644 --- a/src/settings-manager.vala +++ b/src/settings-manager.vala @@ -28,27 +28,27 @@ public class SettingsManager : GLib.Object construct{ this.settings = new Settings ("com.canonical.indicators.sound"); settings.changed["blacklisted-media-players"].connect (on_blacklist_event); - this.fetch_entries.begin(); } public string[] fetch_blacklist() { - return this.blacklist_updates(this.settings.get_strv ("blacklisted-media-players")); + return this.settings.get_strv ("blacklisted-media-players"); } public string[] fetch_interested() { - return this.interested_updates(this.settings.get_strv ("interested-media-players")); + return this.settings.get_strv ("interested-media-players"); } public bool add_interested(string app_desktop_name) { string[] already_interested = fetch_interested(); - already_interested.append ( app_desktop_name ); - return this.settings.set_strv( already_interested ); + already_interested += (app_desktop_name); + return this.settings.set_strv( "interested-media-players", + already_interested ); } - private on_blacklist_event() + private void on_blacklist_event() { this.blacklist_updates(this.settings.get_strv ("blacklisted-media-players")); } -- cgit v1.2.3 From de3ed4111ef50b847e1ba4d6ea06e13f913ba7a0 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 16 Dec 2010 12:36:43 +0000 Subject: race condtion on playbackstatus accommodated for and dbus names changed over the new canonical naming --- data/com.canonical.indicators.sound.gschema.xml | 2 +- data/indicator-sound.service.in | 2 -- src/dbus-shared-names.h | 2 +- src/indicator-sound.c | 4 ++-- src/mpris2-controller.vala | 15 +++++++++++++-- src/music-player-bridge.vala | 10 +++++----- src/player-controller.vala | 7 ++++--- src/pulse-manager.c | 4 ++-- src/sound-service.xml | 4 ++-- 9 files changed, 30 insertions(+), 20 deletions(-) diff --git a/data/com.canonical.indicators.sound.gschema.xml b/data/com.canonical.indicators.sound.gschema.xml index 43cc645..3850f65 100644 --- a/data/com.canonical.indicators.sound.gschema.xml +++ b/data/com.canonical.indicators.sound.gschema.xml @@ -11,7 +11,7 @@ A list of applications which at some point have registered with the sound menu - [] + [ 'banshee-1' ] Each media player which abides by the MPRIS2 spec will automatically appear in the menu. This array should contain the desktop file names (minus .desktop suffix) of applications which diff --git a/data/indicator-sound.service.in b/data/indicator-sound.service.in index 8059216..a80cd03 100644 --- a/data/indicator-sound.service.in +++ b/data/indicator-sound.service.in @@ -1,5 +1,3 @@ [D-BUS Service] Name=com.canonical.indicators.sound Exec=@libexecdir@/indicator-sound-service - - diff --git a/src/dbus-shared-names.h b/src/dbus-shared-names.h index a62238b..9d1e875 100644 --- a/src/dbus-shared-names.h +++ b/src/dbus-shared-names.h @@ -23,7 +23,7 @@ with this program. If not, see . #ifndef __DBUS_SHARED_NAMES_H__ -#define __DBUS_SHARED_NAMES_H__ +#define __DBUS_SHARED_NAMES_H__ 1 #define INDICATOR_SOUND_DBUS_NAME "com.canonical.indicators.sound" #define INDICATOR_SOUND_DBUS_OBJECT "/com/canonical/indicators/sound/menu" diff --git a/src/indicator-sound.c b/src/indicator-sound.c index d5cc54c..34f5ed9 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -561,7 +561,7 @@ fetch_sink_availability_from_dbus(IndicatorSound* self) GError * error = NULL; gboolean * available_input; available_input = g_new0(gboolean, 1); - org_ayatana_indicator_sound_get_sink_availability(sound_dbus_proxy, available_input, &error); + com_canonical_indicators_sound_get_sink_availability(sound_dbus_proxy, available_input, &error); if (error != NULL) { g_warning("Unable to fetch AVAILABILITY at indicator start up: %s", error->message); g_error_free(error); @@ -593,7 +593,7 @@ fetch_mute_value_from_dbus() GError * error = NULL; gboolean *mute_input; mute_input = g_new0(gboolean, 1); - org_ayatana_indicator_sound_get_sink_mute(sound_dbus_proxy, mute_input, &error); + com_canonical_indicators_sound_get_sink_mute(sound_dbus_proxy, mute_input, &error); if (error != NULL) { g_warning("Unable to fetch MUTE at indicator start up: %s", error->message); g_error_free(error); diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 42d08c9..7f14efe 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -46,7 +46,7 @@ public class Mpris2Controller : GLib.Object try { this.mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, this.owner.dbus_name, - "/org/mpris/MediaPlayer2"); + "/org/mpris/MediaPlayer2" ); this.player = Bus.get_proxy_sync ( BusType.SESSION, this.owner.dbus_name, "/org/mpris/MediaPlayer2" ); @@ -73,7 +73,11 @@ public class Mpris2Controller : GLib.Object } Variant? play_v = changed_properties.lookup("PlaybackStatus"); if(play_v != null){ + // Race condition sometimes appears with the playback status + // 200ms timeout ensures we have the correct playback status at all times. string state = this.player.PlaybackStatus; + //debug("in the property update and the playback status = %s and update = %s", state, (string)play_v); + Timeout.add ( 200, ensure_correct_playback_status ); TransportMenuitem.state p = (TransportMenuitem.state)this.determine_play_state(state); (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p); } @@ -81,7 +85,7 @@ public class Mpris2Controller : GLib.Object if(meta_v != null){ GLib.HashTable changed_updates = clean_metadata(); PlayerItem metadata = this.owner.custom_items[PlayerController.widget_order.METADATA]; - metadata.reset( MetadataMenuitem.attributes_format()); + metadata.reset ( MetadataMenuitem.attributes_format()); metadata.update ( changed_updates, MetadataMenuitem.attributes_format()); metadata.property_set_bool ( MENUITEM_PROP_VISIBLE, @@ -89,6 +93,13 @@ public class Mpris2Controller : GLib.Object } } + private bool ensure_correct_playback_status(){ + debug("TEST playback status = %s", this.player.PlaybackStatus); + TransportMenuitem.state p = (TransportMenuitem.state)this.determine_play_state(this.player.PlaybackStatus); + (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p); + return false; + } + private GLib.HashTable? clean_metadata() { GLib.HashTable changed_updates = this.player.Metadata; diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index b13b7f3..327a775 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -58,11 +58,11 @@ public class MusicPlayerBridge : GLib.Object var mpris_key = determine_key ( path ); PlayerController ctrl = new PlayerController ( this.root_menu, app_info, - mpris_key, + null, this.fetch_icon_name(path), calculate_menu_position(), PlayerController.state.OFFLINE ); - this.registered_clients.set(mpris_key, ctrl); + this.registered_clients.set(mpris_key, ctrl); } } @@ -94,7 +94,7 @@ public class MusicPlayerBridge : GLib.Object var mpris_key = determine_key ( path ); // Are we sure clients will appear like this with the new registration method in place. if ( this.registered_clients.has_key (mpris_key) == false ){ - debug("New client has registered that we have not seen before: %s", desktop ); + debug("New client has registered that we have not seen before: %s", dbus_name ); PlayerController ctrl = new PlayerController ( this.root_menu, app_info, dbus_name, @@ -108,8 +108,8 @@ public class MusicPlayerBridge : GLib.Object } else{ this.registered_clients[mpris_key].update_state ( PlayerController.state.READY ); - this.registered_clients[mpris_key].activate ( ); - debug("Application has already registered - awaken the hibernation: %s \n", path); + this.registered_clients[mpris_key].activate ( dbus_name ); + debug("Application has already registered - awaken the hibernation: %s \n", dbus_name ); } } diff --git a/src/player-controller.vala b/src/player-controller.vala index 9e00258..b5c2d76 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -53,7 +53,7 @@ public class PlayerController : GLib.Object public PlayerController(Dbusmenu.Menuitem root, GLib.AppInfo app, - string dbus_name, + string? dbus_name, string icon_name, int offset, state initial_state) @@ -78,8 +78,9 @@ public class PlayerController : GLib.Object this.update_layout(); } - public void activate() + public void activate( string dbus_name ) { + this.dbus_name = dbus_name; this.establish_mpris_connection(); } @@ -103,7 +104,7 @@ public class PlayerController : GLib.Object private void establish_mpris_connection() { - if(this.current_state != state.READY){ + if(this.current_state != state.READY && this.dbus_name != null ){ debug("establish_mpris_connection - Not ready to connect"); return; } diff --git a/src/pulse-manager.c b/src/pulse-manager.c index b002094..4443044 100644 --- a/src/pulse-manager.c +++ b/src/pulse-manager.c @@ -65,7 +65,7 @@ void establish_pulse_activities(SoundServiceDbus *service) pa_main_loop = pa_glib_mainloop_new(g_main_context_default()); g_assert(pa_main_loop); pulse_context = pa_context_new(pa_glib_mainloop_get_api(pa_main_loop), - "ayatana.indicator.sound"); + "com.canonical.indicators.sound"); g_assert(pulse_context); sink_hash = g_hash_table_new_full(g_direct_hash, @@ -103,7 +103,7 @@ reconnect_to_pulse() sink_hash = NULL; } pulse_context = pa_context_new( pa_glib_mainloop_get_api( pa_main_loop ), - "ayatana.indicator.sound" ); + "com.canonical.indicators.sound" ); g_assert(pulse_context); sink_hash = g_hash_table_new_full( g_direct_hash, g_direct_equal, NULL, diff --git a/src/sound-service.xml b/src/sound-service.xml index ee19ceb..a552d52 100644 --- a/src/sound-service.xml +++ b/src/sound-service.xml @@ -1,6 +1,6 @@ - - + + -- cgit v1.2.3 From 4c9ef773092664590d8e6e4fd46d31a35122ab6a Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 16 Dec 2010 12:38:34 +0000 Subject: tidy up --- src/sound-service.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound-service.c b/src/sound-service.c index defcb94..98f1881 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,8 +40,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); - //close_pulse_activites(); - //g_main_loop_quit(mainloop); + close_pulse_activites(); + g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3 From ce99ec3832eaca2d078dc6fb5a1bf3225cd87b7b Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 16 Dec 2010 16:22:51 +0000 Subject: startup bug fixed --- src/player-controller.vala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/player-controller.vala b/src/player-controller.vala index b5c2d76..97f5303 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -29,7 +29,7 @@ public class PlayerController : GLib.Object SEPARATOR, TITLE, METADATA, - TRANSPORT, + TRANSPORT } public enum state{ @@ -104,7 +104,7 @@ public class PlayerController : GLib.Object private void establish_mpris_connection() { - if(this.current_state != state.READY && this.dbus_name != null ){ + if(this.current_state != state.READY || this.dbus_name == null ){ debug("establish_mpris_connection - Not ready to connect"); return; } @@ -179,7 +179,7 @@ public class PlayerController : GLib.Object return result; } - public void determine_state() + private void determine_state() { if(this.mpris_bridge.connected() == true){ this.update_state(state.CONNECTED); -- cgit v1.2.3 From 7ea64f857b5f76cd06e01bfe49eda27c2d2da335 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 16 Dec 2010 17:01:36 +0000 Subject: bumped version in prep for release --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index ea4ab45..88ffe6d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,10 @@ -AC_INIT(indicator-sound, 0.5.2, conor.curran@canonical.com) +AC_INIT(indicator-sound, 0.5.3, conor.curran@canonical.com) AC_PREREQ(2.53) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(indicator-sound, 0.5.2) +AM_INIT_AUTOMAKE(indicator-sound, 0.5.3) AM_MAINTAINER_MODE -- cgit v1.2.3