Files
qbz/crates/qbz-qt/qml/views/playlistmanager/PmFolderCard.qml
T
vicrodh c7a3012955 feat(local-library): complete catalog and metadata workflows
Add bounded native library models, complete grouping rails and scan progress. Bring source-aware metadata editing, media information and collection offline preflight to Qt, and repair inherited Plex album artwork without overriding healthy tokens.

cx
2026-08-28 18:50:05 -06:00

121 lines
4.2 KiB
QML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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.surfaceHover : 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()
}
}
}