// QBZ Slint MVP — UI entry point. // // Stays thin: imports the feature screens and exports the single // top-level window. No raw visual constants or domain logic here // (MVP ADR, sections 13 and 21). // Bundles + registers the Inter 18pt faces (compile-time embed) so the // app can render with Inter — see the FONT_TEST_INTER toggle in main.rs. import "assets/fonts/Inter_18pt-Regular.ttf"; import "assets/fonts/Inter_18pt-Medium.ttf"; import "assets/fonts/Inter_18pt-SemiBold.ttf"; import "assets/fonts/Inter_18pt-Bold.ttf"; import { Theme } from "foundation/semantic-colors.slint"; import { SplashScreen } from "splash/SplashScreen.slint"; import { LoginScreen } from "login/LoginScreen.slint"; import { AppShell } from "shell/AppShell.slint"; import { Toast } from "primitives/Toast.slint"; // Re-export the state globals so the Rust layer can populate them. export { HomeState, HomeActions, DiscoverBrowseState, DiscoverBrowseActions, ForYouState, MixState, GenreFilterState, GenreFilterActions, AlbumState, ArtistState, NavState, ShellState, SessionState, SettingsState, AlbumActions, ArtistActions, ArtworkActions, NowPlayingState, QueueState, SearchState, SearchActions, NetworkSidebarState, NetworkSidebarActions, MusicianState, MusicianActions, LabelState, LabelActions, LocationViewState, LocationViewActions, FavoritesState, FavoritesActions, PlaylistPickerState, PlaylistPickerActions, PlaylistState, PlaylistActions, SidebarState, SidebarActions, SidebarFolderPopupState, CreatePlaylistState, CreatePlaylistActions, EditPlaylistState, EditPlaylistActions, CreateFolderState, CreateFolderActions, DragState, DragActions, PlaylistManagerState, PlaylistManagerActions, OfflineManagerState, OfflineManagerActions, MyQbzState, MyQbzActions, MixtapeCardItem, LocalLibraryState, LocalLibraryActions, LibraryFoldersState, LibFolderEditState, LibraryManageActions, LibraryScanState, LibAlbumFilterState, LocalAlbumState, LocalAlbumActions, TagEditorState, TagEditorActions, FolderEditState, FolderEditActions, ToastState, TextUtil, QconnectDevState, QconnectDevice, AppearanceState, EphemeralPlayChoiceState, EphemeralPlayChoiceActions, PlexSettingsState, PlexAuthActions, PlexSectionItem } from "state.slint"; // Which top-level screen is shown. The app starts on `splash` while it // restores a saved session, then resolves to `shell` or `login`. export enum AppScreen { splash, login, shell } export component AppWindow inherits Window { title: "QBZ"; preferred-width: 1180px; preferred-height: 760px; min-width: 940px; min-height: 600px; background: Theme.surface-main; // Resolved by the Rust layer from the desktop environment (e.g. the // KDE Plasma general font). Empty falls back to the Slint default. in property system-font: ""; default-font-family: root.system-font; in-out property screen: AppScreen.splash; // Forwarded to the Rust layer. callback sign-in-via-browser(); callback use-system-browser(); callback start-offline(); callback open-tos(); callback open-album(string); callback open-artist(string); callback media-action(string, string, string); callback header-menu-navigate(string); callback discover-view-all(string, string); callback settings-bool(string, bool); callback settings-select(string, int); callback settings-slider(string, int); callback settings-reset(); callback settings-release-device(); callback logout(); callback close-app(); if root.screen == AppScreen.splash: SplashScreen { } if root.screen == AppScreen.login: LoginScreen { sign-in-via-browser => { root.sign-in-via-browser(); } use-system-browser => { root.use-system-browser(); } start-offline => { root.start-offline(); } open-tos => { root.open-tos(); } } if root.screen == AppScreen.shell: AppShell { // Fill the window. A conditionally-mounted child sizes to its PREFERRED // size by default, so without this the shell sized to its content — fine // while the right panels were always mounted (tall content), but once // they became conditional, with both closed the shell collapsed to the // top with dead space below. Bind to the real window size (`root` here is // the AppWindow); `100%` did not pin it. width: root.width; height: root.height; open-album(id) => { root.open-album(id); } open-artist(id) => { root.open-artist(id); } media-action(kind, id, action) => { root.media-action(kind, id, action); } header-menu-navigate(route) => { root.header-menu-navigate(route); } discover-view-all(e, t) => { root.discover-view-all(e, t); } settings-bool(k, v) => { root.settings-bool(k, v); } settings-select(k, i) => { root.settings-select(k, i); } settings-slider(k, v) => { root.settings-slider(k, v); } settings-reset => { root.settings-reset(); } settings-release-device => { root.settings-release-device(); } logout => { root.logout(); } close-app => { root.close-app(); } } // App-global in-app toast overlay. Declared last so it floats over // every screen (splash / login / shell). Driven by ToastState via // crate::toast. Toast { width: 100%; height: 100%; } }