Made the playlists list work

This commit is contained in:
Sumner Evans
2019-06-22 14:45:38 -06:00
parent 1df026d9ee
commit af3d024712
8 changed files with 163 additions and 21 deletions

View File

@@ -11,6 +11,7 @@ from .ui.main import MainWindow
from .ui.configure_servers import ConfigureServersDialog from .ui.configure_servers import ConfigureServersDialog
from .state_manager import ApplicationState from .state_manager import ApplicationState
from .cache_manager import CacheManager
class LibremsonicApp(Gtk.Application): class LibremsonicApp(Gtk.Application):
@@ -96,6 +97,9 @@ class LibremsonicApp(Gtk.Application):
context.add_provider_for_screen(screen, css_provider, context.add_provider_for_screen(screen, css_provider,
Gtk.STYLE_PROVIDER_PRIORITY_USER) Gtk.STYLE_PROVIDER_PRIORITY_USER)
self.window.stack.connect('notify::visible-child',
self.on_stack_change)
# Display the window. # Display the window.
self.window.show_all() self.window.show_all()
self.window.present() self.window.present()
@@ -108,8 +112,10 @@ class LibremsonicApp(Gtk.Application):
if self.state.config.current_server is None: if self.state.config.current_server is None:
self.show_configure_servers_dialog() self.show_configure_servers_dialog()
else: else:
self.on_connected_server_changed(None, self.on_connected_server_changed(
self.state.config.current_server) None,
self.state.config.current_server,
)
# ########## ACTION HANDLERS ########## # # ########## ACTION HANDLERS ########## #
def on_configure_servers(self, action, param): def on_configure_servers(self, action, param):
@@ -141,9 +147,15 @@ class LibremsonicApp(Gtk.Application):
self.state.config.current_server = current_server self.state.config.current_server = current_server
self.state.save_config() self.state.save_config()
self.state.cache_manager = CacheManager(
self.state.config.servers[self.state.config.current_server])
# Update the window according to the new server configuration. # Update the window according to the new server configuration.
self.update_window() self.update_window()
def on_stack_change(self, stack, child):
self.update_window()
# ########## HELPER METHODS ########## # # ########## HELPER METHODS ########## #
def show_configure_servers_dialog(self): def show_configure_servers_dialog(self):
"""Show the Connect to Server dialog.""" """Show the Connect to Server dialog."""

View File

@@ -0,0 +1,17 @@
from libremsonic.config import ServerConfiguration
from libremsonic.server import Server
class CacheManager:
server: Server
def __init__(self, server_config: ServerConfiguration):
self.server = Server(
name=server_config.name,
hostname=server_config.server_address,
username=server_config.username,
password=server_config.password,
)
def get_playlists(self):
return self.server.get_playlists()

View File

@@ -1,10 +1,12 @@
from typing import List, Any from typing import List, Any
from libremsonic.cache_manager import CacheManager
from .config import get_config, save_config, AppConfiguration from .config import get_config, save_config, AppConfiguration
class ApplicationState: class ApplicationState:
config: AppConfiguration = AppConfiguration.get_default_configuration() config: AppConfiguration = AppConfiguration.get_default_configuration()
cache_manager: CacheManager = None
current_song: Any # TODO fix current_song: Any # TODO fix
config_file: str config_file: str
playing: bool = False playing: bool = False

View File

@@ -4,13 +4,36 @@ import sys
gi.require_version('Gtk', '3.0') gi.require_version('Gtk', '3.0')
from gi.repository import Gio, Gtk from gi.repository import Gio, Gtk
from libremsonic.state_manager import ApplicationState
class AlbumsPanel(Gtk.Box):
class AlbumsPanel(Gtk.ScrolledWindow):
def __init__(self):
Gtk.ScrolledWindow.__init__(self)
self.child = AlbumsGrid()
self.add(self.child)
def update(self, state: ApplicationState):
self.child.update(state)
class AlbumsGrid(Gtk.FlowBox):
"""Defines the albums panel.""" """Defines the albums panel."""
def __init__(self): def __init__(self):
Gtk.Box.__init__(self) Gtk.FlowBox.__init__(
self,
vexpand=True,
hexpand=True,
row_spacing=12,
column_spacing=12,
margin_top=12,
margin_bottom=12,
homogeneous=True,
valign=Gtk.Align.START,
halign=Gtk.Align.CENTER,
selection_mode=Gtk.SelectionMode.NONE,
)
albums = Gtk.Label('Albums') def update(self, state: ApplicationState):
pass
self.add(albums)

View File

@@ -1,3 +1,11 @@
/* ********** Playback Controls ********** */
#new-playlist-button {
border-radius: 0;
border-left: none;
border-right: none;
border-bottom: none;
}
/* ********** Playback Controls ********** */ /* ********** Playback Controls ********** */
#player-controls-bar #play-button { #player-controls-bar #play-button {
min-height: 45px; min-height: 45px;
@@ -13,7 +21,7 @@
} }
#player-controls-bar #song-scrubber { #player-controls-bar #song-scrubber {
min-width: 300px; min-width: 400px;
} }
#player-controls-bar #volume-slider { #player-controls-bar #volume-slider {

View File

