Created
December 17, 2024 14:10
-
-
Save patrick91/e54781488d8dda15920ea1e56a4d26be to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from datetime import datetime | |
from typing import Callable, Iterable | |
from textual._segment_tools import line_pad | |
from textual.app import App, ComposeResult, RenderResult | |
from textual.color import Color | |
from textual.css.styles import StylesBase | |
from textual.geometry import Size, Spacing | |
from textual.screen import Screen | |
from textual.strip import Strip | |
from textual.widgets import Digits | |
from rich.console import Console, ConsoleOptions | |
from rich.segment import Segment | |
from rich.style import Style | |
from rich.text import Text | |
from textual._styles_cache import StylesCache, make_blank | |
class TransparentBlank: | |
def __rich_console__( | |
self, console: Console, options: ConsoleOptions | |
) -> RenderResult: | |
width = options.max_width | |
height = options.height or options.max_height | |
self._style = Style() | |
segment = Segment(" " * width) | |
line = Segment.line() | |
for _ in range(height): | |
yield segment | |
yield line | |
class TransparentStyleCache(StylesCache): | |
def render_line( | |
self, | |
styles: StylesBase, | |
y: int, | |
size: Size, | |
content_size: Size, | |
padding: Spacing, | |
base_background: Color, | |
background: Color, | |
render_content_line: Callable[[int], Strip], | |
console: Console, | |
border_title: tuple[Text, Color, Color, Style] | None, | |
border_subtitle: tuple[Text, Color, Color, Style] | None, | |
opacity: float, | |
) -> Strip: | |
gutter = styles.gutter | |
width, _ = size | |
content_width, content_height = content_size | |
_, pad_right, _, pad_left = padding | |
line: Iterable[Segment] | |
content_y = y - gutter.top | |
if content_y < content_height: | |
line = render_content_line(y - gutter.top) | |
line = line.adjust_cell_length(content_width) | |
else: | |
line = [make_blank(content_width)] | |
line = line_pad(line, pad_left, pad_right, Style()) | |
strip = Strip(line, width) | |
return strip | |
class TransparentScreen(Screen): | |
def __init__(self, *args, **kwargs) -> None: | |
super().__init__(*args, **kwargs) | |
self._styles_cache = TransparentStyleCache() | |
class ClockApp(App): | |
CSS = """ | |
App { | |
background: transparent; | |
} | |
Screen { | |
align: center middle; | |
&:inline { | |
border: none; | |
height: 50vh; | |
Digits { | |
color: $success; | |
} | |
} | |
background: transparent; | |
} | |
#clock { | |
width: auto; | |
} | |
""" | |
def get_default_screen(self) -> Screen: | |
return TransparentScreen(id="_default") | |
def compose(self) -> ComposeResult: | |
yield Digits("", id="clock") | |
def on_ready(self) -> None: | |
self.update_clock() | |
self.set_interval(1, self.update_clock) | |
def update_clock(self) -> None: | |
clock = datetime.now().time() | |
self.query_one(Digits).update(f"{clock:%T}") | |
def render(self) -> RenderResult: | |
return TransparentBlank() | |
if __name__ == "__main__": | |
app = ClockApp() | |
app.run(inline=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment