v0.1.2: transport buttons fill their bubble as equal tap targets

Prev/play/next (and shuffle) used to hug their ~20px glyphs in the middle
of the 62px rounded box, so most of the bubble was dead space. _box() now
takes split=True: the buttons tile the bubble interior in equal shares,
expanding to the (tightened) margins with the glyph centered in each.
Minimum button widths keep the bubbles at their old footprint — no bigger,
no smaller. Round 21 tests cover the equal split, vertical fill, edge
spans, and the preserved footprint.
This commit is contained in:
2026-07-04 17:03:54 -04:00
parent 8e0ba85086
commit abcbff167c
4 changed files with 114 additions and 10 deletions
+27 -8
View File
@@ -90,22 +90,33 @@ class FlashButton(QToolButton):
def _box(*widgets, bg: QColor, margins=(10, 3, 10, 3), hug=False,
height=None) -> QFrame:
height=None, split=False) -> QFrame:
"""A small rounded frame with its content centered inside.
With hug=True the frame stays at its size hint instead of stretching
to fill the row it sits in. height pins the frame's height (width is
left untouched), so several boxes can be lined up to the same height.
bg is the rounded-rectangle fill (a user-tunable grayscale)."""
bg is the rounded-rectangle fill (a user-tunable grayscale).
With split=True the widgets tile the frame's interior in equal shares
instead of hugging their size hints in the middle — each widget becomes
a full-bleed tap target with its content centered in its share."""
frame = QFrame()
frame.setObjectName("transportBox")
frame.setStyleSheet(_box_style(bg))
inner = QHBoxLayout(frame)
inner.setContentsMargins(*margins)
inner.addStretch()
for widget in widgets:
inner.addWidget(widget)
inner.addStretch()
if split:
inner.setSpacing(0)
for widget in widgets:
widget.setSizePolicy(QSizePolicy.Policy.Expanding,
QSizePolicy.Policy.Expanding)
inner.addWidget(widget, stretch=1)
else:
inner.addStretch()
for widget in widgets:
inner.addWidget(widget)
inner.addStretch()
if height is not None:
frame.setFixedHeight(height)
if hug:
@@ -242,15 +253,23 @@ class TransportBar(QWidget):
self._prev_btn = FlashButton("previous")
self._play_btn = FlashButton("play")
self._next_btn = FlashButton("next")
# split=True turns each button into a full-bleed tap target tiling the
# bubble; the minimum widths keep the bubbles at their pre-split
# footprint (the centering stretches/margins used to pad them out).
for btn in (self._prev_btn, self._play_btn, self._next_btn):
btn.setMinimumWidth(36)
transport_box = _box(self._prev_btn, self._play_btn, self._next_btn,
bg=box_bg, height=CONTROL_HEIGHT)
bg=box_bg, margins=(3, 3, 3, 3),
height=CONTROL_HEIGHT, split=True)
self._boxes.append(transport_box)
layout.addWidget(transport_box)
self._shuffle_btn = FlashButton("shuffle")
self._shuffle_btn.setMinimumWidth(50)
self._shuffle_btn.setCheckable(True)
self._shuffle_btn.setToolTip("Shuffle (doesn't change playlist order)")
shuffle_box = _box(self._shuffle_btn, bg=box_bg, height=CONTROL_HEIGHT)
shuffle_box = _box(self._shuffle_btn, bg=box_bg, margins=(3, 3, 3, 3),
height=CONTROL_HEIGHT, split=True)
self._boxes.append(shuffle_box)
layout.addWidget(shuffle_box)