// The shapes that cross between Rust and the UI. // // Everything here is already *presentation*: labels are formatted, durations are // strings, covers are decoded images. Nothing in the .slint files formats a number or // picks a word, so the German copy and the duration format live in one place (Rust) // rather than being split across two languages. // // `nav` is each item's position in the single flat selection order that runs songs -> // categories -> albums, so one pair of arrow keys walks the whole page. It is assigned // in Rust, where the three lists are built together. export struct AlbumTile { id: string, title: string, artist: string, // "12 Songs · 45:03 · 🧸" - already assembled, including the figurine marker. meta: string, cover: image, is-book: bool, locked: bool, // This album is the one playing; drawn with the accent ring rather than the // selection ring, and outranked by it when they coincide. current: bool, nav: int, } // The grid is handed to the UI pre-chunked into rows, because a `ListView` virtualizes // its model and a flat list of 343 cards has no rows to skip. This is the direct // counterpart of the web app's `content-visibility: auto` on `.grid > .card`, which // exists for exactly the same measurement: 340 live cards saturated the Pi's renderer. export struct GridRow { tiles: [AlbumTile], } export struct CategoryTile { key: string, // "7 Hörbücher" count-label: string, // Up to four covers in a 2x2, or one filling the tile when the category holds a // single album. Four fields rather than an array: the count is fixed and small, and // this keeps the tile a plain struct. cover1: image, cover2: image, cover3: image, cover4: image, cover-count: int, is-book: bool, nav: int, } export struct CategoryRow { tiles: [CategoryTile], } // One of the three shelves on the root screen. export struct Shelf { label: string, icon: string, tiles: [CategoryTile], empty-label: string, } export struct TrackRow { title: string, subtitle: string, duration: string, cover: image, is-book: bool, current: bool, locked: bool, album-id: string, index: int, nav: int, } // What the player bar and the full-screen view both say. Shared so the two cannot // drift apart on a copy change. export struct NowPlaying { title: string, subtitle: string, // "Song 3 von 8" / "Kapitel 3 von 8" counter: string, cover: image, hero-cover: image, is-book: bool, has-album: bool, // "−4:12", the time left in this track. clock-label: string, // "Noch 38:20 im Album" - empty for a podcast, where it means nothing. remaining-label: string, }