Add hadling for audio output devices (close #35)

This commit is contained in:
coderkun 2017-12-25 13:16:56 +01:00
parent 30175ee86a
commit 7a28e9f4bf
3 changed files with 155 additions and 0 deletions

View file

@ -905,6 +905,50 @@
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
<child type="center">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
<child type="center">
<object class="GtkListBox" id="server-output-devices">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
<style>
<class name="no-bg"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">page2</property>
<property name="title" translatable="yes">Audio Devices</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>

View file

@ -114,6 +114,8 @@ class Client(Base):
SIGNAL_LOAD_ALBUMS = 'load-albums'
# Signal: load playlist
SIGNAL_LOAD_PLAYLIST = 'load-playlist'
# Signal: load audio output devices
SIGNAL_LOAD_OUTPUT_DEVICES = 'load-output-devices'
# Signal: error
SIGNAL_ERROR = 'error'
@ -182,6 +184,19 @@ class Client(Base):
self._add_action(self._get_stats)
def get_output_devices(self):
"""Determine the list of audio output devices."""
self._logger.info("get output devices")
self._add_action(self._get_output_devices)
def enable_output_device(self, device, enabled):
"""Enable/disable an audio output device."""
self._logger.info("enable output device")
self._add_action(self._enable_output_device, device, enabled)
def load_albums(self):
self._logger.info("load albums")
self._add_action(self._load_albums)
@ -351,6 +366,9 @@ class Client(Base):
self.load_albums()
self.load_playlist()
self.get_status()
if subsystems['changed'] == 'output':
self.get_output_devices()
self.get_status()
def _noidle(self):
@ -447,6 +465,24 @@ class Client(Base):
self._callback(Client.SIGNAL_STATS, artists, albums, songs, dbplaytime, playtime, uptime)
def _get_output_devices(self):
"""Action: Perform the real loading of output devices."""
devices = []
for output in self._parse_list(self._call('outputs'), ['outputid']):
device = OutputDevice(output['outputid'], output['outputname'])
device.set_enabled(int(output['outputenabled']) == 1)
devices.append(device)
self._callback(Client.SIGNAL_LOAD_OUTPUT_DEVICES, devices)
def _enable_output_device(self, device, enabled):
"""Action: Perform the real enabling/disabling of an output device."""
if enabled:
self._call('enableoutput ', device.get_id())
else:
self._call('disableoutput ', device.get_id())
def _load_albums(self):
"""Action: Perform the real update."""
self._albums = {}
@ -737,6 +773,33 @@ class Client(Base):
class OutputDevice:
def __init__(self, id, name):
self._id = id
self._name = name
self._enabled = None
def get_id(self):
return self._id
def get_name(self):
return self._name
def set_enabled(self, enabled):
self._enabled = enabled
def is_enabled(self):
return self._enabled
class MCGAlbum:
DEFAULT_ALBUM = 'Various'
_FILE_NAMES = ['cover', 'folder']

View file

@ -145,6 +145,7 @@ class Window():
self._header_bar.connect('toolbar-playpause', self.on_header_bar_playpause)
self._header_bar.connect('toolbar-set-volume', self.on_header_bar_set_volume)
self._connection_panel.connect('connection-changed', self.on_connection_panel_connection_changed)
self._panels[Window._PANEL_INDEX_SERVER].connect('change-output-device', self.on_server_panel_output_device_changed)
self._panels[Window._PANEL_INDEX_COVER].connect('toggle-fullscreen', self.on_cover_panel_toggle_fullscreen)
self._panels[Window._PANEL_INDEX_COVER].connect('tracklist-size-changed', self.on_cover_panel_tracklist_size_changed)
self._panels[Window._PANEL_INDEX_COVER].connect('set-song', self.on_cover_panel_set_song)
@ -161,6 +162,7 @@ class Window():
self._mcg.connect_signal(client.Client.SIGNAL_CONNECTION, self.on_mcg_connect)
self._mcg.connect_signal(client.Client.SIGNAL_STATUS, self.on_mcg_status)
self._mcg.connect_signal(client.Client.SIGNAL_STATS, self.on_mcg_stats)
self._mcg.connect_signal(client.Client.SIGNAL_LOAD_OUTPUT_DEVICES, self.on_mcg_load_output_devices)
self._mcg.connect_signal(client.Client.SIGNAL_LOAD_PLAYLIST, self.on_mcg_load_playlist)
self._mcg.connect_signal(client.Client.SIGNAL_LOAD_ALBUMS, self.on_mcg_load_albums)
self._mcg.connect_signal(client.Client.SIGNAL_ERROR, self.on_mcg_error)
@ -302,6 +304,10 @@ class Window():
self._mcg.play_album_from_playlist(album)
def on_server_panel_output_device_changed(self, widget, device, enabled):
self._mcg.enable_output_device(device, enabled)
def on_cover_panel_toggle_fullscreen(self, widget):
if not self._fullscreened:
self._appwindow.fullscreen()
@ -351,6 +357,7 @@ class Window():
self._mcg.load_albums()
self._mcg.get_status()
self._mcg.get_stats()
self._mcg.get_output_devices()
self._connect_action.set_state(GLib.Variant.new_boolean(True))
self._play_action.set_enabled(True)
self._clear_playlist_action.set_enabled(True)
@ -390,6 +397,10 @@ class Window():
self._panels[Window._PANEL_INDEX_SERVER].set_stats(artists, albums, songs, dbplaytime, playtime, uptime)
def on_mcg_load_output_devices(self, devices):
self._panels[Window._PANEL_INDEX_SERVER].set_output_devices(devices)
def on_mcg_load_playlist(self, playlist):
self._panels[self._PANEL_INDEX_PLAYLIST].set_playlist(self._connection_panel.get_host(), playlist)
@ -800,10 +811,14 @@ class ConnectionPanel(GObject.GObject):
class ServerPanel(GObject.GObject):
__gsignals__ = {
'change-output-device': (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,bool,)),
}
def __init__(self, builder):
GObject.GObject.__init__(self)
self._output_buttons = {}
# Widgets
self._panel = builder.get_object('server-panel')
@ -824,6 +839,9 @@ class ServerPanel(GObject.GObject):
self._stats_playtime = builder.get_object('server-stats-playtime')
self._stats_uptime = builder.get_object('server-stats-uptime')
# Audio ouptut devices widgets
self._output_devices = builder.get_object('server-output-devices')
def get(self):
return self._panel
@ -833,6 +851,10 @@ class ServerPanel(GObject.GObject):
return self._toolbar
def on_output_device_toggled(self, widget, device):
self.emit('change-output-device', device, widget.get_active())
def set_status(self, file, audio, bitrate, error):
if not file:
file = ""
@ -866,6 +888,32 @@ class ServerPanel(GObject.GObject):
self._stats_uptime.set_text(str(uptime))
def set_output_devices(self, devices):
device_ids = []
# Add devices
for device in devices:
device_ids.append(device.get_id())
if device.get_id() in self._output_buttons.keys():
self._output_buttons[device.get_id()].freeze_notify()
self._output_buttons[device.get_id()].set_active(device.is_enabled())
self._output_buttons[device.get_id()].thaw_notify()
else:
button = Gtk.CheckButton(device.get_name())
if device.is_enabled():
button.set_active(True)
handler = button.connect('toggled', self.on_output_device_toggled, device)
self._output_devices.insert(button, -1)
self._output_buttons[device.get_id()] = button
self._output_devices.show_all()
# Remove devices
for id in self._output_buttons.keys():
if id not in device_ids:
self._output_devices.remove(self._output_buttons[id].get_parent())
class CoverPanel(GObject.GObject):