mirror of
https://git.srhtnin.garden/sarah/SaraView.git
synced 2026-10-14 18:38:11 +02:00
Properties: colours by type, readable keys, lines between
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
ca37409e37
commit
81ebcd66a1
3 files changed
+101
-14
No files matched your search
+55
-9
@@ -23,6 +23,37 @@ OpenOrClose = re.compile(r"^---\s*$")
|
||||
PropertyLine = re.compile(r"^([^:\s][^:]*?)\s*:\s*(.*)$")
|
||||
TaskLine = re.compile(r"^(\s*(?:[-*+]|\d+[.)])\s+)\[( |x|X)\]")
|
||||
BooleanValue = re.compile(r"^(true|false)$", re.IGNORECASE)
|
||||
Quoted = re.compile(r"""^(["']).*\1$""")
|
||||
IntegerValue = re.compile(r"^[+-]?\d+$")
|
||||
FloatValue = re.compile(r"^[+-]?(\d+\.\d*([eE][+-]?\d+)?|\.\d+([eE][+-]?\d+)?|\d+[eE][+-]?\d+)$")
|
||||
DateValue = re.compile(r"^\d{4}-\d{2}-\d{2}([T ]\d{2}:\d{2}(:\d{2})?)?$")
|
||||
|
||||
|
||||
def ValueKind(Value: str) -> str:
|
||||
"""What a value is, for its colour: quotes always make it text ("42" is
|
||||
text, 42 a number), like YAML. Same rules as Properties.js's ValueKind."""
|
||||
if Value == "":
|
||||
return "Empty"
|
||||
if Quoted.match(Value):
|
||||
return "String"
|
||||
if BooleanValue.match(Value):
|
||||
return "Boolean"
|
||||
if IntegerValue.match(Value):
|
||||
return "Integer"
|
||||
if FloatValue.match(Value):
|
||||
return "Float"
|
||||
if DateValue.match(Value):
|
||||
return "Date"
|
||||
return "String"
|
||||
|
||||
|
||||
def ShownValue(Value: str) -> str:
|
||||
"""A value as shown: without the quotes that only said "this is text"."""
|
||||
return Value[1:-1] if Quoted.match(Value) else Value
|
||||
|
||||
|
||||
def KindColour(Kind: str) -> str:
|
||||
return {"Integer": Palette.Peach, "Float": Palette.Yellow, "Date": Palette.Blue}.get(Kind, Palette.Green)
|
||||
|
||||
# Ticks a box: called with the line (0-based, in the whole note) to flip.
|
||||
OnToggle = Optional[Callable[[int], None]]
|
||||
@@ -93,26 +124,41 @@ def _Checkbox(Checked: bool, Line: int, Toggle: OnToggle) -> ft.Checkbox:
|
||||
)
|
||||
|
||||
|
||||
def _Value(Value: str, FontSize: int, MakeMarkdown: Callable[[str], ft.Control]) -> ft.Control:
|
||||
"""A value in its kind's colour; one with Markdown in it (a link, bold)
|
||||
is rendered as Markdown instead."""
|
||||
Shown = ShownValue(Value)
|
||||
if re.search(r"[\[*_`~]|https?://", Shown):
|
||||
return MakeMarkdown(Shown)
|
||||
return ft.Text(Shown, color=KindColour(ValueKind(Value)), size=FontSize, selectable=True)
|
||||
|
||||
|
||||
def PropertiesView(Found: Parsed, FontSize: int, MakeMarkdown: Callable[[str], ft.Control],
|
||||
Toggle: OnToggle) -> ft.Control:
|
||||
"""The panel. MakeMarkdown renders a value (links, bold)."""
|
||||
"""The panel. MakeMarkdown renders a value with Markdown in it (links, bold)."""
|
||||
Rows: list[ft.Control] = []
|
||||
for Item in Found.Properties:
|
||||
if BooleanValue.match(Item.Value):
|
||||
Shown: ft.Control = _Checkbox(Item.Value.lower() == "true", Item.Line, Toggle)
|
||||
elif Item.List:
|
||||
Shown = ft.Row([ft.Container(ft.Text(Entry, color=Palette.Mauve, size=FontSize - 1), bgcolor=Palette.Surface0,
|
||||
border_radius=4, padding=ft.Padding.symmetric(horizontal=6, vertical=1))
|
||||
Shown = ft.Row([ft.Container(ft.Text(ShownValue(Entry), color=KindColour(ValueKind(Entry)), size=FontSize - 1),
|
||||
bgcolor=Palette.Surface0, border_radius=4,
|
||||
padding=ft.Padding.symmetric(horizontal=6, vertical=1))
|
||||
for Entry in Item.List], wrap=True, spacing=4, run_spacing=4)
|
||||
elif Item.Value:
|
||||
Shown = MakeMarkdown(Item.Value)
|
||||
Shown = _Value(Item.Value, FontSize, MakeMarkdown)
|
||||
else:
|
||||
Shown = ft.Text("Empty", color=Palette.Overlay0, italic=True, size=FontSize - 1)
|
||||
Rows.append(ft.Row([
|
||||
ft.Container(ft.Text(Item.Key, color=Palette.Overlay0, size=FontSize - 1, max_lines=1,
|
||||
overflow=ft.TextOverflow.ELLIPSIS), expand=3),
|
||||
ft.Container(Shown, expand=7, alignment=ft.Alignment.CENTER_LEFT),
|
||||
], spacing=12, vertical_alignment=ft.CrossAxisAlignment.CENTER))
|
||||
Rows.append(ft.Container(
|
||||
ft.Row([
|
||||
ft.Container(ft.Text(Item.Key, color=Palette.Text, size=FontSize - 1, max_lines=1,
|
||||
overflow=ft.TextOverflow.ELLIPSIS), expand=3),
|
||||
ft.Container(Shown, expand=7, alignment=ft.Alignment.CENTER_LEFT),
|
||||
], spacing=12, vertical_alignment=ft.CrossAxisAlignment.CENTER),
|
||||
# A line between properties, like the web view's.
|
||||
border=ft.Border.only(top=ft.BorderSide(1, Palette.Surface1)) if Rows else None,
|
||||
padding=ft.Padding.symmetric(vertical=4),
|
||||
))
|
||||
return ft.Container(
|
||||
ft.Column([ft.Text("Properties", color=Palette.Overlay0, size=FontSize - 1), *Rows], spacing=2, tight=True),
|
||||
bgcolor=Palette.Mantle,
|
||||
|
||||
Reference in new issue
Block a user