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
129 lines
4.8 KiB
QML
129 lines
4.8 KiB
QML
// PmFolderChip — the LIST-mode folder cell (PlaylistManagerView.slint:380-466).
|
|
// 52 px tall, r8, elevated → surface-hover, 0.6 opacity while hidden. The mount
|
|
// forces `width: 184` (`:1382`) so every cell in the wrapping grid has the same
|
|
// pitch; the component's own intrinsic width is never used.
|
|
//
|
|
// The body enters the folder; only the pencil opens the folder editor.
|
|
//
|
|
// Two hover-revealed children — the count and the pencil — at opacity 0/1 with
|
|
// the reference's 150 ms fade. OPACITY, not visibility: the count keeps its
|
|
// layout slot at all times (the same trap qml/shell/Sidebar.qml:996-1008
|
|
// documents). Hover is the reference's OR over the chip's and the pencil's own
|
|
// areas (`:437`), because the pencil's MouseArea sits above the chip's and would
|
|
// otherwise steal `containsMouse` from under the pointer.
|
|
//
|
|
// LAYOUT DEVIATION, stated: the reference is a `HorizontalLayout` whose
|
|
// children are content-sized inside a container the mount widens to 184, so
|
|
// Slint distributes the slack through the wrapper layouts. QML has no
|
|
// equivalent distribution here, so the icon + name + count are content-packed
|
|
// from the left gutter and the pencil is pinned to the right gutter — which is
|
|
// where a 24 px hover affordance belongs in a fixed-pitch chip. Every metric
|
|
// (12/12 padding, spacing 8, icon 36/glyph 20/r8, name 13/500 capped at 120 and
|
|
// elided, count 11) is the reference's.
|
|
|
|
import QtQuick
|
|
import com.blitzfc.qbz
|
|
import "../../controls"
|
|
import "../../theme"
|
|
|
|
Rectangle {
|
|
id: root
|
|
|
|
/// One `QbzPlaylistManager.foldersJson` entry (contract §4.1).
|
|
property var folder: ({})
|
|
signal openRequested()
|
|
signal editRequested()
|
|
|
|
QbzTheme { id: theme }
|
|
|
|
readonly property bool hot: chipArea.containsMouse || pencilArea.containsMouse
|
|
|
|
height: 52
|
|
radius: 8
|
|
color: chipArea.containsMouse ? theme.surfaceElevatedHover : theme.surfaceElevated
|
|
opacity: (root.folder.isHidden === true) ? 0.6 : 1.0
|
|
|
|
Row {
|
|
id: chipRow
|
|
x: 12
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 8
|
|
|
|
PmFolderIcon {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
size: 36
|
|
iconPreset: root.folder.iconPreset || "folder"
|
|
iconColor: root.folder.iconColor || ""
|
|
hasColor: root.folder.hasColor === true
|
|
hasCustomImage: root.folder.hasCustomImage === true
|
|
customImagePath: root.folder.customImagePath || ""
|
|
}
|
|
Text {
|
|
id: nameText
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
// `max-width: 120px` + elide (`:415`), clamped to what is left
|
|
// between the icon and the right-gutter pencil.
|
|
width: Math.max(0, Math.min(120,
|
|
root.width - 12 - 36 - 8 - 8 - countText.width - 8 - 24 - 12))
|
|
text: root.folder.name || ""
|
|
color: theme.textPrimary
|
|
font.pixelSize: 13
|
|
font.weight: theme.weightMedium
|
|
verticalAlignment: Text.AlignVCenter
|
|
elide: Text.ElideRight
|
|
}
|
|
Text {
|
|
id: countText
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
// The raw integer, not the pluralised string the CARD renders
|
|
// (`:422`).
|
|
text: root.folder.count === undefined ? "0" : String(root.folder.count)
|
|
color: theme.textMuted
|
|
font.pixelSize: 11
|
|
verticalAlignment: Text.AlignVCenter
|
|
opacity: root.hot ? 1.0 : 0.0
|
|
Behavior on opacity { NumberAnimation { duration: 150 } }
|
|
}
|
|
}
|
|
|
|
// The body area stops 32 px short of the right edge — the pencil's gutter
|
|
// (`:459`).
|
|
MouseArea {
|
|
id: chipArea
|
|
anchors.left: parent.left
|
|
anchors.top: parent.top
|
|
anchors.bottom: parent.bottom
|
|
width: Math.max(0, parent.width - 32)
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onClicked: root.openRequested()
|
|
}
|
|
|
|
Rectangle {
|
|
x: parent.width - width - 12
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: 24
|
|
height: 24
|
|
radius: 4
|
|
opacity: root.hot ? 1.0 : 0.0
|
|
Behavior on opacity { NumberAnimation { duration: 150 } }
|
|
// TRANSPARENT at rest here, unlike the card's elevated plate (`:439`).
|
|
color: pencilArea.containsMouse ? theme.surfaceCard : "transparent"
|
|
|
|
QbzIcon {
|
|
anchors.centerIn: parent
|
|
name: "pen-line"
|
|
width: 12
|
|
height: 12
|
|
tintName: pencilArea.containsMouse ? "textPrimary" : "muted"
|
|
}
|
|
MouseArea {
|
|
id: pencilArea
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onClicked: root.editRequested()
|
|
}
|
|
}
|
|
}
|