// Playlist Manager cover collage — a square thumbnail of a playlist's // track covers, mirroring Tauri's PlaylistCollage: // - 0 covers -> fallback list-music glyph // - 1-3 covers -> a single full-bleed cover // - 4+ covers -> a 2x2 grid (1px gap) // // The covers + decoded images live on the PmPlaylistItem (cover-count, // cover1..cover4). This component only lays them out. import { Theme } from "../foundation/semantic-colors.slint"; import { Radius } from "../foundation/radius.slint"; import { PmPlaylistItem } from "../state.slint"; import { QbzIcon } from "QbzIcon.slint"; export component PmCollage inherits Rectangle { in property item; in property size: 140px; in property radius: Radius.sm; width: root.size; height: root.size; border-radius: root.radius; clip: true; background: Theme.surface-elevated; property n: root.item.cover-count; property gap: 1px; // 0 covers -> fallback glyph. if root.n == 0: QbzIcon { source: @image-url("../assets/icons/list-music.svg"); width: root.size * 0.32; height: root.size * 0.32; x: Math.round((parent.width - self.width) / 2 / 1px) * 1px; y: Math.round((parent.height - self.height) / 2 / 1px) * 1px; tint: Theme.text-muted; } // 1-3 covers -> single full-bleed cover. if root.n >= 1 && root.n < 4: Image { width: 100%; height: 100%; source: root.item.cover1; image-fit: cover; } // 4+ covers -> 2x2 grid. if root.n >= 4: VerticalLayout { spacing: root.gap; HorizontalLayout { spacing: root.gap; Image { source: root.item.cover1; image-fit: cover; width: (root.size - root.gap) / 2; height: (root.size - root.gap) / 2; } Image { source: root.item.cover2; image-fit: cover; width: (root.size - root.gap) / 2; height: (root.size - root.gap) / 2; } } HorizontalLayout { spacing: root.gap; Image { source: root.item.cover3; image-fit: cover; width: (root.size - root.gap) / 2; height: (root.size - root.gap) / 2; } Image { source: root.item.cover4; image-fit: cover; width: (root.size - root.gap) / 2; height: (root.size - root.gap) / 2; } } } }