- AlbumReactivePanel: drop the eight 100ms Behaviors on 30 Hz data (a retriggered Behavior animates at display rate and every animation frame is a full-window present), and read the settle — not the publishing bridge list — in the energy formulas (the .length guard re-evaluated the visual bindings on every FFT publish). - LyricsSyncEngine: the fast cadence rides the pulse; the 250 ms idle re-check keeps its own timer. - EqualizerBars: the phase accumulates on the pulse and the 'active' gate is host-provided (invisible subtrees still dirty the window). Measured on the owner's machine, immersive reactive panel open: 132 -> ~33 presents/s, 83% -> ~25% GPU. km
111 lines
3.8 KiB
QML
111 lines
3.8 KiB
QML
// ImmersiveTrackMeta — the homologated immersive track-info block (§6.7 of
|
|
// the 2026-08-02 immersive-port contract), port of ImmersiveTrackInfo in
|
|
// crates/qbz-ui/ui/immersive/ImmersiveTrackInfo.slint:78-143.
|
|
//
|
|
// HOMOLOGATED look/spacing across AlbumReactive / Static / Coverflow (and the
|
|
// SPLIT left column, §5.6): spacing 6px, the "Now Playing" indicator padded
|
|
// 8px below, the quality badge padded 12px above, fonts 28/18/14.
|
|
//
|
|
// Every row reads QbzPlayer.np* (the Slint block reads NowPlayingState):
|
|
// "Now Playing" + EqualizerBars — VISIBLE ONLY WHILE npPlaying (:85,:100)
|
|
// title 28px/700 elide center (:106-113)
|
|
// artist 18px #ffffffb3 elide center (:116-122)
|
|
// album 14px italic #ffffff80, only when non-empty (:125-132)
|
|
// QualityBadgeFull (tier + detail), self-hides when tier == "" (:135-141)
|
|
//
|
|
// The Slint root is a VerticalLayout with alignment: center — the Qt twin is
|
|
// a Column whose width the MOUNT sets (every B3 mount passes the panel width)
|
|
// and whose rows center themselves horizontally.
|
|
|
|
import QtQuick
|
|
import com.blitzfc.qbz
|
|
import "../controls"
|
|
|
|
Column {
|
|
id: root
|
|
|
|
/// Equalizer tint + "Now Playing" label color (Slint equalizer-tint).
|
|
property color equalizerTint: "#7c3aed"
|
|
|
|
spacing: 6
|
|
|
|
// "Now Playing" indicator: equalizer bars + label, shown only while
|
|
// playing (:85-103). The Slint HorizontalLayout carries padding-bottom 8
|
|
// — the wrapper Item's +8 height is that padding.
|
|
Item {
|
|
visible: QbzPlayer.npPlaying
|
|
width: parent.width
|
|
height: visible ? npRow.implicitHeight + 8 : 0
|
|
Row {
|
|
id: npRow
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
spacing: 8
|
|
height: 14
|
|
EqualizerBars {
|
|
tint: root.equalizerTint
|
|
// The gate lives at the mount (EqualizerBars.qml explains
|
|
// why): this host sits inside the always-mounted ImmersiveView.
|
|
active: QbzImmersive.open
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
Text {
|
|
text: QbzSession.tr("Now Playing", QbzSession.trRev)
|
|
color: root.equalizerTint
|
|
font.pixelSize: 12
|
|
font.weight: Font.DemiBold
|
|
font.letterSpacing: 0.5
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
}
|
|
}
|
|
|
|
// Track title (:106-113).
|
|
Text {
|
|
width: parent.width
|
|
text: QbzPlayer.npTitle
|
|
color: "#ffffff"
|
|
font.pixelSize: 28
|
|
font.weight: Font.Bold
|
|
horizontalAlignment: Text.AlignHCenter
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
// Artist (:116-122). Slint #ffffffb3 (RRGGBBAA) -> #b3ffffff.
|
|
Text {
|
|
width: parent.width
|
|
text: QbzPlayer.npArtist
|
|
color: "#b3ffffff"
|
|
font.pixelSize: 18
|
|
horizontalAlignment: Text.AlignHCenter
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
// Album (italic, dimmer), only when present (:125-132).
|
|
Text {
|
|
visible: QbzPlayer.npAlbum !== ""
|
|
width: parent.width
|
|
text: QbzPlayer.npAlbum
|
|
color: "#80ffffff"
|
|
font.pixelSize: 14
|
|
font.italic: true
|
|
horizontalAlignment: Text.AlignHCenter
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
// Quality badge, centered, padding-top 12 (:135-141). Self-hides when
|
|
// tier == "" (QualityBadgeFull's own gate) — the wrapper collapses with
|
|
// it so the 12px pad vanishes too.
|
|
Item {
|
|
visible: QbzPlayer.npQualityTier !== ""
|
|
width: parent.width
|
|
height: visible ? badge.implicitHeight + 12 : 0
|
|
QualityBadgeFull {
|
|
id: badge
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
anchors.bottom: parent.bottom
|
|
tier: QbzPlayer.npQualityTier
|
|
detail: QbzPlayer.npQualityDetail
|
|
}
|
|
}
|
|
}
|