Add hadling for audio output devices (close #35)
This commit is contained in:
parent
30175ee86a
commit
7a28e9f4bf
3 changed files with 155 additions and 0 deletions
|
@ -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>
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in a new issue