Last active
April 21, 2025 15:35
-
-
Save ddkasa/101adcd93ca340c3ee625df725cd450c to your computer and use it in GitHub Desktop.
Textual Christmas
This file contains hidden or 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 collections import deque | |
from typing import Self | |
from pyfiglet import figlet_format | |
from rich.color import Color | |
from rich.segment import Segment | |
from rich.style import Style | |
from textual.app import App, ComposeResult | |
from textual.containers import Center | |
from textual.geometry import Region | |
from textual.reactive import reactive | |
from textual.strip import Strip | |
from textual.widget import Widget | |
from textual.widgets import Header | |
class ChristmasWidget(Widget): | |
DEFAULT_CSS = """ | |
ChristmasWidget { | |
width: auto; | |
height: auto; | |
padding: 2 6; | |
} | |
""" | |
colors: deque[Style] = deque() | |
text: reactive[list[str]] = reactive(list, init=False, layout=True) | |
def on_mount(self) -> None: | |
for color in ("#165B33", "#146B3A", "#F8B229", "#EA4630", "#BB2528"): | |
self.colors.append(Style(color=Color.parse(color))) | |
self.clock = self.set_interval(0.2, self.refresh) | |
def render_lines(self, crop: Region) -> list[Strip]: | |
self.colors.rotate() | |
return super().render_lines(crop) | |
def render_line(self, y: int) -> Strip: | |
try: | |
return Strip([Segment(self.text[y], style=self.colors[y % 5])]) | |
except IndexError: | |
return Strip.blank(self.size.width) | |
def with_text(self, text: str) -> Self: | |
self.text = figlet_format(text, "banner", width=self.app.size.width).split("\n") | |
return self | |
def get_content_height(self, *_) -> int: | |
return len(self.text) | |
def get_content_width(self, *_) -> int: | |
if self.text: | |
return len(max(self.text, key=len)) | |
return 0 | |
class ChristmasApp(App): | |
TITLE = "Merry Christmas" | |
CSS = """ | |
ChristmasApp { | |
background: $panel-darken-2; | |
} | |
Center { | |
height: 100%; | |
align: center middle; | |
} | |
""" | |
def compose(self) -> ComposeResult: | |
yield Header(show_clock=True) | |
with Center(): | |
yield ChristmasWidget().with_text("Merry Christmas!") | |
if __name__ == "__main__": | |
ChristmasApp().run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment