#!/usr/bin/env python3 import gi gi.require_version('Gtk', '4.0') gi.require_version('Adw', '1') import locale from gi.repository import Gtk, Adw, GObject from mcg.zeroconf import ZeroconfProvider @Gtk.Template(resource_path='/xyz/suruatoel/mcg/ui/server-panel.ui') class ServerPanel(Adw.Bin): __gtype_name__ = 'McgServerPanel' __gsignals__ = { 'connection-changed': (GObject.SIGNAL_RUN_FIRST, None, (str, int, str)), 'change-output-device': (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,bool,)), } # Widgets toolbar = Gtk.Template.Child() connection_status_page = Gtk.Template.Child() status_page = Gtk.Template.Child() stats_page = Gtk.Template.Child() devices_page = Gtk.Template.Child() # Connection widgets zeroconf_list = Gtk.Template.Child() host_row = Gtk.Template.Child() port_spinner = Gtk.Template.Child() password_row = Gtk.Template.Child() # Status widgets status_file = Gtk.Template.Child() status_audio = Gtk.Template.Child() status_bitrate = Gtk.Template.Child() status_error = Gtk.Template.Child() # Stats widgets stats_artists = Gtk.Template.Child() stats_albums = Gtk.Template.Child() stats_songs = Gtk.Template.Child() stats_dbplaytime = Gtk.Template.Child() stats_playtime = Gtk.Template.Child() stats_uptime = Gtk.Template.Child() # Audio ouptut devices widgets output_devices = Gtk.Template.Child() def __init__(self, **kwargs): super().__init__(**kwargs) self._none_label = "" self._output_buttons = {} self._is_selected = False # Widgets self._none_label = self.status_file.get_label() # Zeroconf provider self._zeroconf_provider = ZeroconfProvider() self._zeroconf_provider.connect_signal(ZeroconfProvider.SIGNAL_SERVICE_NEW, self.on_new_service) def set_selected(self, selected): self._is_selected = selected def get_toolbar(self): return self.toolbar def on_new_service(self, service): name, host, port = service row_button = Gtk.Button() row_button.set_label(locale.gettext("use")) row_button.connect("clicked", self.on_service_selected, host, port) row = Adw.ActionRow() row.set_title(name) row.set_subtitle("{} ({})".format(host, port)) row.add_suffix(row_button) self.zeroconf_list.insert(row, -1) def on_service_selected(self, widget, host, port): self.set_host(host) self.set_port(port) @Gtk.Template.Callback() def on_host_entry_apply(self, widget): self._call_back() @Gtk.Template.Callback() def on_port_spinner_value_changed(self, widget): self._call_back() def set_connection_sensitive(self, sensitive): self.connection_status_page.set_sensitive(sensitive) self.status_page.set_visible(not sensitive) self.stats_page.set_visible(not sensitive) self.devices_page.set_visible(not sensitive) def set_host(self, host): self.host_row.set_text(host) def get_host(self): return self.host_row.get_text() def set_port(self, port): self.port_spinner.set_value(port) def get_port(self): return self.port_spinner.get_value_as_int() def set_password(self, password): if password is None: password = "" self.password_row.set_text(password) def get_password(self): if self.password_row.get_text() == "": return None else: return self.password_entry.get_text() 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 file: file = GObject.markup_escape_text(file) else: file = self._none_label self.status_file.set_markup(file) # Audio information if audio: parts = audio.split(":") if len(parts) == 3: audio = "{} Hz, {} bit, {} channels".format(parts[0], parts[1], parts[2]) else: audio = self._none_label self.status_audio.set_markup(audio) # Bitrate if bitrate: bitrate = bitrate + " kb/s" else: bitrate = self._none_label self.status_bitrate.set_markup(bitrate) # Error if error: error = GObject.markup_escape_text(error) else: error = self._none_label self.status_error.set_markup(error) def set_stats(self, artists, albums, songs, dbplaytime, playtime, uptime): self.stats_artists.set_text(str(artists)) self.stats_albums.set_text(str(albums)) self.stats_songs.set_text(str(songs)) self.stats_dbplaytime.set_text(str(dbplaytime)) self.stats_playtime.set_text(str(playtime)) 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.new_with_label(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 # 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()) def _call_back(self): self.emit('connection-changed', self.get_host(), self.get_port(), self.get_password(),)