"""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, 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 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))