"""Custom Textual widgets for the TUI."""
from rich.text import Text
# Runtime import: read by Sphinx autodoc / get_type_hints on compose().
from textual.app import ComposeResult # noqa: TC002
from textual.binding import Binding
from textual.widgets import Input, ListItem, ListView, Static
# Runtime import: read by Sphinx autodoc / get_type_hints on the widget signatures.
from olink.tui.models import TargetItem # noqa: TC001
__all__ = ["SearchInput", "StatusBar", "TargetListWidget", "TargetRow"]
[docs]
class TargetRow(ListItem):
"""A single target row in the list."""
def __init__(self, item: TargetItem) -> None:
self.item = item
super().__init__()
[docs]
def compose(self) -> ComposeResult:
"""Render the pin marker, name and description as one styled line."""
label = Text()
marker = "★ " if self.item.pinned else " "
label.append(marker, style="yellow")
label.append(f"{self.item.name:20s}", style="cyan")
label.append(f" {self.item.description}")
yield Static(label)
[docs]
class StatusBar(Static):
"""Bottom status bar showing mode, count, and messages."""
def on_mount(self) -> None:
self.styles.background = "darkblue"
self.styles.color = "white"
self.styles.height = 1
self.styles.dock = "bottom"
[docs]
def status_update(self, mode: str, count: int, total: int) -> None:
"""Update the status bar content."""
mode_label = "Available" if mode == "available" else "All"
self.update(f" [{mode_label}: {count}/{total}]")
self.styles.color = "white"
[docs]
def set_error(self, message: str) -> None:
"""Show an error message."""
self.update(f" \u2717 {message}")
self.styles.color = "red"
[docs]
def set_success(self, message: str) -> None:
"""Show a success message."""
self.update(f" \u2713 {message}")
self.styles.color = "green"