Source code for stormlog.tui.widgets.welcome

"""Welcome banner widget used by the Textual TUI."""

from __future__ import annotations

import logging
from typing import Any

from rich.text import Text
from textual.widgets import Static


[docs] class AsciiWelcome(Static): """Animated ASCII welcome banner, uses pyfiglet when available.""" def __init__( self, messages: list[str], font: str = "Standard", interval: float = 3.0, figlet_cls: Any | None = None, logger: logging.Logger | None = None, **kwargs: Any, ) -> None: super().__init__("", **kwargs) self.messages = messages or ["Stormlog"] self.font_name = font self.interval = interval self._frame_index = 0 self._figlet = None self._figlet_cls = figlet_cls self._logger = logger or logging.getLogger(__name__) if self._figlet_cls: try: self._figlet = self._figlet_cls(font=self.font_name) except Exception as exc: self._logger.debug("Figlet initialization failed: %s", exc) self._figlet = None
[docs] def on_mount(self) -> None: self._render_frame() if len(self.messages) > 1: self.set_interval(self.interval, self._advance_frame)
def _advance_frame(self) -> None: self._frame_index = (self._frame_index + 1) % len(self.messages) self._render_frame() def _render_frame(self) -> None: message = self.messages[self._frame_index] ascii_text = self._render_ascii(message) self.update(ascii_text) def _render_ascii(self, message: str) -> Text: if self._figlet: try: rendered = self._figlet.renderText(message) return Text(rendered.rstrip()) except Exception as exc: self._logger.debug("Figlet render failed, using fallback: %s", exc) title = "Stormlog" width = max(28, len(title), len(message)) border = f"+{'-' * (width + 2)}+" fallback = "\n".join( [ border, f"| {title.center(width)} |", f"| {message.center(width)} |", border, ] ) return Text(fallback)