@@ -5,6 +5,7 @@ gi.require_version('Gtk', '3.0')
from gi.repository import Gio, Gtk from gi.repository import Gio, Gtk
from .albums import AlbumsPanel from .albums import AlbumsPanel
from .playlists import PlaylistsPanel
from .player_controls import PlayerControls from .player_controls import PlayerControls
from libremsonic.server import Server from libremsonic.server import Server
from libremsonic.state_manager import ApplicationState from libremsonic.state_manager import ApplicationState
@@ -20,21 +21,21 @@ class MainWindow(Gtk.ApplicationWindow):
self.panels = { self.panels = {
'Albums': AlbumsPanel(), 'Albums': AlbumsPanel(),
'Artists': Gtk.Label('Artists'), 'Artists': Gtk.Label('Artists'),
'Playlists': Gtk.Label('Playlists'), 'Playlists': PlaylistsPanel(),
'More': Gtk.Label('More'), 'More': Gtk.Label('More'),
} }
# Create the stack # Create the stack
stack = self.create_stack(**self.panels) self.stack = self.create_stack(**self.panels)
stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT) self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
self.titlebar = self.create_headerbar(stack) self.titlebar = self.create_headerbar(self.stack)
self.set_titlebar(self.titlebar) self.set_titlebar(self.titlebar)
self.player_controls = PlayerControls() self.player_controls = PlayerControls()
flowbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) flowbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
flowbox.pack_start(stack, True, True, 0) flowbox.pack_start(self.stack, True, True, 0)
flowbox.pack_start(self.player_controls, False, True, 0) flowbox.pack_start(self.player_controls, False, True, 0)
self.add(flowbox) self.add(flowbox)
@@ -49,6 +50,10 @@ class MainWindow(Gtk.ApplicationWindow):
self.connected_to_label.set_markup( self.connected_to_label.set_markup(
f'<span style="italic">Not Connected to a Server</span>') f'<span style="italic">Not Connected to a Server</span>')
active_panel = self.stack.get_visible_child()
if hasattr(active_panel, 'update'):
active_panel.update(state)
self.player_controls.update(state) self.player_controls.update(state)
def create_stack(self, **kwargs): def create_stack(self, **kwargs):

View File

@@ -37,19 +37,27 @@ class PlayerControls(Gtk.ActionBar):
details_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) details_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
details_box.pack_start(Gtk.Box(), True, True, 0) details_box.pack_start(Gtk.Box(), True, True, 0)
self.song_name = Gtk.Label('<b>Song name</b>', self.song_name = Gtk.Label(
halign=Gtk.Align.START, '<b>Song name</b>',
use_markup=True) halign=Gtk.Align.START,
use_markup=True,
)
self.song_name.set_name('song-name') self.song_name.set_name('song-name')
details_box.add(self.song_name) details_box.add(self.song_name)
self.album_name = Gtk.Label('Album name', halign=Gtk.Align.START) self.album_name = Gtk.Label(
'<i>Album name</i>',
halign=Gtk.Align.START,
use_markup=True,
)
self.album_name.set_name('album-name') self.album_name.set_name('album-name')
details_box.add(self.album_name) details_box.add(self.album_name)
self.artist_name = Gtk.Label('<i>Artist name</i>', self.artist_name = Gtk.Label(
halign=Gtk.Align.START, 'Artist name',
use_markup=True) halign=Gtk.Align.START,
use_markup=True,
)
self.artist_name.set_name('artist-name') self.artist_name.set_name('artist-name')
details_box.add(self.artist_name) details_box.add(self.artist_name)
@@ -122,6 +130,8 @@ class PlayerControls(Gtk.ActionBar):
return box return box
def create_up_next_volume(self): def create_up_next_volume(self):
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
vbox.pack_start(Gtk.Box(), True, True, 0)
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
# Up Next button # Up Next button
@@ -144,7 +154,9 @@ class PlayerControls(Gtk.ActionBar):
volume_slider.set_value(100) volume_slider.set_value(100)
box.pack_start(volume_slider, True, True, 0) box.pack_start(volume_slider, True, True, 0)
return box vbox.pack_start(box, False, True, 0)
vbox.pack_start(Gtk.Box(), True, True, 0)
return vbox
def button_with_icon(self, def button_with_icon(self,
icon_name, icon_name,

View File

@@ -0,0 +1,63 @@
import gi
import sys
gi.require_version('Gtk', '3.0')
from gi.repository import Gio, Gtk
from libremsonic.server.api_objects import Playlist
from libremsonic.state_manager import ApplicationState
class PlaylistsPanel(Gtk.Paned):
"""Defines the playlists panel."""
def __init__(self):
Gtk.FlowBox.__init__(
self,
orientation=Gtk.Orientation.HORIZONTAL,
)
# The playlist list on the left side
# =====================================================================
playlist_list_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
list_scroll_window = Gtk.ScrolledWindow(min_content_width=200)
self.playlist_list = Gtk.ListBox()
list_scroll_window.add(self.playlist_list)
playlist_list_vbox.pack_start(list_scroll_window, True, True, 0)
# Add playlist button
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
add_icon = Gio.ThemedIcon(name='list-add')
image = Gtk.Image.new_from_gicon(add_icon, Gtk.IconSize.LARGE_TOOLBAR)
box.add(image)
box.add(Gtk.Label('New Playlist', margin=10))
self.new_playlist = Gtk.Button(name='new-playlist-button')
self.new_playlist.add(box)
playlist_list_vbox.pack_start(self.new_playlist, False, False, 0)
self.pack1(playlist_list_vbox, False, False)
# The playlist view on the right side
# =====================================================================
self.playlist_view = Gtk.ListBox()
self.pack2(self.playlist_view, True, False)
def update(self, state: ApplicationState):
playlists = state.cache_manager.get_playlists()
for c in self.playlist_list.get_children():
self.playlist_list.remove(c)
for playlist in playlists.playlist:
self.playlist_list.add(self.create_playlist_label(playlist))
self.playlist_list.show_all()
def create_playlist_label(self, playlist: Playlist):
return Gtk.Label(
f'<b>{playlist.name}</b>',
halign=Gtk.Align.START,
use_markup=True,
margin=10,
)