"""SaraTag: tag files with Books (per-file sidecars) defined by Lexicons. The window and navigation; each page lives in its own *Page.py.""" import flet as ft from BrowsePage import BrowsePage from Core import ( AppName, ApplyAppearance, AssetsDir, BuildTheme, BundledFontFamily, EffectiveSettings, IsWindows, LoadConfig, Palette, ) from LexiconsPage import LexiconsPage from LibrariesPage import LibrariesPage from Library import TagCore from RecordsPage import RecordsPage from Settings import ShowSettingsDialog from UpdatePage import UpdatePage from Widgets import App Destinations = [ ("Browse", ft.Icons.PHOTO_LIBRARY_OUTLINED, ft.Icons.PHOTO_LIBRARY), ("Records", ft.Icons.FOLDER_SPECIAL_OUTLINED, ft.Icons.FOLDER_SPECIAL), ("Libraries", ft.Icons.COLLECTIONS_BOOKMARK_OUTLINED, ft.Icons.COLLECTIONS_BOOKMARK), ("Lexicons", ft.Icons.MENU_BOOK_OUTLINED, ft.Icons.MENU_BOOK), ("Update", ft.Icons.SYNC_OUTLINED, ft.Icons.SYNC), ] Names = [Name for Name, _, _ in Destinations] def Main(Page: ft.Page) -> None: TagCore.EnsureConfigFiles() Config = LoadConfig() Appearance = EffectiveSettings(Config) ApplyAppearance(Appearance) # before anything reads Palette.X Page.title = AppName Page.theme_mode = ft.ThemeMode.DARK Page.theme = BuildTheme() Page.dark_theme = BuildTheme() Page.fonts = {BundledFontFamily: "fonts/Fixedsys_Excelsior_Regular.ttf"} Page.window.title_bar_hidden = Appearance.HideWindowTitleBar Page.window.icon = str(AssetsDir / "Icon.png") Page.padding = 0 Page.bgcolor = Palette.Base Page.window.width = 1280 Page.window.height = 820 if IsWindows: Page.window.icon = str(AssetsDir / "Icon.ico") # taskbar/title bar (Linux: the desktop entry) Page.window.min_width = 900 Page.window.min_height = 560 TheApp = App(Page, Config) Body = ft.Container(expand=True) Pages: dict[str, ft.Control] = {} State = {"Current": ""} def Navigate(Name: str, **Arguments) -> None: if Name not in Pages: return Previous = Pages.get(State["Current"]) if Previous is not None: Previous.Leave() State["Current"] = Name Rail.selected_index = Names.index(Name) Body.content = Pages[Name] Page.update() Pages[Name].Refresh(**Arguments) TheApp.Navigate = Navigate Pages.update({ "Browse": BrowsePage(TheApp), "Records": RecordsPage(TheApp), "Libraries": LibrariesPage(TheApp), "Lexicons": LexiconsPage(TheApp), "Update": UpdatePage(TheApp), }) Rail = ft.NavigationRail( selected_index=0, label_type=ft.NavigationRailLabelType.ALL, bgcolor=Palette.Mantle, indicator_color=Palette.Surface0, min_width=88, destinations=[ft.NavigationRailDestination(icon=Icon, selected_icon=Selected, label=Name) for Name, Icon, Selected in Destinations], on_change=lambda e: Navigate(Names[e.control.selected_index]), ) SettingsButton = ft.IconButton( icon=ft.Icons.SETTINGS_OUTLINED, icon_color=Palette.Mauve, tooltip="Settings", # SaraTagConf.toml may have changed (hidden directories, ...), so reload the page. on_click=lambda e: ShowSettingsDialog(TheApp, lambda: Navigate(State["Current"])), ) Page.add(ft.Column([ ft.Container( content=ft.Row([ ft.Text(AppName, size=24, color=Palette.Mauve), ft.Container(expand=True), SettingsButton, ]), padding=ft.Padding.symmetric(horizontal=16, vertical=8), bgcolor=Palette.Mantle, border=ft.Border.only(bottom=ft.BorderSide(1, Palette.Surface1)), ), ft.Row([Rail, ft.VerticalDivider(width=1, color=Palette.Surface1), Body], expand=True, spacing=0, vertical_alignment=ft.CrossAxisAlignment.STRETCH), ], expand=True, spacing=0)) Navigate(Config.StartPage if Config.StartPage in Pages else "Browse") if __name__ == "__main__": ft.run(Main, assets_dir=str(AssetsDir))