v0.24.0: click the blank cover
Clicking the gray sidebar art square (playing track has no embedded art) now opens Download Album Art for that track, same as the right-click menu. Once art is embedded the square refreshes and a click opens the big view again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
"""LinTunes — iTunes-style music library manager and player for Linux."""
|
"""LinTunes — iTunes-style music library manager and player for Linux."""
|
||||||
|
|
||||||
__version__ = "0.23.0"
|
__version__ = "0.24.0"
|
||||||
|
|||||||
@@ -206,6 +206,8 @@ class MainWindow(QMainWindow):
|
|||||||
self._sidebar.library_selected.connect(self._show_library)
|
self._sidebar.library_selected.connect(self._show_library)
|
||||||
self._sidebar.playlist_selected.connect(self._show_playlist)
|
self._sidebar.playlist_selected.connect(self._show_playlist)
|
||||||
self._sidebar.tree.export_requested.connect(self._export_playlist)
|
self._sidebar.tree.export_requested.connect(self._export_playlist)
|
||||||
|
self._sidebar.art.download_art_requested.connect(
|
||||||
|
lambda tid: self._download_album_art([tid]))
|
||||||
self._content.currentChanged.connect(self._update_totals)
|
self._content.currentChanged.connect(self._update_totals)
|
||||||
for view in (self._library_view, self._playlist_view):
|
for view in (self._library_view, self._playlist_view):
|
||||||
view.play_requested.connect(
|
view.play_requested.connect(
|
||||||
@@ -1399,7 +1401,11 @@ class MainWindow(QMainWindow):
|
|||||||
self, "Download Album Art",
|
self, "Download Album Art",
|
||||||
"Couldn't embed artwork in some files:\n\n"
|
"Couldn't embed artwork in some files:\n\n"
|
||||||
+ "\n".join(failures[:10]))
|
+ "\n".join(failures[:10]))
|
||||||
elif done:
|
if done:
|
||||||
|
# Normally track_updated already did this, but only when the
|
||||||
|
# file's size changed.
|
||||||
|
self._sidebar.art.refresh()
|
||||||
|
if done and not failures:
|
||||||
noun = "track" if done == 1 else "tracks"
|
noun = "track" if done == 1 else "tracks"
|
||||||
self.statusBar().showMessage(
|
self.statusBar().showMessage(
|
||||||
f"Artwork embedded in {done} {noun}", 5000)
|
f"Artwork embedded in {done} {noun}", 5000)
|
||||||
|
|||||||
+16
-6
@@ -88,7 +88,10 @@ class SidebarPanel(QWidget):
|
|||||||
|
|
||||||
class SidebarArt(QWidget):
|
class SidebarArt(QWidget):
|
||||||
"""Square album art pinned to the sidebar bottom; gray square when the
|
"""Square album art pinned to the sidebar bottom; gray square when the
|
||||||
current track has no embedded art. A click opens the big art window."""
|
current track has no embedded art. A click opens the big art window, or,
|
||||||
|
on the gray square, asks for the track's art to be downloaded."""
|
||||||
|
|
||||||
|
download_art_requested = pyqtSignal(int) # track id
|
||||||
|
|
||||||
def __init__(self, player, parent=None):
|
def __init__(self, player, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
@@ -96,7 +99,6 @@ class SidebarArt(QWidget):
|
|||||||
self._pixmap: QPixmap | None = None
|
self._pixmap: QPixmap | None = None
|
||||||
self._track = None
|
self._track = None
|
||||||
self._art_window = ArtWindow()
|
self._art_window = ArtWindow()
|
||||||
self.setToolTip("Click to view full size")
|
|
||||||
player.track_changed.connect(self.set_track)
|
player.track_changed.connect(self.set_track)
|
||||||
|
|
||||||
def set_track(self, track):
|
def set_track(self, track):
|
||||||
@@ -108,6 +110,12 @@ class SidebarArt(QWidget):
|
|||||||
pixmap = QPixmap()
|
pixmap = QPixmap()
|
||||||
if pixmap.loadFromData(data):
|
if pixmap.loadFromData(data):
|
||||||
self._pixmap = pixmap
|
self._pixmap = pixmap
|
||||||
|
if self._pixmap is not None:
|
||||||
|
self.setToolTip("Click to view full size")
|
||||||
|
elif track is not None:
|
||||||
|
self.setToolTip("Click to download album art")
|
||||||
|
else:
|
||||||
|
self.setToolTip("")
|
||||||
if self._art_window.isVisible():
|
if self._art_window.isVisible():
|
||||||
self._art_window.set_artwork(self._pixmap, self._title())
|
self._art_window.set_artwork(self._pixmap, self._title())
|
||||||
self.update()
|
self.update()
|
||||||
@@ -132,10 +140,12 @@ class SidebarArt(QWidget):
|
|||||||
# A click is a release that lands on the art. Opening on press would
|
# A click is a release that lands on the art. Opening on press would
|
||||||
# also fire when a drag merely starts here.
|
# also fire when a drag merely starts here.
|
||||||
if (event.button() == Qt.MouseButton.LeftButton
|
if (event.button() == Qt.MouseButton.LeftButton
|
||||||
and self.rect().contains(event.position().toPoint())
|
and self.rect().contains(event.position().toPoint())):
|
||||||
and self._pixmap is not None):
|
if self._pixmap is not None:
|
||||||
self._art_window.show_artwork(self._pixmap, self._title(),
|
self._art_window.show_artwork(self._pixmap, self._title(),
|
||||||
self.screen())
|
self.screen())
|
||||||
|
elif self._track is not None:
|
||||||
|
self.download_art_requested.emit(self._track.track_id)
|
||||||
super().mouseReleaseEvent(event)
|
super().mouseReleaseEvent(event)
|
||||||
|
|
||||||
def paintEvent(self, event):
|
def paintEvent(self, event):
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
"""Round 61: clicking the gray (art-less) sidebar square asks for the
|
||||||
|
playing track's art to be downloaded; with art it still opens the big view."""
|
||||||
|
|
||||||
|
from PyQt6.QtCore import Qt
|
||||||
|
from PyQt6.QtGui import QPixmap
|
||||||
|
|
||||||
|
from lintunes.models import Track
|
||||||
|
from tests.test_round49 import _FakePlayer, _release
|
||||||
|
|
||||||
|
|
||||||
|
def _art():
|
||||||
|
from lintunes.gui.sidebar import SidebarArt
|
||||||
|
art = SidebarArt(_FakePlayer())
|
||||||
|
art.resize(100, 100)
|
||||||
|
requested = []
|
||||||
|
art.download_art_requested.connect(requested.append)
|
||||||
|
return art, requested
|
||||||
|
|
||||||
|
|
||||||
|
def _track(tid=7):
|
||||||
|
# No location: set_track reads no art, which is the gray-square case
|
||||||
|
return Track(track_id=tid, name="Song", artist="Artist", album="Album")
|
||||||
|
|
||||||
|
|
||||||
|
class TestGraySquareClick:
|
||||||
|
def test_click_without_art_requests_a_download(self, qapp):
|
||||||
|
art, requested = _art()
|
||||||
|
art.set_track(_track(42))
|
||||||
|
art.mouseReleaseEvent(_release(Qt.MouseButton.LeftButton))
|
||||||
|
assert requested == [42]
|
||||||
|
assert not art._art_window.isVisible()
|
||||||
|
|
||||||
|
def test_no_track_requests_nothing(self, qapp):
|
||||||
|
art, requested = _art()
|
||||||
|
art.mouseReleaseEvent(_release(Qt.MouseButton.LeftButton))
|
||||||
|
assert requested == []
|
||||||
|
|
||||||
|
def test_with_art_opens_the_big_view_instead(self, qapp):
|
||||||
|
art, requested = _art()
|
||||||
|
art.set_track(_track())
|
||||||
|
pixmap = QPixmap(32, 32)
|
||||||
|
pixmap.fill(Qt.GlobalColor.blue)
|
||||||
|
art._pixmap = pixmap
|
||||||
|
art.mouseReleaseEvent(_release(Qt.MouseButton.LeftButton))
|
||||||
|
try:
|
||||||
|
assert requested == []
|
||||||
|
assert art._art_window.isVisible()
|
||||||
|
finally:
|
||||||
|
art._art_window.hide()
|
||||||
|
|
||||||
|
def test_right_click_or_release_outside_requests_nothing(self, qapp):
|
||||||
|
art, requested = _art()
|
||||||
|
art.set_track(_track())
|
||||||
|
art.mouseReleaseEvent(_release(Qt.MouseButton.RightButton))
|
||||||
|
art.mouseReleaseEvent(_release(Qt.MouseButton.LeftButton, 500, 500))
|
||||||
|
assert requested == []
|
||||||
|
|
||||||
|
def test_tooltip_says_what_a_click_will_do(self, qapp):
|
||||||
|
art, _ = _art()
|
||||||
|
art.set_track(None)
|
||||||
|
assert art.toolTip() == ""
|
||||||
|
art.set_track(_track())
|
||||||
|
assert art.toolTip() == "Click to download album art"
|
||||||
Reference in New Issue
Block a user