ai-station/.venv/lib/python3.12/site-packages/textual/demo/page.py

95 lines
2.5 KiB
Python
Raw Permalink Normal View History

2025-12-25 14:54:33 +00:00
from __future__ import annotations
import inspect
from rich.syntax import Syntax
from textual import work
from textual.app import ComposeResult
from textual.binding import Binding
from textual.containers import ScrollableContainer
from textual.screen import ModalScreen, Screen
from textual.widgets import Static
class CodeScreen(ModalScreen):
DEFAULT_CSS = """
CodeScreen {
#code {
border: heavy $accent;
margin: 2 4;
scrollbar-gutter: stable;
Static {
width: auto;
}
}
}
"""
BINDINGS = [("escape", "dismiss", "Dismiss code")]
def __init__(self, title: str, code: str) -> None:
super().__init__()
self.code = code
self.title = title
def compose(self) -> ComposeResult:
with ScrollableContainer(id="code"):
yield Static(
Syntax(
self.code, lexer="python", indent_guides=True, line_numbers=True
),
expand=True,
)
def on_mount(self):
code_widget = self.query_one("#code")
code_widget.border_title = self.title
code_widget.border_subtitle = "Escape to close"
class PageScreen(Screen):
DEFAULT_CSS = """
PageScreen {
width: 100%;
height: 1fr;
overflow-y: auto;
}
"""
BINDINGS = [
Binding(
"c",
"show_code",
"Code",
tooltip="Show the code used to generate this screen",
)
]
@work(thread=True)
def get_code(self, source_file: str) -> str | None:
"""Read code from disk, or return `None` on error."""
try:
with open(source_file, "rt", encoding="utf-8") as file_:
return file_.read()
except Exception:
return None
async def action_show_code(self):
source_file = inspect.getsourcefile(self.__class__)
if source_file is None:
self.notify(
"Could not get the code for this page",
title="Show code",
severity="error",
)
return
code = await self.get_code(source_file).wait()
if code is None:
self.notify(
"Could not get the code for this page",
title="Show code",
severity="error",
)
else:
self.app.push_screen(CodeScreen("Code for this page", code))