feat(qbz-qt): Large NPB dock — sidebar space reservation + FFT spectrum band
The Large dock was a bare cover overlay: the sidebar knew nothing about it, so the playlist rows kept running to the sidebar's bottom edge and sat underneath the album art. Sidebar.slint reserves the in-sidebar portion of the dock; the port had dropped that. Reserve it the same way, from a single source of truth. QbzShell gains largeDockHeight (shell_bridge.rs owns the arithmetic: 9 top + band + gap + 208 art + 4 bottom), the sidebar subtracts largeDockHeight - npbLargeHeight from the playlist list, and AppShell pins the overlay at height - largeDockHeight. The 112px bar height becomes a theme token so the shell and the reservation cannot drift apart. The band the cover was missing needs the FFT tap, so wire it: the runtime is built with_visualizer, viz_qt.rs runs the frontend-agnostic producer from qbz-audio and drains it at 30fps into a new QbzViz domain bridge as typed QList<f32>. Bars (28 mirrored columns over the 14 active bins), Waveform (48 downsampled L columns) and Energy (5 bands) render as Slint does, the cover's eye button toggles the band, clicking it cycles the mode, and both persist to ui_prefs. Cost is zero when unused: the tap starts disabled, the eye toggle gates capture, the drain thread parks while off, and the transport is mirrored so a paused player parks the producer instead of re-analyzing a stale buffer. The QML binds bar HEIGHTS against static-model Repeaters — the lists are replaced per frame, so a model binding would rebuild every delegate 30 times a second. Adds the eye/eye-off icon pair to the seven baked tint variants. 18/18 tests; offscreen smoke clean (0 QML errors, home published). cc
This commit is contained in:
27 files changed
+978
-45
No files matched your search
@@ -32,6 +32,21 @@ Rectangle {
|
||||
property bool searchOpen: false
|
||||
property bool playlistsCollapsed: false
|
||||
property string activePlaylistId: ""
|
||||
// ---- Large-NPB dock space reservation -------------------------------
|
||||
// The cover+spectrum dock is an AppShell-ROOT overlay pinned flush to the
|
||||
// WINDOW bottom-left, so it extends the bar's height BELOW this sidebar
|
||||
// (which stops at npb.top). Only the IN-SIDEBAR portion has to be
|
||||
// reserved, and it shrinks when the band is hidden — that is why the
|
||||
// height comes from the bridge and not a literal.
|
||||
//
|
||||
// Without this the playlist list keeps running to the sidebar's bottom
|
||||
// edge and the rows sit UNDER the album art (Sidebar.slint:1145 reserves
|
||||
// the same way).
|
||||
readonly property bool largeDockActive: QbzShell.npbMode === 3 && QbzShell.sidebarState === 0
|
||||
readonly property real dockReserve: largeDockActive
|
||||
? Math.max(0, QbzShell.largeDockHeight - theme.npbLargeHeight)
|
||||
: 0
|
||||
|
||||
// Flattened entries from the bridge + the url-keyed cover map.
|
||||
readonly property var entries: parseEntries(QbzShell.sidebarJson)
|
||||
property var coverMap: ({})
|
||||
@@ -447,7 +462,10 @@ Rectangle {
|
||||
Item {
|
||||
visible: !root.playlistsCollapsed
|
||||
width: parent.width
|
||||
height: parent.height - y - 16
|
||||
// `root.dockReserve` keeps the rows clear of the Large-NPB cover
|
||||
// (0 in every other mode). Clamped so a short window shrinks the
|
||||
// list to nothing instead of giving it a negative height.
|
||||
height: Math.max(0, parent.height - y - 16 - root.dockReserve)
|
||||
|
||||
Flickable {
|
||||
id: plFlick
|
||||
|
||||
Reference in new issue
Block a user