"""SaraSort: a GUI for configuring SaraSortd. It doesn't sort anything itself; it reads and edits SaraSortd's configs and controls its systemd service.""" import flet as ft from ConfigPage import ConfigPage from Core import ( AppName, ApplyAppearance, AssetsDir, BuildTheme, BundledFontFamily, EffectiveSettings, LoadConfig, Palette, ) from FlowPage import FlowPage from ServicePage import ServicePage from SettingsPage import SettingsPage from TemplatesPage import TemplatesPage from ToolsPage import ToolsPage from Widgets import App Destinations = [ ("Flow", ft.Icons.SCHEMA_OUTLINED, ft.Icons.SCHEMA), ("Service", ft.Icons.MONITOR_HEART_OUTLINED, ft.Icons.MONITOR_HEART), ("Configs", ft.Icons.TUNE_OUTLINED, ft.Icons.TUNE), ("Templates", ft.Icons.DASHBOARD_CUSTOMIZE_OUTLINED, ft.Icons.DASHBOARD_CUSTOMIZE), ("Tools", ft.Icons.BUILD_OUTLINED, ft.Icons.BUILD), ("Settings", ft.Icons.SETTINGS_OUTLINED, ft.Icons.SETTINGS), ] Names = [Name for Name, _, _ in Destinations] def Main(Page: ft.Page) -> None: 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.padding = 0 Page.bgcolor = Palette.Base Page.window.width = 1180 Page.window.height = 780 Page.window.min_width = 760 Page.window.min_height = 520 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 isinstance(Previous, ServicePage): Previous.StopPolling() State["Current"] = Name Rail.selected_index = Names.index(Name) Body.content = Pages[Name] Page.update() Shown = Pages[Name] Shown.Refresh(**Arguments) if isinstance(Shown, ServicePage): Shown.StartPolling() TheApp.Navigate = Navigate Pages.update({ "Flow": FlowPage(TheApp), "Service": ServicePage(TheApp), "Configs": ConfigPage(TheApp), "Templates": TemplatesPage(TheApp), "Tools": ToolsPage(TheApp), "Settings": SettingsPage(TheApp, OnSaved=lambda: None), }) 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]), ) async def CloseWindow(e) -> None: await Page.window.close() TitleRow = [ft.WindowDragArea( ft.Container(ft.Text(AppName, size=18, color=Palette.Mauve), padding=ft.Padding.only(left=16, top=6, bottom=6)), expand=True, )] if Appearance.HideWindowTitleBar: TitleRow += [ ft.IconButton(ft.Icons.MINIMIZE, icon_size=16, tooltip="Minimize", on_click=lambda e: (setattr(Page.window, "minimized", True), Page.update())), ft.IconButton(ft.Icons.CLOSE, icon_size=16, tooltip="Close", on_click=CloseWindow), ] Page.add(ft.Column([ ft.Container(ft.Row(TitleRow, spacing=0), 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 "Flow") if __name__ == "__main__": ft.run(Main, assets_dir=str(AssetsDir))