mirror of
https://git.srhtnin.garden/sarah/SaraView.git
synced 2026-10-14 18:38:11 +02:00
Add Flet desktop client
This commit is contained in:
1 parent
16787aba14
commit
0eecfba224
18 files changed
+2588
No files matched your search
+105
@@ -0,0 +1,105 @@
|
||||
"""SaraView's desktop client: browse and edit files in a local root directory,
|
||||
or on a SaraView server (the one on SpineS) through its API. Laid out like
|
||||
SaraFem: a directory tree on the left, the file list (or an open file) on
|
||||
the right."""
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
from typing import Optional
|
||||
|
||||
import flet as ft
|
||||
|
||||
from App import App
|
||||
from Browser import Browser
|
||||
from Core import (
|
||||
AppName, ApplyAppearance, AssetsDir, BuildTheme, BundledFontFamily, EffectiveSettings, LoadConfig, Palette,
|
||||
ResizeHandle,
|
||||
)
|
||||
from Filetree import Filetree
|
||||
from Settings import ShowSettingsDialog
|
||||
|
||||
|
||||
def _SetCursorThemeFallback() -> None:
|
||||
"""GTK reads XCURSOR_THEME directly and doesn't always inherit it (shows as
|
||||
'Unable to load ... from the cursor theme'). Same fix as SaraFem's."""
|
||||
if os.environ.get("XCURSOR_THEME"):
|
||||
return
|
||||
try:
|
||||
Result = subprocess.run(["gsettings", "get", "org.gnome.desktop.interface", "cursor-theme"],
|
||||
capture_output=True, text=True, timeout=2)
|
||||
Theme = Result.stdout.strip().strip("'")
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
Theme = ""
|
||||
os.environ["XCURSOR_THEME"] = Theme or "Adwaita"
|
||||
|
||||
|
||||
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 = 760
|
||||
Page.window.min_width = 720
|
||||
Page.window.min_height = 480
|
||||
|
||||
TheApp = App(Page, Config)
|
||||
|
||||
def OnPathChanged(Root: Optional[str], RelativePath: str, Reload: bool) -> None:
|
||||
if Reload: # directories may have moved, so the tree starts over
|
||||
Tree.Reload()
|
||||
Tree.RevealPath(Root, RelativePath)
|
||||
|
||||
def ShowSettings(Category: str = "General") -> None:
|
||||
ShowSettingsDialog(TheApp, OnSettingsSaved, Category)
|
||||
|
||||
def OnSettingsSaved(Reconnect: bool) -> None:
|
||||
Tree.visible = Divider.visible = Config.ShowSidebar
|
||||
if Reconnect:
|
||||
TheApp.Connect() # its listeners reload the tree and the browser
|
||||
else:
|
||||
Body.update()
|
||||
TheBrowser.Refresh()
|
||||
|
||||
def ToggleSidebar() -> None:
|
||||
Config.ShowSidebar = not Config.ShowSidebar
|
||||
Config.Save()
|
||||
Tree.visible = Divider.visible = Config.ShowSidebar
|
||||
Body.update()
|
||||
|
||||
def OnDrag(Delta: float) -> None:
|
||||
Tree.width = max(140, (Tree.width or Config.SidebarWidth) + Delta)
|
||||
Tree.update()
|
||||
|
||||
def OnDragEnd() -> None:
|
||||
Config.SidebarWidth = int(Tree.width)
|
||||
Config.Save()
|
||||
|
||||
TheBrowser = Browser(TheApp, OnPathChanged, lambda: ShowSettings("Connection" if TheApp.ConnectError else "General"),
|
||||
ToggleSidebar)
|
||||
Tree = Filetree(TheApp, TheBrowser.NavigateTo)
|
||||
Divider = ResizeHandle(OnDrag, OnDragEnd)
|
||||
Tree.visible = Divider.visible = Config.ShowSidebar
|
||||
# STRETCH so the divider gets the full height to be dragged along.
|
||||
Body = ft.Row([Tree, Divider, TheBrowser], expand=True, spacing=0, vertical_alignment=ft.CrossAxisAlignment.STRETCH)
|
||||
Page.add(Body)
|
||||
|
||||
def OnSourceChanged() -> None:
|
||||
Tree.Reload()
|
||||
TheBrowser.SourceChanged()
|
||||
|
||||
TheApp.Listeners.append(OnSourceChanged)
|
||||
TheApp.Connect()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
_SetCursorThemeFallback()
|
||||
ft.run(Main, assets_dir=str(AssetsDir))
|
||||
Reference in new issue
Block a user