Files
qbz/crates/qbz-qt/qml/views/local/FolderSubcard.qml
T
vicrodh ed7fa588ea fix(qt): elevated controls lift on hover instead of darkening
Buttons that rest on surfaceElevated used surfaceHover for their hover
fill: a 6% white wash meant for rows that rest transparent. Over an
elevated button it lands DARKER than the rest fill — on a modal's dark
ground the Cancel/Save/footer buttons went near-black under the pointer.

QbzTheme gains surfaceElevatedHover (a lift of surfaceElevated, derived
so every palette has it), its ambient half-alpha twin, and the
elevatedFill / elevatedHoverFill pair an ambient-aware control paints.
Every site with the old pairing (65 across modals, toolbars, selects,
circle actions, chips and cards) now hovers to the lift.

cc
2026-09-14 00:49:54 -06:00

116 lines
4.0 KiB
QML

// Subfolder cover card for the tree-mode folder-detail pane
// (LocalLibraryView.slint:57 FolderSubcard). Bordered card (radius 6, accent
// border on hover), square cover = card width - 16 with a folder placeholder,
// name 13px/medium, recursive track count 11px/muted. Click drills in.
// Right-click opens the same folder queue menu the tree rows carry (a
// deliberate divergence — the Slint card has no menu; see TreeRow.qml).
import QtQuick
import com.blitzfc.qbz
import "../../controls"
import "../../theme"
Rectangle {
id: root
property var item: ({})
/// Resolved cover for item.artKey (the host's artMap lookup).
property string artSource: ""
/// The LocalLibraryView root (shared skeleton pulse + artwork gate).
property var view: null
signal opened()
QbzTheme { id: theme }
radius: 6
border.width: 1
border.color: cardArea.containsMouse ? theme.accent : theme.borderSubtle
color: cardArea.containsMouse ? theme.surfaceElevatedHover : theme.surfaceElevated
Column {
anchors.fill: parent
anchors.margins: 8
spacing: 6
Rectangle {
width: parent.width
height: parent.width
radius: 4
color: theme.surfaceMain
clip: true
QbzIcon {
name: "folder"
width: 32
height: 32
anchors.centerIn: parent
tintName: "muted"
}
RoundedImage {
gridArtwork: true
id: subcardArt
anchors.fill: parent
source: root.artSource
radius: 4
}
// Per-item cover placeholder — hands over when the art is on the
// canvas, not when the path lands; settles out when the folder
// has none (local artwork resolution drops keys with no cover).
QbzSkeleton {
variant: "art"
anchors.fill: parent
blockRadius: 4
pending: root.view ? root.view.artWanted(root.item.artKey) : false
coverReady: subcardArt.ready
phase: root.view ? root.view.skelPhase : false
settleMs: root.view ? root.view.artSettleMs : 0
settleHold: root.view ? root.view.artPulse : false
}
}
Text {
width: parent.width
text: root.item.name || ""
color: theme.textPrimary
font.pixelSize: 13
font.weight: theme.weightMedium
elide: Text.ElideRight
}
Text {
width: parent.width
text: (root.item.trackCount || 0) + " "
+ QbzSession.tr("tracks", QbzSession.trRev)
color: theme.textMuted
font.pixelSize: 11
elide: Text.ElideRight
}
}
MouseArea {
id: cardArea
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: Qt.PointingHandCursor
onClicked: function (mouse) {
if (mouse.button === Qt.RightButton) {
folderMenu.openAtCursor(cardArea, mouse.x, mouse.y)
return
}
root.opened()
}
}
CardMenu {
id: folderMenu
menuWidth: 200
entries: [
{ "label": QbzSession.tr("Play", QbzSession.trRev), "icon": "play-fill", "action": "play" },
{ "label": QbzSession.tr("Play next", QbzSession.trRev), "icon": "list-start", "action": "next" },
{ "label": QbzSession.tr("Play later", QbzSession.trRev), "icon": "list-plus", "action": "later" },
{ "label": QbzSession.tr("Add to queue", QbzSession.trRev), "icon": "list-end", "action": "queue" },
]
onPicked: function (a) {
if (a === "play") QbzLocal.playFolder(root.item.path)
else QbzLocal.enqueue("folder", root.item.path, a)
}
}
}