feat(qt): overAmbient legibility mode for the quality badge and track info
Immersive surfaces sit directly on the ambient field, where theme tokens have no contrast guarantee — a light cover washed the split Track Info panel and the quality badges out completely. QualityBadgeFull, TrackInfoBody, InfoMetaCell and InfoCreditCell gain an opt-in overAmbient mode: fixed light text with the restrained native shadow the lyrics surfaces already use, and the badge swaps the theme surface for its own translucent dark scrim covering only the chip. Defaults stay off, so the desktop modal and every themed mount are untouched. The immersive Track Info panel and song card opt in. cc
This commit is contained in:
6 files changed
+90
-22
No files matched your search
@@ -19,6 +19,10 @@ Column {
|
||||
/// dictating its width.
|
||||
property int colW: 280
|
||||
|
||||
/// Immersive-panel legibility mode (see TrackInfoBody.qml): fixed light
|
||||
/// colors + native shadow instead of the theme tokens.
|
||||
property bool overAmbient: false
|
||||
|
||||
signal nameClicked(string name, string roleRaw)
|
||||
|
||||
QbzTheme { id: theme }
|
||||
@@ -29,7 +33,9 @@ Column {
|
||||
Text {
|
||||
width: cc.colW
|
||||
text: cc.cell ? (cc.cell.role || "") : ""
|
||||
color: theme.textMuted
|
||||
color: cc.overAmbient ? "#b3ffffff" : theme.textMuted
|
||||
style: cc.overAmbient ? Text.Raised : Text.Normal
|
||||
styleColor: "#b0000000"
|
||||
font.pixelSize: 11
|
||||
font.weight: theme.weightSemibold
|
||||
font.letterSpacing: 0.5
|
||||
@@ -49,7 +55,10 @@ Column {
|
||||
id: nameText
|
||||
width: cc.colW
|
||||
text: nameRow.modelData
|
||||
color: nameArea.containsMouse ? theme.accent : theme.textPrimary
|
||||
color: nameArea.containsMouse ? theme.accent
|
||||
: (cc.overAmbient ? "#f2ffffff" : theme.textPrimary)
|
||||
style: cc.overAmbient ? Text.Raised : Text.Normal
|
||||
styleColor: "#b0000000"
|
||||
font.pixelSize: 14
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ Column {
|
||||
id: mc
|
||||
property string label: ""
|
||||
property int cellWidth: 0
|
||||
/// Immersive-panel legibility mode (see TrackInfoBody.qml): fixed light
|
||||
/// label + native shadow instead of the theme token.
|
||||
property bool overAmbient: false
|
||||
|
||||
QbzTheme { id: theme }
|
||||
|
||||
@@ -28,7 +31,9 @@ Column {
|
||||
Text {
|
||||
width: mc.cellWidth
|
||||
text: mc.label
|
||||
color: theme.textMuted
|
||||
color: mc.overAmbient ? "#b3ffffff" : theme.textMuted
|
||||
style: mc.overAmbient ? Text.Raised : Text.Normal
|
||||
styleColor: "#b0000000"
|
||||
font.pixelSize: 11
|
||||
font.weight: theme.weightSemibold
|
||||
font.letterSpacing: 0.5
|
||||
|
||||
@@ -24,6 +24,18 @@ Column {
|
||||
|
||||
QbzTheme { id: theme }
|
||||
|
||||
/// Legibility mode for the immersive split panel (2026-08-31 visual
|
||||
/// cleanup): there the body sits directly on the ambient field, where
|
||||
/// theme tokens have no contrast guarantee over a light cover. On, every
|
||||
/// text uses a fixed light color plus the restrained native shadow the
|
||||
/// lyrics surfaces use. The desktop modal keeps the theme (default off).
|
||||
property bool overAmbient: false
|
||||
readonly property color cPrimary: overAmbient ? "#f2ffffff" : theme.textPrimary
|
||||
readonly property color cMuted: overAmbient ? "#b3ffffff" : theme.textMuted
|
||||
readonly property color cRule: overAmbient ? "#2effffff" : theme.surfaceElevated
|
||||
readonly property int cStyle: overAmbient ? Text.Raised : Text.Normal
|
||||
readonly property color cShadow: "#b0000000"
|
||||
|
||||
readonly property var doc: host ? host.doc : ({})
|
||||
|
||||
// ---- Loading ---------------------------------------------------------
|
||||
@@ -36,7 +48,9 @@ Column {
|
||||
anchors.centerIn: parent
|
||||
width: Math.max(0, parent.width - 120)
|
||||
text: QbzSession.tr("Loading track info...", QbzSession.trRev)
|
||||
color: theme.textMuted
|
||||
color: body.cMuted
|
||||
style: body.cStyle
|
||||
styleColor: body.cShadow
|
||||
font.pixelSize: theme.fontBody
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
@@ -55,14 +69,18 @@ Column {
|
||||
Text {
|
||||
width: parent.width
|
||||
text: QbzSession.tr("Failed to load track info", QbzSession.trRev)
|
||||
color: theme.textMuted
|
||||
color: body.cMuted
|
||||
style: body.cStyle
|
||||
styleColor: body.cShadow
|
||||
font.pixelSize: theme.fontBody
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
Text {
|
||||
width: parent.width
|
||||
text: body.host ? body.host.errorText : ""
|
||||
color: theme.textMuted
|
||||
color: body.cMuted
|
||||
style: body.cStyle
|
||||
styleColor: body.cShadow
|
||||
font.pixelSize: theme.fontLegal
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
@@ -99,7 +117,9 @@ Column {
|
||||
Text {
|
||||
width: parent.width
|
||||
text: body.doc.title || ""
|
||||
color: theme.textPrimary
|
||||
color: body.cPrimary
|
||||
style: body.cStyle
|
||||
styleColor: body.cShadow
|
||||
font.pixelSize: 16
|
||||
font.weight: theme.weightSemibold
|
||||
wrapMode: Text.WordWrap
|
||||
@@ -108,7 +128,9 @@ Column {
|
||||
visible: (body.doc.album || "") !== ""
|
||||
width: parent.width
|
||||
text: body.doc.album || ""
|
||||
color: theme.textMuted
|
||||
color: body.cMuted
|
||||
style: body.cStyle
|
||||
styleColor: body.cShadow
|
||||
font.pixelSize: theme.fontLegal
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
@@ -121,7 +143,9 @@ Column {
|
||||
id: artistText
|
||||
text: body.doc.artist || ""
|
||||
color: (body.doc.artistId || "") !== ""
|
||||
? theme.accent : theme.textPrimary
|
||||
? theme.accent : body.cPrimary
|
||||
style: body.cStyle
|
||||
styleColor: body.cShadow
|
||||
font.pixelSize: 16
|
||||
font.weight: theme.weightSemibold
|
||||
}
|
||||
@@ -149,7 +173,9 @@ Column {
|
||||
width: 18
|
||||
height: 18
|
||||
anchors.centerIn: parent
|
||||
tintName: closeArea.containsMouse ? "textPrimary" : "muted"
|
||||
tintName: body.overAmbient
|
||||
? (closeArea.containsMouse ? "white" : "muted")
|
||||
: (closeArea.containsMouse ? "textPrimary" : "muted")
|
||||
}
|
||||
MouseArea {
|
||||
id: closeArea
|
||||
@@ -177,22 +203,28 @@ Column {
|
||||
spacing: 24
|
||||
InfoMetaCell {
|
||||
cellWidth: loadedCol.metaColW
|
||||
overAmbient: body.overAmbient
|
||||
label: QbzSession.tr("Duration", QbzSession.trRev)
|
||||
Text {
|
||||
width: loadedCol.metaColW
|
||||
text: body.doc.duration || ""
|
||||
color: theme.textPrimary
|
||||
color: body.cPrimary
|
||||
style: body.cStyle
|
||||
styleColor: body.cShadow
|
||||
font.pixelSize: 14
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
InfoMetaCell {
|
||||
cellWidth: loadedCol.metaColW
|
||||
overAmbient: body.overAmbient
|
||||
label: QbzSession.tr("Quality", QbzSession.trRev)
|
||||
Text {
|
||||
width: loadedCol.metaColW
|
||||
text: body.doc.quality || ""
|
||||
color: theme.textPrimary
|
||||
color: body.cPrimary
|
||||
style: body.cStyle
|
||||
styleColor: body.cShadow
|
||||
font.pixelSize: 14
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
@@ -202,11 +234,14 @@ Column {
|
||||
InfoMetaCell {
|
||||
visible: (body.doc.isrc || "") !== ""
|
||||
cellWidth: loadedCol.metaColW
|
||||
overAmbient: body.overAmbient
|
||||
label: "ISRC"
|
||||
Text {
|
||||
width: loadedCol.metaColW
|
||||
text: body.doc.isrc || ""
|
||||
color: theme.textMuted
|
||||
color: body.cMuted
|
||||
style: body.cStyle
|
||||
styleColor: body.cShadow
|
||||
font.pixelSize: 14
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
@@ -228,6 +263,7 @@ Column {
|
||||
spacing: 24
|
||||
InfoMetaCell {
|
||||
cellWidth: loadedCol.metaColW
|
||||
overAmbient: body.overAmbient
|
||||
label: QbzSession.tr("Label", QbzSession.trRev)
|
||||
Item {
|
||||
width: loadedCol.metaColW
|
||||
@@ -238,7 +274,9 @@ Column {
|
||||
text: body.doc.label || ""
|
||||
color: (labelArea.containsMouse
|
||||
&& (body.doc.labelId || "") !== "")
|
||||
? theme.accent : theme.textPrimary
|
||||
? theme.accent : body.cPrimary
|
||||
style: body.cStyle
|
||||
styleColor: body.cShadow
|
||||
font.pixelSize: 14
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
@@ -265,7 +303,7 @@ Column {
|
||||
visible: body.host && body.host.credits.length > 0
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: theme.surfaceElevated
|
||||
color: body.cRule
|
||||
}
|
||||
Item {
|
||||
visible: body.host && body.host.credits.length > 0
|
||||
@@ -284,6 +322,7 @@ Column {
|
||||
delegate: InfoCreditCell {
|
||||
required property var modelData
|
||||
colW: loadedCol.creditsColW
|
||||
overAmbient: body.overAmbient
|
||||
cell: modelData
|
||||
onNameClicked: function (n, r) { body.host.openMusician(n, r) }
|
||||
}
|
||||
@@ -297,6 +336,7 @@ Column {
|
||||
delegate: InfoCreditCell {
|
||||
required property var modelData
|
||||
colW: loadedCol.creditsColW
|
||||
overAmbient: body.overAmbient
|
||||
cell: modelData
|
||||
onNameClicked: function (n, r) { body.host.openMusician(n, r) }
|
||||
}
|
||||
@@ -314,7 +354,7 @@ Column {
|
||||
visible: (body.doc.copyright || "") !== ""
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: theme.surfaceElevated
|
||||
color: body.cRule
|
||||
}
|
||||
Item {
|
||||
visible: (body.doc.copyright || "") !== ""
|
||||
@@ -325,7 +365,9 @@ Column {
|
||||
visible: (body.doc.copyright || "") !== ""
|
||||
width: parent.width
|
||||
text: body.doc.copyright || ""
|
||||
color: theme.textMuted
|
||||
color: body.cMuted
|
||||
style: body.cStyle
|
||||
styleColor: body.cShadow
|
||||
font.pixelSize: 12
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user