Use GTK Composite Templates (close #62)
Use GTK Composite Templates for GUI elements to clean up and simplify the code for widgets and all UI elements. This includes splitting the large “gtk.glade” file into smaller .ui files and the large “widgets.py” file into smaller .py files.
This commit is contained in:
parent
f4b545369c
commit
ba373ddf4e
31 changed files with 4431 additions and 4300 deletions
650
mcg/window.py
Normal file
650
mcg/window.py
Normal file
|
|
@ -0,0 +1,650 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
try:
|
||||
import keyring
|
||||
use_keyring = True
|
||||
except:
|
||||
use_keyring = False
|
||||
import logging
|
||||
|
||||
from gi.repository import Gtk, Gdk, GObject, GLib, Gio
|
||||
|
||||
from mcg import client
|
||||
from mcg.shortcutsdialog import ShortcutsDialog
|
||||
from mcg.connectionpanel import ConnectionPanel
|
||||
from mcg.serverpanel import ServerPanel
|
||||
from mcg.coverpanel import CoverPanel
|
||||
from mcg.playlistpanel import PlaylistPanel
|
||||
from mcg.librarypanel import LibraryPanel
|
||||
from mcg.zeroconf import ZeroconfProvider
|
||||
|
||||
|
||||
|
||||
|
||||
class WindowState(GObject.Object):
|
||||
WIDTH = 'width'
|
||||
HEIGHT = 'height'
|
||||
IS_MAXIMIZED = 'is_maximized'
|
||||
IS_FULLSCREENED = 'is_fullscreened'
|
||||
width = GObject.Property(type=int, default=800)
|
||||
height = GObject.Property(type=int, default=600)
|
||||
is_maximized = GObject.Property(type=bool, default=False)
|
||||
is_fullscreened = GObject.Property(type=bool, default=False)
|
||||
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
|
||||
|
||||
|
||||
@Gtk.Template(resource_path='/de/coderkun/mcg/ui/window.ui')
|
||||
class Window(Gtk.ApplicationWindow):
|
||||
__gtype_name__ = 'McgAppWindow'
|
||||
SETTING_HOST = 'host'
|
||||
SETTING_PORT = 'port'
|
||||
SETTING_CONNECTED = 'connected'
|
||||
SETTING_WINDOW_WIDTH = 'width'
|
||||
SETTING_WINDOW_HEIGHT = 'height'
|
||||
SETTING_WINDOW_MAXIMIZED = 'is-maximized'
|
||||
SETTING_PANEL = 'panel'
|
||||
SETTING_ITEM_SIZE = 'item-size'
|
||||
SETTING_SORT_ORDER = 'sort-order'
|
||||
SETTING_SORT_TYPE = 'sort-type'
|
||||
_CUSTOM_STARTUP_COMPLETE = 'startup-complete'
|
||||
|
||||
# Widgets
|
||||
content_stack = Gtk.Template.Child()
|
||||
panel_stack = Gtk.Template.Child()
|
||||
toolbar_stack = Gtk.Template.Child()
|
||||
# Headerbar
|
||||
headerbar = Gtk.Template.Child()
|
||||
headerbar_title_stack = Gtk.Template.Child()
|
||||
headerbar_panel_switcher = Gtk.Template.Child()
|
||||
headerbar_connection_label = Gtk.Template.Child()
|
||||
headerbar_button_connect = Gtk.Template.Child()
|
||||
headerbar_button_playpause = Gtk.Template.Child()
|
||||
headerbar_button_volume = Gtk.Template.Child()
|
||||
# Infobar
|
||||
info_revealer = Gtk.Template.Child()
|
||||
info_bar = Gtk.Template.Child()
|
||||
info_label = Gtk.Template.Child()
|
||||
|
||||
|
||||
def __init__(self, app, title, settings):
|
||||
super().__init__()
|
||||
self.set_application(app)
|
||||
self.set_title(title)
|
||||
self._settings = settings
|
||||
self._panels = []
|
||||
self._mcg = client.Client()
|
||||
self._state = WindowState()
|
||||
self._changing_volume = False
|
||||
self._setting_volume = False
|
||||
|
||||
# Help/Shortcuts dialog
|
||||
self.set_help_overlay(ShortcutsDialog())
|
||||
|
||||
# Login screen
|
||||
self._connection_panel = ConnectionPanel()
|
||||
# Server panel
|
||||
self._server_panel = ServerPanel()
|
||||
self._panels.append(self._server_panel)
|
||||
# Cover panel
|
||||
self._cover_panel = CoverPanel()
|
||||
self._panels.append(self._cover_panel)
|
||||
# Playlist panel
|
||||
self._playlist_panel = PlaylistPanel(self._mcg)
|
||||
self._playlist_panel.connect('open-standalone', self.on_panel_open_standalone)
|
||||
self._playlist_panel.connect('close-standalone', self.on_panel_close_standalone)
|
||||
self._panels.append(self._playlist_panel)
|
||||
# Library panel
|
||||
self._library_panel = LibraryPanel(self._mcg)
|
||||
self._library_panel.connect('open-standalone', self.on_panel_open_standalone)
|
||||
self._library_panel.connect('close-standalone', self.on_panel_close_standalone)
|
||||
self._panels.append(self._library_panel)
|
||||
# Stack
|
||||
self.content_stack.add(self._connection_panel)
|
||||
self.panel_stack.add_titled(self._server_panel, 'server-panel', "Server")
|
||||
self.panel_stack.add_titled(self._cover_panel, 'cover-panel', "Cover")
|
||||
self.panel_stack.add_titled(self._playlist_panel, 'playlist-panel', "Playlist")
|
||||
self.panel_stack.add_titled(self._library_panel, 'library-panel', "Library")
|
||||
# Header
|
||||
self._playlist_panel.get_headerbar_standalone().connect('close', self.on_panel_close_standalone)
|
||||
self._library_panel.get_headerbar_standalone().connect('close', self.on_panel_close_standalone)
|
||||
# Toolbar stack
|
||||
self.toolbar_stack.add(self._server_panel.get_toolbar())
|
||||
self.toolbar_stack.add(self._cover_panel.get_toolbar())
|
||||
self.toolbar_stack.add(self._playlist_panel.get_toolbar())
|
||||
self.toolbar_stack.add(self._library_panel.get_toolbar())
|
||||
|
||||
# Properties
|
||||
self._set_headerbar_sensitive(False, False)
|
||||
self._connection_panel.set_host(self._settings.get_string(Window.SETTING_HOST))
|
||||
self._connection_panel.set_port(self._settings.get_int(Window.SETTING_PORT))
|
||||
if use_keyring:
|
||||
self._connection_panel.set_password(keyring.get_password(ZeroconfProvider.KEYRING_SYSTEM, ZeroconfProvider.KEYRING_USERNAME))
|
||||
self._playlist_panel.set_item_size(self._settings.get_int(Window.SETTING_ITEM_SIZE))
|
||||
self._library_panel.set_item_size(self._settings.get_int(Window.SETTING_ITEM_SIZE))
|
||||
self._library_panel.set_sort_order(self._settings.get_enum(Window.SETTING_SORT_ORDER))
|
||||
self._library_panel.set_sort_type(self._settings.get_boolean(Window.SETTING_SORT_TYPE))
|
||||
|
||||
# Signals
|
||||
self._connection_panel.connect('connection-changed', self.on_connection_panel_connection_changed)
|
||||
self.panel_stack.connect('notify::visible-child', self.on_stack_switched)
|
||||
self._server_panel.connect('change-output-device', self.on_server_panel_output_device_changed)
|
||||
self._cover_panel.connect('toggle-fullscreen', self.on_cover_panel_toggle_fullscreen)
|
||||
self._cover_panel.connect('set-song', self.on_cover_panel_set_song)
|
||||
self._cover_panel.connect('albumart', self.on_cover_panel_albumart)
|
||||
self._playlist_panel.connect('clear-playlist', self.on_playlist_panel_clear_playlist)
|
||||
self._playlist_panel.connect('remove-album', self.on_playlist_panel_remove)
|
||||
self._playlist_panel.connect('remove-multiple-albums', self.on_playlist_panel_remove_multiple)
|
||||
self._playlist_panel.connect('play', self.on_playlist_panel_play)
|
||||
self._playlist_panel.connect('albumart', self.on_playlist_panel_albumart)
|
||||
self._library_panel.connect('update', self.on_library_panel_update)
|
||||
self._library_panel.connect('play', self.on_library_panel_play)
|
||||
self._library_panel.connect('queue', self.on_library_panel_queue)
|
||||
self._library_panel.connect('queue-multiple', self.on_library_panel_queue_multiple)
|
||||
self._library_panel.connect('item-size-changed', self.on_library_panel_item_size_changed)
|
||||
self._library_panel.connect('sort-order-changed', self.on_library_panel_sort_order_changed)
|
||||
self._library_panel.connect('sort-type-changed', self.on_library_panel_sort_type_changed)
|
||||
self._library_panel.connect('albumart', self.on_library_panel_albumart)
|
||||
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_PULSE_ALBUMS, self.on_mcg_pulse_albums)
|
||||
self._mcg.connect_signal(client.Client.SIGNAL_INIT_ALBUMS, self.on_mcg_init_albums)
|
||||
self._mcg.connect_signal(client.Client.SIGNAL_LOAD_ALBUMS, self.on_mcg_load_albums)
|
||||
self._mcg.connect_signal(client.Client.SIGNAL_LOAD_ALBUMART, self.on_mcg_load_albumart)
|
||||
self._mcg.connect_signal(client.Client.SIGNAL_CUSTOM, self.on_mcg_custom)
|
||||
self._mcg.connect_signal(client.Client.SIGNAL_ERROR, self.on_mcg_error)
|
||||
self._settings.connect('changed::'+Window.SETTING_PANEL, self.on_settings_panel_changed)
|
||||
self._settings.connect('changed::'+Window.SETTING_ITEM_SIZE, self.on_settings_item_size_changed)
|
||||
self._settings.connect('changed::'+Window.SETTING_SORT_ORDER, self.on_settings_sort_order_changed)
|
||||
self._settings.connect('changed::'+Window.SETTING_SORT_TYPE, self.on_settings_sort_type_changed)
|
||||
self._settings.bind(Window.SETTING_WINDOW_WIDTH, self._state, WindowState.WIDTH, Gio.SettingsBindFlags.DEFAULT)
|
||||
self._settings.bind(Window.SETTING_WINDOW_HEIGHT, self._state, WindowState.HEIGHT, Gio.SettingsBindFlags.DEFAULT)
|
||||
self._settings.bind(Window.SETTING_WINDOW_MAXIMIZED, self._state, WindowState.IS_MAXIMIZED, Gio.SettingsBindFlags.DEFAULT)
|
||||
|
||||
# Actions
|
||||
self.set_default_size(self._state.width, self._state.height)
|
||||
if self._state.get_property(WindowState.IS_MAXIMIZED):
|
||||
self.maximize()
|
||||
self.show_all()
|
||||
self.content_stack.set_visible_child(self._connection_panel)
|
||||
if self._settings.get_boolean(Window.SETTING_CONNECTED):
|
||||
self._connect()
|
||||
|
||||
# Menu actions
|
||||
self._connect_action = Gio.SimpleAction.new_stateful("connect", None, GLib.Variant.new_boolean(False))
|
||||
self._connect_action.connect('change-state', self.on_menu_connect)
|
||||
self.add_action(self._connect_action)
|
||||
self._play_action = Gio.SimpleAction.new_stateful("play", None, GLib.Variant.new_boolean(False))
|
||||
self._play_action.set_enabled(False)
|
||||
self._play_action.connect('change-state', self.on_menu_play)
|
||||
self.add_action(self._play_action)
|
||||
self._clear_playlist_action = Gio.SimpleAction.new("clear-playlist", None)
|
||||
self._clear_playlist_action.set_enabled(False)
|
||||
self._clear_playlist_action.connect('activate', self.on_menu_clear_playlist)
|
||||
self.add_action(self._clear_playlist_action)
|
||||
panel_variant = GLib.Variant.new_string("0")
|
||||
self._panel_action = Gio.SimpleAction.new_stateful("panel", panel_variant.get_type(), panel_variant)
|
||||
self._panel_action.set_enabled(False)
|
||||
self._panel_action.connect('change-state', self.on_menu_panel)
|
||||
self.add_action(self._panel_action)
|
||||
self._toggle_fullscreen_action = Gio.SimpleAction.new("toggle-fullscreen", None)
|
||||
self._toggle_fullscreen_action.set_enabled(True)
|
||||
self._toggle_fullscreen_action.connect('activate', self.on_menu_toggle_fullscreen)
|
||||
self.add_action(self._toggle_fullscreen_action)
|
||||
|
||||
|
||||
# Menu callbacks
|
||||
|
||||
def on_menu_connect(self, action, value):
|
||||
self._connect()
|
||||
|
||||
|
||||
def on_menu_play(self, action, value):
|
||||
self._mcg.playpause()
|
||||
|
||||
|
||||
def on_menu_clear_playlist(self, action, value):
|
||||
self._mcg.clear_playlist()
|
||||
|
||||
|
||||
def on_menu_panel(self, action, value):
|
||||
action.set_state(value)
|
||||
self.panel_stack.set_visible_child(self._panels[int(value.get_string())])
|
||||
|
||||
|
||||
def on_menu_toggle_fullscreen(self, action, value):
|
||||
self.panel_stack.set_visible_child(self._cover_panel)
|
||||
if not self._state.get_property(WindowState.IS_FULLSCREENED):
|
||||
self.fullscreen()
|
||||
else:
|
||||
self.unfullscreen()
|
||||
|
||||
|
||||
# Window callbacks
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def on_resize(self, widget, event):
|
||||
if not self._state.get_property(WindowState.IS_MAXIMIZED):
|
||||
size = self.get_size()
|
||||
self._state.set_property(WindowState.WIDTH, size.width)
|
||||
self._state.set_property(WindowState.HEIGHT, size.height)
|
||||
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def on_state(self, widget, state):
|
||||
self._state.set_property(WindowState.IS_MAXIMIZED, (state.new_window_state & Gdk.WindowState.MAXIMIZED > 0))
|
||||
self._fullscreen((state.new_window_state & Gdk.WindowState.FULLSCREEN > 0))
|
||||
|
||||
|
||||
# HeaderBar callbacks
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def on_headerbar_connection_active_notify(self, widget, status):
|
||||
self._connect()
|
||||
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def on_headerbar_connection_state_set(self, widget, state):
|
||||
return True
|
||||
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def on_headerbar_volume_press(self, widget, active):
|
||||
self._changing_volume = active
|
||||
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def on_headerbar_volume_release(self, widget, active):
|
||||
self._changing_volume = active
|
||||
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def on_headerbar_playpause_toggled(self, widget):
|
||||
self._mcg.playpause()
|
||||
self._mcg.get_status()
|
||||
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def on_headerbar_volume_changed(self, widget, value):
|
||||
if not self._setting_volume:
|
||||
self._mcg.set_volume(int(value*100))
|
||||
|
||||
|
||||
# Infobar callback
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def on_info_bar_close(self, *args):
|
||||
self.info_revealer.set_reveal_child(False)
|
||||
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def on_info_bar_response(self, widget, response):
|
||||
self.info_revealer.set_reveal_child(False)
|
||||
|
||||
|
||||
|
||||
# Panel callbacks
|
||||
|
||||
def on_stack_switched(self, widget, prop):
|
||||
self._set_visible_toolbar()
|
||||
self._save_visible_panel()
|
||||
self._set_menu_visible_panel()
|
||||
for panel in self._panels:
|
||||
panel.set_selected(panel == self.panel_stack.get_visible_child())
|
||||
GObject.idle_add(
|
||||
self.panel_stack.child_set_property,
|
||||
self.panel_stack.get_visible_child(),
|
||||
'needs-attention',
|
||||
False
|
||||
)
|
||||
|
||||
def on_panel_open_standalone(self, panel):
|
||||
self.set_titlebar(panel.get_headerbar_standalone())
|
||||
|
||||
|
||||
def on_panel_close_standalone(self, headerbar):
|
||||
self.set_titlebar(self.headerbar)
|
||||
|
||||
def on_connection_panel_connection_changed(self, widget, host, port, password):
|
||||
self._settings.set_string(Window.SETTING_HOST, host)
|
||||
self._settings.set_int(Window.SETTING_PORT, port)
|
||||
if use_keyring:
|
||||
if password:
|
||||
keyring.set_password(ZeroconfProvider.KEYRING_SYSTEM, ZeroconfProvider.KEYRING_USERNAME, password)
|
||||
else:
|
||||
if keyring.get_password(ZeroconfProvider.KEYRING_SYSTEM, ZeroconfProvider.KEYRING_USERNAME):
|
||||
keyring.delete_password(ZeroconfProvider.KEYRING_SYSTEM, ZeroconfProvider.KEYRING_USERNAME)
|
||||
|
||||
|
||||
def on_playlist_panel_clear_playlist(self, widget):
|
||||
self._mcg.clear_playlist()
|
||||
|
||||
|
||||
def on_playlist_panel_remove(self, widget, album):
|
||||
self._mcg.remove_album_from_playlist(album)
|
||||
|
||||
|
||||
def on_playlist_panel_remove_multiple(self, widget, albums):
|
||||
self._mcg.remove_albums_from_playlist(albums)
|
||||
|
||||
|
||||
def on_playlist_panel_play(self, widget, album):
|
||||
self._mcg.play_album_from_playlist(album)
|
||||
|
||||
|
||||
def on_playlist_panel_albumart(self, widget, album):
|
||||
self._mcg.get_albumart(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._state.get_property(WindowState.IS_FULLSCREENED):
|
||||
self.fullscreen()
|
||||
else:
|
||||
self.unfullscreen()
|
||||
|
||||
|
||||
def on_cover_panel_set_song(self, widget, pos, time):
|
||||
self._mcg.seek(pos, time)
|
||||
|
||||
|
||||
def on_cover_panel_albumart(self, widget, album):
|
||||
self._mcg.get_albumart(album)
|
||||
|
||||
|
||||
def on_library_panel_update(self, widget):
|
||||
self._mcg.update()
|
||||
|
||||
|
||||
def on_library_panel_play(self, widget, album):
|
||||
self._mcg.play_album(album)
|
||||
|
||||
|
||||
def on_library_panel_queue(self, widget, album):
|
||||
self._mcg.queue_album(album)
|
||||
|
||||
|
||||
def on_library_panel_queue_multiple(self, widget, albums):
|
||||
self._mcg.queue_albums(albums)
|
||||
|
||||
|
||||
def on_library_panel_item_size_changed(self, widget, size):
|
||||
self._playlist_panel.set_item_size(size)
|
||||
self._settings.set_int(Window.SETTING_ITEM_SIZE, self._library_panel.get_item_size())
|
||||
|
||||
|
||||
def on_library_panel_sort_order_changed(self, widget, sort_order):
|
||||
self._settings.set_enum(Window.SETTING_SORT_ORDER, self._library_panel.get_sort_order())
|
||||
|
||||
|
||||
def on_library_panel_sort_type_changed(self, widget, sort_type):
|
||||
self._settings.set_boolean(Window.SETTING_SORT_TYPE, self._library_panel.get_sort_type())
|
||||
|
||||
|
||||
def on_library_panel_albumart(self, widget, album):
|
||||
self._mcg.get_albumart(album)
|
||||
|
||||
|
||||
# MCG callbacks
|
||||
|
||||
def on_mcg_connect(self, connected):
|
||||
if connected:
|
||||
GObject.idle_add(self._connect_connected)
|
||||
self._mcg.load_playlist()
|
||||
self._mcg.load_albums()
|
||||
self._mcg.get_custom(Window._CUSTOM_STARTUP_COMPLETE)
|
||||
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)
|
||||
self._panel_action.set_enabled(True)
|
||||
else:
|
||||
GObject.idle_add(self._connect_disconnected)
|
||||
self._connect_action.set_state(GLib.Variant.new_boolean(False))
|
||||
self._play_action.set_enabled(False)
|
||||
self._clear_playlist_action.set_enabled(False)
|
||||
self._panel_action.set_enabled(False)
|
||||
|
||||
|
||||
def on_mcg_status(self, state, album, pos, time, volume, file, audio, bitrate, error):
|
||||
# Album
|
||||
GObject.idle_add(self._cover_panel.set_album, album)
|
||||
if not album and self._state.get_property(WindowState.IS_FULLSCREENED):
|
||||
self._fullscreen(False)
|
||||
# State
|
||||
if state == 'play':
|
||||
GObject.idle_add(self._set_play)
|
||||
GObject.idle_add(self._cover_panel.set_play, pos, time)
|
||||
self._play_action.set_state(GLib.Variant.new_boolean(True))
|
||||
elif state == 'pause' or state == 'stop':
|
||||
GObject.idle_add(self._set_pause)
|
||||
GObject.idle_add(self._cover_panel.set_pause)
|
||||
self._play_action.set_state(GLib.Variant.new_boolean(False))
|
||||
# Volume
|
||||
GObject.idle_add(self._set_volume, volume)
|
||||
# Status
|
||||
self._server_panel.set_status(file, audio, bitrate, error)
|
||||
# Error
|
||||
if error is None:
|
||||
self.info_revealer.set_reveal_child(False)
|
||||
else:
|
||||
self._show_error(error)
|
||||
|
||||
|
||||
def on_mcg_stats(self, artists, albums, songs, dbplaytime, playtime, uptime):
|
||||
self._server_panel.set_stats(artists, albums, songs, dbplaytime, playtime, uptime)
|
||||
|
||||
|
||||
def on_mcg_load_output_devices(self, devices):
|
||||
self._server_panel.set_output_devices(devices)
|
||||
|
||||
|
||||
def on_mcg_load_playlist(self, playlist):
|
||||
self._playlist_panel.set_playlist(self._connection_panel.get_host(), playlist)
|
||||
|
||||
|
||||
def on_mcg_init_albums(self):
|
||||
GObject.idle_add(self._library_panel.init_albums)
|
||||
|
||||
|
||||
def on_mcg_pulse_albums(self):
|
||||
GObject.idle_add(self._library_panel.load_albums)
|
||||
|
||||
|
||||
def on_mcg_load_albums(self, albums):
|
||||
self._library_panel.set_albums(self._connection_panel.get_host(), albums)
|
||||
|
||||
|
||||
def on_mcg_load_albumart(self, album, data):
|
||||
GObject.idle_add(self._cover_panel.set_albumart, album, data)
|
||||
GObject.idle_add(self._playlist_panel.set_albumart, album, data)
|
||||
GObject.idle_add(self._library_panel.set_albumart, album, data)
|
||||
|
||||
|
||||
def on_mcg_custom(self, name):
|
||||
if name == Window._CUSTOM_STARTUP_COMPLETE:
|
||||
for panel in self._panels:
|
||||
GObject.idle_add(
|
||||
self.panel_stack.child_set_property,
|
||||
panel,
|
||||
'needs-attention',
|
||||
False
|
||||
)
|
||||
|
||||
|
||||
def on_mcg_error(self, error):
|
||||
GObject.idle_add(self._show_error, str(error))
|
||||
|
||||
|
||||
# Settings callbacks
|
||||
|
||||
def on_settings_panel_changed(self, settings, key):
|
||||
panel_index = settings.get_int(key)
|
||||
self.panel_stack.set_visible_child(self._panels[panel_index])
|
||||
|
||||
|
||||
def on_settings_item_size_changed(self, settings, key):
|
||||
size = settings.get_int(key)
|
||||
self._playlist_panel.set_item_size(size)
|
||||
self._library_panel.set_item_size(size)
|
||||
|
||||
|
||||
def on_settings_sort_order_changed(self, settings, key):
|
||||
sort_order = settings.get_enum(key)
|
||||
self._library_panel.set_sort_order(sort_order)
|
||||
|
||||
|
||||
def on_settings_sort_type_changed(self, settings, key):
|
||||
sort_type = settings.get_boolean(key)
|
||||
self._library_panel.set_sort_type(sort_type)
|
||||
|
||||
|
||||
# Private methods
|
||||
|
||||
def _connect(self):
|
||||
self._connection_panel.set_sensitive(False)
|
||||
self._set_headerbar_sensitive(False, True)
|
||||
if self._mcg.is_connected():
|
||||
self._mcg.disconnect()
|
||||
self._settings.set_boolean(Window.SETTING_CONNECTED, False)
|
||||
else:
|
||||
host = self._connection_panel.get_host()
|
||||
port = self._connection_panel.get_port()
|
||||
password = self._connection_panel.get_password()
|
||||
self._mcg.connect(host, port, password)
|
||||
self._settings.set_boolean(Window.SETTING_CONNECTED, True)
|
||||
|
||||
|
||||
def _connect_connected(self):
|
||||
self._headerbar_connected()
|
||||
self._set_headerbar_sensitive(True, False)
|
||||
self.content_stack.set_visible_child(self.panel_stack)
|
||||
self.panel_stack.set_visible_child(self._panels[self._settings.get_int(Window.SETTING_PANEL)])
|
||||
|
||||
|
||||
def _connect_disconnected(self):
|
||||
self._playlist_panel.stop_threads();
|
||||
self._library_panel.stop_threads();
|
||||
self._headerbar_disconnected()
|
||||
self._set_headerbar_sensitive(False, False)
|
||||
self._save_visible_panel()
|
||||
self.content_stack.set_visible_child(self._connection_panel)
|
||||
self._connection_panel.set_sensitive(True)
|
||||
|
||||
|
||||
def _fullscreen(self, fullscreened_new):
|
||||
if fullscreened_new != self._state.get_property(WindowState.IS_FULLSCREENED):
|
||||
self._state.set_property(WindowState.IS_FULLSCREENED, fullscreened_new)
|
||||
if self._state.get_property(WindowState.IS_FULLSCREENED):
|
||||
self.headerbar.hide()
|
||||
self._cover_panel.set_fullscreen(True)
|
||||
# Hide cursor
|
||||
self.get_window().set_cursor(
|
||||
Gdk.Cursor.new_from_name(Gdk.Display.get_default(), "none")
|
||||
)
|
||||
else:
|
||||
self.headerbar.show()
|
||||
self._cover_panel.set_fullscreen(False)
|
||||
# Reset cursor
|
||||
self.get_window().set_cursor(
|
||||
Gdk.Cursor.new_from_name(Gdk.Display.get_default(), "default")
|
||||
)
|
||||
|
||||
|
||||
def _save_visible_panel(self):
|
||||
panel_index_selected = self._panels.index(self.panel_stack.get_visible_child())
|
||||
self._settings.set_int(Window.SETTING_PANEL, panel_index_selected)
|
||||
|
||||
|
||||
def _set_menu_visible_panel(self):
|
||||
panel_index_selected = self._panels.index(self.panel_stack.get_visible_child())
|
||||
self._panel_action.set_state(GLib.Variant.new_string(str(panel_index_selected)))
|
||||
|
||||
|
||||
def _set_visible_toolbar(self):
|
||||
panel_index_selected = self._panels.index(self.panel_stack.get_visible_child())
|
||||
toolbar = self._panels[panel_index_selected].get_toolbar()
|
||||
self.toolbar_stack.set_visible_child(toolbar)
|
||||
|
||||
|
||||
def _set_play(self):
|
||||
self.headerbar_button_playpause.handler_block_by_func(
|
||||
self.on_headerbar_playpause_toggled
|
||||
)
|
||||
self.headerbar_button_playpause.set_active(True)
|
||||
self.headerbar_button_playpause.handler_unblock_by_func(
|
||||
self.on_headerbar_playpause_toggled
|
||||
)
|
||||
|
||||
|
||||
def _set_pause(self):
|
||||
self.headerbar_button_playpause.handler_block_by_func(
|
||||
self.on_headerbar_playpause_toggled
|
||||
)
|
||||
self.headerbar_button_playpause.set_active(False)
|
||||
self.headerbar_button_playpause.handler_unblock_by_func(
|
||||
self.on_headerbar_playpause_toggled
|
||||
)
|
||||
|
||||
|
||||
def _set_volume(self, volume):
|
||||
if volume >= 0:
|
||||
self.headerbar_button_volume.set_visible(True)
|
||||
if not self._changing_volume:
|
||||
self._setting_volume = True
|
||||
self.headerbar_button_volume.set_value(volume / 100)
|
||||
self._setting_volume = False
|
||||
else:
|
||||
self.headerbar_button_volume.set_visible(False)
|
||||
|
||||
|
||||
def _headerbar_connected(self):
|
||||
self.headerbar_button_connect.handler_block_by_func(
|
||||
self.on_headerbar_connection_active_notify
|
||||
)
|
||||
self.headerbar_button_connect.set_active(True)
|
||||
self.headerbar_button_connect.set_state(True)
|
||||
self.headerbar_button_connect.handler_unblock_by_func(
|
||||
self.on_headerbar_connection_active_notify
|
||||
)
|
||||
self.headerbar_title_stack.set_visible_child(self.headerbar_panel_switcher)
|
||||
|
||||
|
||||
def _headerbar_disconnected(self):
|
||||
self.headerbar_button_connect.handler_block_by_func(
|
||||
self.on_headerbar_connection_active_notify
|
||||
)
|
||||
self.headerbar_button_connect.set_active(False)
|
||||
self.headerbar_button_connect.set_state(False)
|
||||
self.headerbar_button_connect.handler_unblock_by_func(
|
||||
self.on_headerbar_connection_active_notify
|
||||
)
|
||||
self.headerbar_title_stack.set_visible_child(self.headerbar_connection_label)
|
||||
|
||||
|
||||
def _set_headerbar_sensitive(self, sensitive, connecting):
|
||||
self.headerbar_button_playpause.set_sensitive(sensitive)
|
||||
self.headerbar_button_volume.set_sensitive(sensitive)
|
||||
self.headerbar_panel_switcher.set_sensitive(sensitive)
|
||||
self.headerbar_button_connect.set_sensitive(not connecting)
|
||||
|
||||
|
||||
def _show_error(self, message):
|
||||
self.info_bar.set_message_type(Gtk.MessageType.ERROR)
|
||||
self.info_label.set_text(message)
|
||||
self.info_revealer.set_reveal_child(True)
|
||||
Loading…
Reference in a new issue