v0.31.6: album art inside the playlists' frame; text and playhead lifted 2px

The playlist list and the album art under it share one frame (the list's
own style, drawn around both), and the no-art placeholder is a shade
lighter than that frame line so the line still reads around it. The
playlist name, times and playhead sit 2px up (HeaderRow.LIFT), on the
Library button's bottom line by eye.
This commit is contained in:
2026-09-28 23:36:48 -07:00
parent 49b7126765
commit 9549a140b5
4 changed files with 32 additions and 11 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
"""LinTunes — iTunes-style music library manager and player for Linux."""
__version__ = "0.31.5"
__version__ = "0.31.6"
+20 -6
View File
@@ -2,6 +2,7 @@ from PyQt6.QtWidgets import (
QWidget, QVBoxLayout, QPushButton, QTreeWidget, QTreeWidgetItem, QMenu,
QInputDialog, QMessageBox, QAbstractItemView, QLineEdit, QApplication,
QHBoxLayout, QListWidget, QListWidgetItem, QStackedWidget, QSizePolicy,
QFrame,
)
from PyQt6.QtCore import Qt, QTimer, QPoint, pyqtSignal
from PyQt6.QtGui import QBrush, QPainter, QPalette, QPixmap
@@ -75,17 +76,28 @@ class SidebarPanel(QWidget):
self.header = top
top.header_owner = self
# The playlists and the album art under them are one group inside
# one frame — the list's own frame, drawn around both, so the art
# sits within it rather than hanging below.
group = QFrame()
self._lists = QStackedWidget()
self.tree = PlaylistTree(manager)
self._lists.addWidget(self.tree)
self.friend_list = FriendPlaylistList()
self._lists.addWidget(self.friend_list)
layout.addWidget(self._lists, stretch=1)
# What the header row lines the Library button up with.
self.list_area = self._lists
group.setFrameShape(self.tree.frameShape())
group.setFrameShadow(self.tree.frameShadow())
for view in (self.tree, self.friend_list):
view.setFrameShape(QFrame.Shape.NoFrame)
inner = QVBoxLayout(group)
inner.setContentsMargins(0, 0, 0, 0)
inner.setSpacing(0)
inner.addWidget(self._lists, stretch=1)
self.art = SidebarArt(player)
layout.addWidget(self.art)
inner.addWidget(self.art)
layout.addWidget(group, stretch=1)
# What the header row lines the Library button up with.
self.list_area = group
self.library_button.clicked.connect(self._on_library_clicked)
self.tree.playlist_selected.connect(self._on_playlist_selected)
@@ -305,7 +317,9 @@ class SidebarArt(QWidget):
def paintEvent(self, event):
painter = QPainter(self)
painter.fillRect(self.rect(), self.palette().mid().color())
# A shade lighter than mid: the sidebar group's frame line is drawn
# in mid, and would vanish into a placeholder of the same gray.
painter.fillRect(self.rect(), self.palette().mid().color().lighter(112))
if self._pixmap is None or self._pixmap.isNull():
return
scaled = self._pixmap.scaled(
+6 -2
View File
@@ -276,6 +276,10 @@ class HeaderRow(QWidget):
# lists: every item in the row stands on one floor, BOTTOM px up.
TOP_PAD = 2
BOTTOM = 5
# Text and the playhead have no hard bottom edge, so on the floor itself
# they read as sitting lower than the Library button beside them; this
# lifts them onto the button's bottom line by eye.
LIFT = 2
def __init__(self, seek: QWidget, parent=None):
super().__init__(parent)
@@ -336,7 +340,7 @@ class HeaderRow(QWidget):
self.seek.layout().invalidate()
self.seek.setGeometry(seek_left, self.TOP_PAD,
max(0, panel.right() + 1 - seek_left),
box_h + drop)
box_h + drop - self.LIFT)
header = self.view_header
if header is not None:
width = max(0, seek_left - self.GAP - content_left)
@@ -344,7 +348,7 @@ class HeaderRow(QWidget):
header.setAlignment(Qt.AlignmentFlag.AlignLeft
| Qt.AlignmentFlag.AlignBottom)
header.setGeometry(content_left, self.TOP_PAD, width,
box_h + self._drop(header))
box_h + self._drop(header) - self.LIFT)
else:
header.setGeometry(content_left, self.TOP_PAD, width, box_h)