diff --git a/sublime_music/ui/main.py b/sublime_music/ui/main.py index fbc14e3..3cd3dc0 100644 --- a/sublime_music/ui/main.py +++ b/sublime_music/ui/main.py @@ -176,7 +176,7 @@ class MainWindow(Handy.ApplicationWindow): drawer.set_flap(mobile_flap) def drawer_reveal_progress(drawer, _): - self.player_manager.flap_open = drawer.get_reveal_progress() > 0.5 + self.player_manager.flap_reveal_progress = drawer.get_reveal_progress() drawer.connect("notify::reveal-progress", drawer_reveal_progress) self.sidebar_flap.set_content(drawer) diff --git a/sublime_music/ui/player_controls/common.py b/sublime_music/ui/player_controls/common.py index 46fce53..48f5472 100644 --- a/sublime_music/ui/player_controls/common.py +++ b/sublime_music/ui/player_controls/common.py @@ -113,29 +113,22 @@ def show_play_queue_popover(manager: Manager, relative_to, paths: List[str], pos # Album Art column. This function defines what image to use for the play queue # song icon. -def filename_to_pixbuf( - column: Any, - cell: Gtk.CellRendererPixbuf, - model: Gtk.ListStore, - tree_iter: Gtk.TreeIter, - flags: Any, -): - cell.set_property("sensitive", model.get_value(tree_iter, 0)) - filename = model.get_value(tree_iter, 1) - if not filename: - cell.set_property("icon_name", "") - return +def filename_to_pixbuf(manager: Manager): + def f2p( + column: Any, + cell: Gtk.CellRendererPixbuf, + model: Gtk.ListStore, + tree_iter: Gtk.TreeIter, + flags: Any, + ): + cell.set_property("sensitive", model.get_value(tree_iter, 0)) + filename = model.get_value(tree_iter, 1) + playing = model.get_value(tree_iter, 3) - pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(filename, 50, 50, True) + pixbuf = manager.get_play_queue_cover_art(filename, playing) + if not pixbuf: + cell.set_property("icon_name", "") + else: + cell.set_property("pixbuf", pixbuf) - # If this is the playing song, then overlay the play icon. - if model.get_value(tree_iter, 3): - play_overlay_pixbuf = GdkPixbuf.Pixbuf.new_from_file( - str(resolve_path("ui/images/play-queue-play.png")) - ) - - play_overlay_pixbuf.composite( - pixbuf, 0, 0, 50, 50, 0, 0, 1, 1, GdkPixbuf.InterpType.NEAREST, 200 - ) - - cell.set_property("pixbuf", pixbuf) + return f2p diff --git a/sublime_music/ui/player_controls/desktop.py b/sublime_music/ui/player_controls/desktop.py index 8a83ffd..c58c447 100644 --- a/sublime_music/ui/player_controls/desktop.py +++ b/sublime_music/ui/player_controls/desktop.py @@ -384,7 +384,7 @@ class Desktop(Gtk.Box): renderer = Gtk.CellRendererPixbuf() renderer.set_fixed_size(55, 60) column = Gtk.TreeViewColumn("", renderer) - column.set_cell_data_func(renderer, common.filename_to_pixbuf) + column.set_cell_data_func(renderer, common.filename_to_pixbuf(self.state)) column.set_resizable(True) self.play_queue_list.append_column(column) diff --git a/sublime_music/ui/player_controls/manager.py b/sublime_music/ui/player_controls/manager.py index 598edf3..bd92f7b 100644 --- a/sublime_music/ui/player_controls/manager.py +++ b/sublime_music/ui/player_controls/manager.py @@ -5,9 +5,10 @@ from functools import partial import bleach -from gi.repository import GObject, Gtk, GLib +from gi.repository import GObject, Gtk, GLib, GdkPixbuf from .. import util +from ...util import resolve_path from ...adapters import AdapterManager, Result from ...adapters.api_objects import Song from ...config import AppConfiguration @@ -36,7 +37,7 @@ class Manager(GObject.GObject): scrubber_cache = GObject.Property(type=int, default=0) play_queue_open = GObject.Property(type=bool, default=False) play_queue_store = GObject.Property(type=Gtk.ListStore) - flap_open = GObject.Property(type=bool, default=False) + flap_reveal_progress = GObject.Property(type=float, default=False) offline_mode = GObject.Property(type=bool, default=False) has_song = GObject.Property(type=bool, default=False) @@ -55,7 +56,7 @@ class Manager(GObject.GObject): def __init__(self): super().__init__() - self.volume = Gtk.Adjustment(1, 0, 1, 0.01, 0, 0) + self.volume = Gtk.Adjustment.new(1, 0, 1, 0.01, 0, 0) self.scrubber = Gtk.Adjustment() self.scrubber.set_step_increment(1) self.scrubber.connect("value-changed", self.on_scrubber_changed) @@ -69,6 +70,7 @@ class Manager(GObject.GObject): bool, # playing str, # song ID ) + self.play_queue_store_art_cache = {} # Set up drag-and-drop on the song list for editing the order of the # playlist. @@ -192,7 +194,31 @@ class Manager(GObject.GObject): for control in self._controls: control.set_cover_art(cover_art_filename, loading) + def get_play_queue_cover_art(self, filename: Optional[str], playing: bool): + if filename in self.play_queue_store_art_cache: + return self.play_queue_store_art_cache[filename] + + if not filename: + return None + + pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(filename, 50, 50, True) + + # If this is the playing song, then overlay the play icon. + if playing: + play_overlay_pixbuf = GdkPixbuf.Pixbuf.new_from_file( + str(resolve_path("ui/images/play-queue-play.png")) + ) + + play_overlay_pixbuf.composite( + pixbuf, 0, 0, 50, 50, 0, 0, 1, 1, GdkPixbuf.InterpType.NEAREST, 200 + ) + + self.play_queue_store_art_cache[filename] = pixbuf + return pixbuf + def on_play_queue_model_row_move(self, *args): + self.play_queue_store_art_cache = {} + # TODO return diff --git a/sublime_music/ui/player_controls/mobile.py b/sublime_music/ui/player_controls/mobile.py index f4cb9ba..3d06c84 100644 --- a/sublime_music/ui/player_controls/mobile.py +++ b/sublime_music/ui/player_controls/mobile.py @@ -10,31 +10,17 @@ from ...config import AppConfiguration from ...util import resolve_path from . import common -class MobileHandle(Gtk.EventBox): +class MobileHandle(Gtk.ActionBar): def __init__(self, state): - super().__init__(above_child=False) + super().__init__() self.get_style_context().add_class("background") self.state = state self.state.add_control(self) - action_bar = Gtk.ActionBar() + self.pack_start(self.create_song_display()) - action_bar.pack_start(self.create_song_display()) - - buttons = Gtk.Stack(transition_type=Gtk.StackTransitionType.CROSSFADE) - - close_buttons = Handy.Squeezer(halign=Gtk.Align.END, homogeneous=False) - - expanded_close_buttons = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) - expanded_close_buttons.pack_start(common.create_prev_button(self.state), False, False, 5) - expanded_close_buttons.pack_start(common.create_play_button(self.state, large=False), False, False, 5) - expanded_close_buttons.pack_start(common.create_next_button(self.state), False, False, 5) - - close_buttons.add(expanded_close_buttons) - close_buttons.add(common.create_play_button(self.state, large=False, halign=Gtk.Align.END)) - - buttons.add(close_buttons) + buttons = Gtk.Overlay() open_buttons = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, halign=Gtk.Align.END) @@ -65,18 +51,30 @@ class MobileHandle(Gtk.EventBox): buttons.add(open_buttons) + close_buttons = Handy.Squeezer(halign=Gtk.Align.END, homogeneous=False) + + expanded_close_buttons = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + expanded_close_buttons.pack_start(common.create_prev_button(self.state), False, False, 5) + expanded_close_buttons.pack_start(common.create_play_button(self.state, large=False), False, False, 5) + expanded_close_buttons.pack_start(common.create_next_button(self.state), False, False, 5) + + close_buttons.add(expanded_close_buttons) + close_buttons.add(common.create_play_button(self.state, large=False, halign=Gtk.Align.END)) + + close_buttons.get_style_context().add_class("background") + + buttons.add_overlay(close_buttons) + def flap_reveal(*_): - if self.state.flap_open: - buttons.set_visible_child(open_buttons) - else: - buttons.set_visible_child(close_buttons) + progress = 1 - self.state.flap_reveal_progress + close_buttons.set_opacity(progress) + close_buttons.set_visible(progress > 0.05) + if progress < 0.8: self.state.play_queue_open = False - self.state.connect("notify::flap-open", flap_reveal) + self.state.connect("notify::flap-reveal-progress", flap_reveal) - action_bar.pack_end(buttons) - - self.add(action_bar) + self.pack_end(buttons) def create_song_display(self): box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, hexpand=True) @@ -260,7 +258,7 @@ class MobileFlap(Handy.Flap): renderer = Gtk.CellRendererPixbuf() renderer.set_fixed_size(55, 60) column = Gtk.TreeViewColumn("", renderer) - column.set_cell_data_func(renderer, common.filename_to_pixbuf) + column.set_cell_data_func(renderer, common.filename_to_pixbuf(self.state)) column.set_resizable(True) play_queue_list.append_column(column)