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
121 lines
4.2 KiB
QML
121 lines
4.2 KiB
QML
// PmFolderCard — the GRID-mode folder cell (PlaylistManagerView.slint:291-373).
|
||
// 160 × 150, r10, elevated → surface-hover on body hover, 0.6 opacity while the
|
||
// folder is hidden (the ONLY hidden affordance on a folder — no eye glyph, no
|
||
// badge).
|
||
//
|
||
// The body enters the folder in the current grid/list presentation. Only the
|
||
// top-right pencil opens the editor; conflating the two made ordinary folder
|
||
// navigation impossible (owner correction, 2026-08-28).
|
||
//
|
||
// Hover semantics are the reference's OR (`ta.has-hover || edit-ta.has-hover`,
|
||
// `:349`): the pencil's own MouseArea sits above the card's and would otherwise
|
||
// steal `containsMouse`, dropping the pencil to opacity 0 under the pointer
|
||
// while it still accepts the click. Declaration order is z-order in QML and
|
||
// `propagateComposedEvents` does not rescue `pressed`, so the pencil is
|
||
// declared AFTER the card's MouseArea, deliberately.
|
||
|
||
import QtQuick
|
||
import com.blitzfc.qbz
|
||
import "../../controls"
|
||
import "../../theme"
|
||
|
||
Rectangle {
|
||
id: root
|
||
|
||
/// One `QbzPlaylistManager.foldersJson` entry (contract §4.1).
|
||
property var folder: ({})
|
||
/// Body navigation and pencil editing are deliberately distinct targets.
|
||
signal openRequested()
|
||
signal editRequested()
|
||
|
||
QbzTheme { id: theme }
|
||
|
||
readonly property bool hot: cardArea.containsMouse || pencilArea.containsMouse
|
||
|
||
width: 160
|
||
height: 150
|
||
radius: 10
|
||
color: cardArea.containsMouse ? theme.surfaceElevatedHover : theme.surfaceElevated
|
||
opacity: (root.folder.isHidden === true) ? 0.6 : 1.0
|
||
|
||
// padding 16 / spacing 8 / centred column.
|
||
Column {
|
||
anchors.centerIn: parent
|
||
width: parent.width - 32
|
||
spacing: 8
|
||
|
||
PmFolderIcon {
|
||
anchors.horizontalCenter: parent.horizontalCenter
|
||
size: 64
|
||
iconPreset: root.folder.iconPreset || "folder"
|
||
iconColor: root.folder.iconColor || ""
|
||
hasColor: root.folder.hasColor === true
|
||
hasCustomImage: root.folder.hasCustomImage === true
|
||
customImagePath: root.folder.customImagePath || ""
|
||
}
|
||
Text {
|
||
width: parent.width
|
||
height: 18
|
||
text: root.folder.name || ""
|
||
color: theme.textPrimary
|
||
font.pixelSize: 13
|
||
font.weight: theme.weightMedium
|
||
horizontalAlignment: Text.AlignHCenter
|
||
verticalAlignment: Text.AlignVCenter
|
||
elide: Text.ElideRight
|
||
}
|
||
Text {
|
||
width: parent.width
|
||
// Rust never pluralises this one — the reference picks the string in
|
||
// the markup (`:332-334`), so the two msgids are resolved here. An
|
||
// empty folder reads "0 playlists"; there is no empty state.
|
||
text: (root.folder.count === 1)
|
||
? QbzSession.tr("1 playlist", QbzSession.trRev)
|
||
: QbzSession.tr("{} playlists", QbzSession.trRev)
|
||
.replace("{}", root.folder.count || 0)
|
||
color: theme.textMuted
|
||
font.pixelSize: 12
|
||
horizontalAlignment: Text.AlignHCenter
|
||
elide: Text.ElideRight
|
||
}
|
||
}
|
||
|
||
MouseArea {
|
||
id: cardArea
|
||
anchors.fill: parent
|
||
hoverEnabled: true
|
||
cursorShape: Qt.PointingHandCursor
|
||
onClicked: root.openRequested()
|
||
}
|
||
|
||
// Hover pencil, top-right. Declared after the card area so it wins the
|
||
// press (see the header).
|
||
Rectangle {
|
||
x: parent.width - width - 8
|
||
y: 8
|
||
width: 24
|
||
height: 24
|
||
radius: 4
|
||
opacity: root.hot ? 1.0 : 0.0
|
||
Behavior on opacity { NumberAnimation { duration: 150 } }
|
||
// Goes DARKER than the card on its own hover — deliberate upstream
|
||
// (`:351`).
|
||
color: pencilArea.containsMouse ? theme.surfaceCard : theme.surfaceElevated
|
||
|
||
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()
|
||
}
|
||
}
|
||
}
|