Files
SaraFem/Tags.py
T
2026-09-24 22:03:58 +02:00

73 lines
2.6 KiB
Python

"""Standalone SaraTag Book-tag panel. Split out from Preview.py (Bugs/Minor:
"SaraTag only shows in preview pane") so it can be shown/hidden and positioned
independently — see AppConfig.ShowTags / TagsPosition / TagsLayout."""
from pathlib import Path
from typing import Optional
import flet as ft
from Books import ReadBookForFile
from Core import AppConfig, Palette
# Fixedsys Excelsior is fixed-width, so a per-character estimate is accurate
# enough to size chips without a real text-measurement API.
EstimatedCharWidth = 7.5
ChipPadding = 32
def _EstimateChipWidth(Label: str, Config: AppConfig) -> Optional[float]:
if not Config.TagMinWidth and not Config.TagMaxWidth:
return None # let the chip hug its content, no constraint requested
Natural = len(Label) * EstimatedCharWidth + ChipPadding
Lower = Config.TagMinWidth or 0
Upper = Config.TagMaxWidth or Natural
return max(Lower, min(Natural, Upper))
def _MakeChip(Key: str, Value, Config: AppConfig) -> ft.Chip:
Label = f"{Key}: {Value}"
return ft.Chip(
label=Label,
label_text_style=ft.TextStyle(color=Palette.Text, size=12),
bgcolor=Palette.Surface0,
shadow_color=Palette.Surface0,
elevation=0,
elevation_on_click=0,
show_checkmark=False,
width=_EstimateChipWidth(Label, Config),
)
class TagPanel(ft.Container):
def __init__(self, Config: AppConfig):
self.Config = Config
self.Body = ft.Column(spacing=0)
self.Body.controls = self._BuildContent(None)
BorderSide = ft.BorderSide(1, Palette.Surface1)
super().__init__(
content=self.Body,
padding=8,
bgcolor=Palette.Mantle,
border=ft.Border(top=BorderSide, right=BorderSide, bottom=BorderSide, left=BorderSide),
)
def ShowPath(self, EntryPath: Optional[Path]) -> None:
self.Body.controls = self._BuildContent(EntryPath)
self.update()
def _BuildContent(self, EntryPath: Optional[Path]) -> list[ft.Control]:
if EntryPath is None or EntryPath.is_dir():
return [ft.Text("No tags.", color=Palette.Overlay0, size=12)]
Book = ReadBookForFile(EntryPath, self.Config)
if not Book or not Book["Tags"]:
return [ft.Text("No tags.", color=Palette.Overlay0, size=12)]
Chips = [_MakeChip(Key, Value, self.Config) for Key, Value in Book["Tags"].items()]
if self.Config.TagsLayout == "vertical":
return [ft.Column(Chips, spacing=4, horizontal_alignment=ft.CrossAxisAlignment.START)]
return [ft.Row(Chips, wrap=True, spacing=4, run_spacing=4)]