From ee2ba9c677721724c8385ff2c9f32f7a9f090f0d Mon Sep 17 00:00:00 2001 From: Xavi Garcia Mena Date: Fri, 22 Jan 2016 14:10:07 -0600 Subject: Code for Bug 1213907 added. Only showing active players playback controls --- src/service.vala | 2 +- src/sound-menu.vala | 92 ++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 68 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/service.vala b/src/service.vala index 29b8670..2228ba2 100644 --- a/src/service.vala +++ b/src/service.vala @@ -94,7 +94,7 @@ public class IndicatorSound.Service: Object { this.menus = new HashTable (str_hash, str_equal); this.menus.insert ("desktop_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.SHOW_MUTE | SoundMenu.DisplayFlags.HIDE_PLAYERS | SoundMenu.DisplayFlags.GREETER_PLAYERS)); this.menus.insert ("phone_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.SHOW_SILENT_MODE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS | SoundMenu.DisplayFlags.GREETER_PLAYERS)); - this.menus.insert ("desktop", new SoundMenu ("indicator.desktop-settings", SoundMenu.DisplayFlags.SHOW_MUTE)); + this.menus.insert ("desktop", new SoundMenu ("indicator.desktop-settings", SoundMenu.DisplayFlags.SHOW_MUTE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS_PLAY_CONTROLS)); this.menus.insert ("phone", new SoundMenu ("indicator.phone-settings", SoundMenu.DisplayFlags.SHOW_SILENT_MODE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS)); this.menus.@foreach ( (profile, menu) => { diff --git a/src/sound-menu.vala b/src/sound-menu.vala index bdb8df2..fde1a6c 100644 --- a/src/sound-menu.vala +++ b/src/sound-menu.vala @@ -25,9 +25,18 @@ public class SoundMenu: Object HIDE_INACTIVE_PLAYERS = 2, HIDE_PLAYERS = 4, GREETER_PLAYERS = 8, - SHOW_SILENT_MODE = 16 + SHOW_SILENT_MODE = 16, + HIDE_INACTIVE_PLAYERS_PLAY_CONTROLS = 32 } + public enum PlayerSectionPosistion { + LABEL = 0, + PLAYER_CONTROLS = 1, + PLAYLIST = 2 + } + + const string PLAYBACK_ITEM_TYPE = "com.canonical.unity.playback-item"; + public SoundMenu (string? settings_action, DisplayFlags flags) { /* A sound menu always has at least two sections: the volume section (this.volume_section) * at the start of the menu, and the settings section at the end. Between those two, @@ -68,6 +77,7 @@ public class SoundMenu: Object this.hide_players = (flags & DisplayFlags.HIDE_PLAYERS) != 0; this.hide_inactive = (flags & DisplayFlags.HIDE_INACTIVE_PLAYERS) != 0; + this.hide_inactive_player_controls = (flags & DisplayFlags.HIDE_INACTIVE_PLAYERS_PLAY_CONTROLS) != 0; this.notify_handlers = new HashTable (direct_hash, direct_equal); this.greeter_players = (flags & DisplayFlags.GREETER_PLAYERS) != 0; @@ -148,6 +158,15 @@ public class SoundMenu: Object return -1; } + public void update_all_players_play_section() { + foreach (var player_stored in notify_handlers.get_keys ()) { + int index = this.find_player_section(player_stored); + if (index != -1) { + // just update to verify if we must hide the player controls + update_player_section (player_stored, index); + } + } + } public void add_player (MediaPlayer player) { if (this.notify_handlers.contains (player)) @@ -158,21 +177,32 @@ public class SoundMenu: Object this.update_playlists (player); var handler_id = player.notify["is-running"].connect ( () => { + int index = this.find_player_section(player); if (player.is_running) { - int index = this.find_player_section(player); if (index == -1) { this.insert_player_section (player); } else { update_player_section (player, index); } + number_of_running_players++; } else { + number_of_running_players--; if (this.hide_inactive) this.remove_player_section (player); + else { + if (index != -1) { + // just update to verify if we must hide the player controls + update_player_section (player, index); + } + } } - this.update_playlists (player); + + // we need to update the rest of players, because we might have + // a non running player still showing the playback controls + update_all_players_play_section(); }); this.notify_handlers.insert (player, handler_id); @@ -239,8 +269,10 @@ public class SoundMenu: Object bool high_volume_warning_shown = false; bool hide_inactive; bool hide_players = false; + bool hide_inactive_player_controls = false; HashTable notify_handlers; bool greeter_players = false; + int number_of_running_players = 0; /* returns the position in this.menu of the section that's associated with @player */ int find_player_section (MediaPlayer player) { @@ -261,9 +293,24 @@ public class SoundMenu: Object return -1; } + int find_player_playback_controls_section (Menu player_menu) { + int n = player_menu.get_n_items (); + for (int i = 0; i < n; i++) { + string type; + player_menu.get_item_attribute (i, "x-canonical-type", "s", out type); + if (type == PLAYBACK_ITEM_TYPE) + return i; + } + + return -1; + } + MenuItem create_playback_menu_item (MediaPlayer player) { var playback_item = new MenuItem (null, null); playback_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.playback-item"); + playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id + ".disabled"); + playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id + ".disabled"); + playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id + ".disabled"); if (player.is_running) { if (player.can_do_play) { playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id); @@ -301,24 +348,10 @@ public class SoundMenu: Object player_item.set_attribute_value ("icon", icon.serialize ()); section.append_item (player_item); - var playback_item = new MenuItem (null, null); - playback_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.playback-item"); - playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id + ".disabled"); - playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id + ".disabled"); - playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id + ".disabled"); - - if (player.is_running) { - if (player.can_do_play) { - playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id); - } - if (player.can_do_next) { - playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id); - } - if (player.can_do_prev) { - playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id); - } + var playback_item = create_playback_menu_item (player); + if (player.is_running|| !this.hide_inactive_player_controls) { + section.insert_item (PlayerSectionPosistion.PLAYER_CONTROLS, playback_item); } - section.append_item (playback_item); /* Add new players to the end of the player sections, just before the settings */ if (settings_shown) { @@ -339,12 +372,21 @@ public class SoundMenu: Object void update_player_section (MediaPlayer player, int index) { var player_section = this.menu.get_item_link(index, Menu.LINK_SECTION) as Menu; - if (player_section.get_n_items () == 2) { - // we have 2 items, the second one is the playback item - // remove it first - player_section.remove (1); + + int play_control_index = find_player_playback_controls_section (player_section); + if (player.is_running || !this.hide_inactive_player_controls) { MenuItem playback_item = create_playback_menu_item (player); - player_section.append_item (playback_item); + if (play_control_index != -1) { + player_section.remove (PlayerSectionPosistion.PLAYER_CONTROLS); + } + player_section.insert_item (PlayerSectionPosistion.PLAYER_CONTROLS, playback_item); + } else { + if (play_control_index != -1 && number_of_running_players >= 1) { + warning("REMOVING SECTION number of running players: %d", number_of_running_players); + // remove both, playlist and play controls + player_section.remove (PlayerSectionPosistion.PLAYLIST); + player_section.remove (PlayerSectionPosistion.PLAYER_CONTROLS); + } } } -- cgit v1.2.3 From 12715ce7e03fec9544d7261c87aa9ddaa39b75ad Mon Sep 17 00:00:00 2001 From: Xavi Garcia Mena Date: Fri, 29 Jan 2016 12:16:34 +0100 Subject: added integration tests for adding/removing players and playback controls --- src/sound-menu.vala | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/sound-menu.vala b/src/sound-menu.vala index fde1a6c..d100be1 100644 --- a/src/sound-menu.vala +++ b/src/sound-menu.vala @@ -308,9 +308,6 @@ public class SoundMenu: Object MenuItem create_playback_menu_item (MediaPlayer player) { var playback_item = new MenuItem (null, null); playback_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.playback-item"); - playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id + ".disabled"); - playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id + ".disabled"); - playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id + ".disabled"); if (player.is_running) { if (player.can_do_play) { playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id); -- cgit v1.2.3 From 028e56ca8e6fa0c45f163d2ec0923053f71deb33 Mon Sep 17 00:00:00 2001 From: Xavi Garcia Mena Date: Thu, 4 Feb 2016 14:49:30 +0100 Subject: Added Charles suggestions --- src/sound-menu.vala | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/sound-menu.vala b/src/sound-menu.vala index 896b7d2..669e83d 100644 --- a/src/sound-menu.vala +++ b/src/sound-menu.vala @@ -29,7 +29,7 @@ public class SoundMenu: Object HIDE_INACTIVE_PLAYERS_PLAY_CONTROLS = 32 } - public enum PlayerSectionPosistion { + public enum PlayerSectionPosition { LABEL = 0, PLAYER_CONTROLS = 1, PLAYLIST = 2 @@ -182,21 +182,12 @@ public class SoundMenu: Object if (index == -1) { this.insert_player_section (player); } - else { - update_player_section (player, index); - } number_of_running_players++; } else { number_of_running_players--; if (this.hide_inactive) this.remove_player_section (player); - else { - if (index != -1) { - // just update to verify if we must hide the player controls - update_player_section (player, index); - } - } } this.update_playlists (player); @@ -307,7 +298,7 @@ public class SoundMenu: Object MenuItem create_playback_menu_item (MediaPlayer player) { var playback_item = new MenuItem (null, null); - playback_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.playback-item"); + playback_item.set_attribute ("x-canonical-type", "s", PLAYBACK_ITEM_TYPE); if (player.is_running) { if (player.can_do_play) { playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id); @@ -345,9 +336,9 @@ public class SoundMenu: Object player_item.set_attribute_value ("icon", icon.serialize ()); section.append_item (player_item); - var playback_item = create_playback_menu_item (player); if (player.is_running|| !this.hide_inactive_player_controls) { - section.insert_item (PlayerSectionPosistion.PLAYER_CONTROLS, playback_item); + var playback_item = create_playback_menu_item (player); + section.insert_item (PlayerSectionPosition.PLAYER_CONTROLS, playback_item); } /* Add new players to the end of the player sections, just before the settings */ @@ -374,14 +365,14 @@ public class SoundMenu: Object if (player.is_running || !this.hide_inactive_player_controls) { MenuItem playback_item = create_playback_menu_item (player); if (play_control_index != -1) { - player_section.remove (PlayerSectionPosistion.PLAYER_CONTROLS); + player_section.remove (PlayerSectionPosition.PLAYER_CONTROLS); } - player_section.insert_item (PlayerSectionPosistion.PLAYER_CONTROLS, playback_item); + player_section.insert_item (PlayerSectionPosition.PLAYER_CONTROLS, playback_item); } else { if (play_control_index != -1 && number_of_running_players >= 1) { // remove both, playlist and play controls - player_section.remove (PlayerSectionPosistion.PLAYLIST); - player_section.remove (PlayerSectionPosistion.PLAYER_CONTROLS); + player_section.remove (PlayerSectionPosition.PLAYLIST); + player_section.remove (PlayerSectionPosition.PLAYER_CONTROLS); } } } -- cgit v1.2.3 From f1bdb863aea00a03acf9501432e2baa70dd9ee8b Mon Sep 17 00:00:00 2001 From: Xavi Garcia Mena Date: Wed, 10 Feb 2016 14:08:49 +0100 Subject: Added persistence for last running player --- src/service.vala | 15 +++++++++++---- src/sound-menu.vala | 23 ++++++++++++++++++++--- 2 files changed, 31 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/service.vala b/src/service.vala index 2228ba2..cb30820 100644 --- a/src/service.vala +++ b/src/service.vala @@ -91,11 +91,12 @@ public class IndicatorSound.Service: Object { this.actions.add_action (this.create_high_volume_action ()); this.actions.add_action (this.create_volume_sync_action ()); + string last_player = this.settings.get_string ("last-running-player"); this.menus = new HashTable (str_hash, str_equal); - this.menus.insert ("desktop_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.SHOW_MUTE | SoundMenu.DisplayFlags.HIDE_PLAYERS | SoundMenu.DisplayFlags.GREETER_PLAYERS)); - this.menus.insert ("phone_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.SHOW_SILENT_MODE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS | SoundMenu.DisplayFlags.GREETER_PLAYERS)); - this.menus.insert ("desktop", new SoundMenu ("indicator.desktop-settings", SoundMenu.DisplayFlags.SHOW_MUTE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS_PLAY_CONTROLS)); - this.menus.insert ("phone", new SoundMenu ("indicator.phone-settings", SoundMenu.DisplayFlags.SHOW_SILENT_MODE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS)); + this.menus.insert ("desktop_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.SHOW_MUTE | SoundMenu.DisplayFlags.HIDE_PLAYERS | SoundMenu.DisplayFlags.GREETER_PLAYERS, last_player)); + this.menus.insert ("phone_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.SHOW_SILENT_MODE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS | SoundMenu.DisplayFlags.GREETER_PLAYERS, last_player)); + this.menus.insert ("desktop", new SoundMenu ("indicator.desktop-settings", SoundMenu.DisplayFlags.SHOW_MUTE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS_PLAY_CONTROLS | SoundMenu.DisplayFlags.ADD_PLAY_CONTROL_INACTIVE_PLAYER, last_player)); + this.menus.insert ("phone", new SoundMenu ("indicator.phone-settings", SoundMenu.DisplayFlags.SHOW_SILENT_MODE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS, last_player)); this.menus.@foreach ( (profile, menu) => { this.volume_control.bind_property ("active-mic", menu, "show-mic-volume", BindingFlags.SYNC_CREATE); @@ -109,6 +110,12 @@ public class IndicatorSound.Service: Object { this.volume_control.active_output_changed.connect (menu.update_volume_slider); }); + this.menus.@foreach ( (profile, menu) => { + menu.last_player_updated.connect ((player_id) => { + this.settings.set_value ("last-running-player", player_id); + }); + }); + this.sync_preferred_players (); this.settings.changed["interested-media-players"].connect ( () => { this.sync_preferred_players (); diff --git a/src/sound-menu.vala b/src/sound-menu.vala index 669e83d..630dca0 100644 --- a/src/sound-menu.vala +++ b/src/sound-menu.vala @@ -26,7 +26,8 @@ public class SoundMenu: Object HIDE_PLAYERS = 4, GREETER_PLAYERS = 8, SHOW_SILENT_MODE = 16, - HIDE_INACTIVE_PLAYERS_PLAY_CONTROLS = 32 + HIDE_INACTIVE_PLAYERS_PLAY_CONTROLS = 32, + ADD_PLAY_CONTROL_INACTIVE_PLAYER = 64 } public enum PlayerSectionPosition { @@ -37,7 +38,7 @@ public class SoundMenu: Object const string PLAYBACK_ITEM_TYPE = "com.canonical.unity.playback-item"; - public SoundMenu (string? settings_action, DisplayFlags flags) { + public SoundMenu (string? settings_action, DisplayFlags flags, string default_player_id) { /* A sound menu always has at least two sections: the volume section (this.volume_section) * at the start of the menu, and the settings section at the end. Between those two, * it has a dynamic amount of player sections, one for each registered player. @@ -78,10 +79,13 @@ public class SoundMenu: Object this.hide_players = (flags & DisplayFlags.HIDE_PLAYERS) != 0; this.hide_inactive = (flags & DisplayFlags.HIDE_INACTIVE_PLAYERS) != 0; this.hide_inactive_player_controls = (flags & DisplayFlags.HIDE_INACTIVE_PLAYERS_PLAY_CONTROLS) != 0; + this.add_play_button_inactive_player = (flags & DisplayFlags.ADD_PLAY_CONTROL_INACTIVE_PLAYER) != 0; this.notify_handlers = new HashTable (direct_hash, direct_equal); this.greeter_players = (flags & DisplayFlags.GREETER_PLAYERS) != 0; + this.default_player = default_player_id; + } ~SoundMenu () { @@ -261,9 +265,11 @@ public class SoundMenu: Object bool hide_inactive; bool hide_players = false; bool hide_inactive_player_controls = false; + bool add_play_button_inactive_player = false; HashTable notify_handlers; bool greeter_players = false; int number_of_running_players = 0; + string default_player = ""; /* returns the position in this.menu of the section that's associated with @player */ int find_player_section (MediaPlayer player) { @@ -309,6 +315,10 @@ public class SoundMenu: Object if (player.can_do_prev) { playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id); } + } else { + if (this.add_play_button_inactive_player) { + playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id); + } } return playback_item; } @@ -336,7 +346,7 @@ public class SoundMenu: Object player_item.set_attribute_value ("icon", icon.serialize ()); section.append_item (player_item); - if (player.is_running|| !this.hide_inactive_player_controls) { + if (player.is_running|| !this.hide_inactive_player_controls || player.id == this.default_player) { var playback_item = create_playback_menu_item (player); section.insert_item (PlayerSectionPosition.PLAYER_CONTROLS, playback_item); } @@ -362,6 +372,11 @@ public class SoundMenu: Object var player_section = this.menu.get_item_link(index, Menu.LINK_SECTION) as Menu; int play_control_index = find_player_playback_controls_section (player_section); + if (player.is_running && number_of_running_players == 1) { + // this is the first or the last player running... + // store its id + this.last_player_updated (player.id); + } if (player.is_running || !this.hide_inactive_player_controls) { MenuItem playback_item = create_playback_menu_item (player); if (play_control_index != -1) { @@ -432,4 +447,6 @@ public class SoundMenu: Object return slider; } + + public signal void last_player_updated (string player_id); } -- cgit v1.2.3