This commit is contained in:
Benjamin Schaaf
2021-02-09 01:24:04 +11:00
parent 56ae24b479
commit 4ba2e09cf1
5 changed files with 302 additions and 271 deletions

View File

@@ -1,7 +1,7 @@
from random import randint
from typing import Any, cast, List
from gi.repository import Gdk, GLib, GObject, Gtk, Pango
from gi.repository import Gdk, GLib, GObject, Gtk, Pango, Handy
from sublime_music.adapters import AdapterManager, api_objects as API, Result
from sublime_music.config import AppConfiguration
@@ -15,81 +15,37 @@ from .spinner_image import SpinnerImage
class AlbumWithSongs(Gtk.Box):
__gsignals__ = {
"song-selected": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ()),
# "song-selected": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ()),
"song-clicked": (
GObject.SignalFlags.RUN_FIRST,
GObject.TYPE_NONE,
(int, object, object),
),
"back-clicked": (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ()),
}
show_back_button = GObject.Property(type=bool, default=False)
album = None
offline_mode = True
cover_art_result = None
def __init__(
self,
cover_art_size: int = 200,
show_artist_name: bool = True,
):
Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL)
def __init__(self, show_artist_name: bool = True, scroll_contents: bool = False, **kwargs):
Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)
self.show_artist_name = show_artist_name
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.artist_artwork = SpinnerImage(
loading=False,
image_name="artist-album-list-artwork",
spinner_name="artist-artwork-spinner",
image_size=cover_art_size,
)
# Account for 10px margin on all sides with "+ 20".
self.artist_artwork.set_size_request(cover_art_size + 20, cover_art_size + 20)
box.pack_start(self.artist_artwork, False, False, 0)
box.pack_start(Gtk.Box(), True, True, 0)
self.pack_start(box, False, False, 0)
action_bar = Gtk.ActionBar()
album_details = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
album_title_and_buttons = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
back_button_revealer = Gtk.Revealer(transition_type=Gtk.RevealerTransitionType.CROSSFADE)
self.bind_property("show-back-button", back_button_revealer, "reveal-child", GObject.BindingFlags.SYNC_CREATE)
# TODO (#43): deal with super long-ass titles
self.title = Gtk.Label(
name="artist-album-list-album-name",
halign=Gtk.Align.START,
ellipsize=Pango.EllipsizeMode.END,
)
album_title_and_buttons.add(self.title)
back_button = IconButton("go-previous-symbolic")
back_button.connect("clicked", lambda *_: self.emit("back-clicked"))
back_button_revealer.add(back_button)
self.play_btn = IconButton(
"media-playback-start-symbolic",
"Play all songs in this album",
sensitive=False,
)
self.play_btn.connect("clicked", self.play_btn_clicked)
album_title_and_buttons.pack_start(self.play_btn, False, False, 5)
self.shuffle_btn = IconButton(
"media-playlist-shuffle-symbolic",
"Shuffle all songs in this album",
sensitive=False,
)
self.shuffle_btn.connect("clicked", self.shuffle_btn_clicked)
album_title_and_buttons.pack_start(self.shuffle_btn, False, False, 5)
self.play_next_btn = IconButton(
"queue-front-symbolic",
"Play all of the songs in this album next",
sensitive=False,
)
album_title_and_buttons.pack_start(self.play_next_btn, False, False, 5)
self.add_to_queue_btn = IconButton(
"queue-back-symbolic",
"Add all the songs in this album to the end of the play queue",
sensitive=False,
)
album_title_and_buttons.pack_start(self.add_to_queue_btn, False, False, 5)
action_bar.pack_start(back_button_revealer)
self.download_all_btn = IconButton(
"folder-download-symbolic",
@@ -97,21 +53,105 @@ class AlbumWithSongs(Gtk.Box):
sensitive=False,
)
self.download_all_btn.connect("clicked", self.on_download_all_click)
album_title_and_buttons.pack_end(self.download_all_btn, False, False, 5)
action_bar.pack_end(self.download_all_btn)
album_details.add(album_title_and_buttons)
self.add_to_queue_btn = IconButton(
"queue-back-symbolic",
"Add all the songs in this album to the end of the play queue",
sensitive=False,
)
action_bar.pack_end(self.add_to_queue_btn)
self.stats = Gtk.Label(
self.play_next_btn = IconButton(
"queue-front-symbolic",
"Play all of the songs in this album next",
sensitive=False,
)
action_bar.pack_end(self.play_next_btn)
self.shuffle_btn = IconButton(
"media-playlist-shuffle-symbolic",
"Shuffle all songs in this album",
sensitive=False,
)
self.shuffle_btn.connect("clicked", self.shuffle_btn_clicked)
action_bar.pack_end(self.shuffle_btn)
self.play_btn = IconButton(
"media-playback-start-symbolic",
"Play all songs in this album",
sensitive=False,
)
self.play_btn.connect("clicked", self.play_btn_clicked)
action_bar.pack_end(self.play_btn)
self.pack_start(action_bar, False, False, 0)
if scroll_contents:
self.pack_start(Gtk.Separator(), False, False, 0)
scrolled_window = Gtk.ScrolledWindow(hscrollbar_policy=Gtk.PolicyType.NEVER)
self.pack_start(scrolled_window, True, True, 0)
contents_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
scrolled_window.add(contents_box)
else:
contents_box = self
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.artist_artwork = SpinnerImage(
loading=False,
image_name="artist-album-list-artwork",
spinner_name="artist-artwork-spinner",
image_size=80,
)
# Account for 10px margin on all sides with "+ 20".
# self.artist_artwork.set_size_request(cover_art_size + 20, cover_art_size + 20)
box.pack_start(self.artist_artwork, False, False, 0)
album_details = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
# TODO (#43): deal with super long-ass titles
self.title = Gtk.Label(
name="artist-album-list-album-name",
halign=Gtk.Align.START,
ellipsize=Pango.EllipsizeMode.END,
)
album_details.pack_start(self.title, False, False, 0)
self.artist_and_year = Gtk.Label(
halign=Gtk.Align.START,
margin_left=10,
margin_right=10,
ellipsize=Pango.EllipsizeMode.END,
)
album_details.add(self.stats)
album_details.pack_start(self.artist_and_year, False, False, 0)
details_bottom_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.genre_and_song_count = Gtk.Label()
details_bottom_box.pack_start(self.genre_and_song_count, False, False, 10)
squeezer = Handy.Squeezer(homogeneous=False)
self.song_duration_long = Gtk.Label(halign=Gtk.Align.END)
squeezer.add(self.song_duration_long)
self.song_duration_short = Gtk.Label(halign=Gtk.Align.END)
squeezer.add(self.song_duration_short)
details_bottom_box.pack_end(squeezer, False, False, 20)
album_details.pack_start(details_bottom_box, False, False, 0)
self.loading_indicator_container = Gtk.Box()
album_details.add(self.loading_indicator_container)
album_details.pack_start(self.loading_indicator_container, False, False, 0)
self.error_container = Gtk.Box()
album_details.add(self.error_container)
album_details.pack_start(self.error_container, False, False, 0)
box.pack_start(album_details, True, True, 0)
contents_box.pack_start(box, False, False, 0)
# clickable, cache status, title, duration, song ID
self.album_song_store = Gtk.ListStore(bool, str, str, str, str)
@@ -144,11 +184,7 @@ class AlbumWithSongs(Gtk.Box):
self.album_songs.get_selection().connect(
"changed", self.on_song_selection_change
)
album_details.add(self.album_songs)
self.pack_end(album_details, True, True, 0)
# self.update_album_songs(album.id)
contents_box.pack_start(self.album_songs, True, True, 0)
# Event Handlers
# =========================================================================
@@ -256,12 +292,18 @@ class AlbumWithSongs(Gtk.Box):
self.title.set_label(album.name)
self.stats.set_label(util.dot_join(
album.artist.name if self.show_artist_name and album.artist else None,
album.year,
album.genre.name if album.genre else None,
util.format_sequence_duration(album.duration) if album.duration else None,
))
artist = album.artist.name if self.show_artist_name and album.artist else None
self.artist_and_year.set_label(util.dot_join(artist, album.year))
self.genre_and_song_count.set_label(util.dot_join(
f"{album.song_count} " + util.pluralize("song", album.song_count),
album.genre.name if album.genre else None))
self.song_duration_long.set_label(
util.format_sequence_duration(album.duration) if album.duration else "")
self.song_duration_short.set_label(
util.format_song_duration(album.duration) if album.duration else "")
if self.cover_art_result is not None:
self.cover_art_result.cancel()