diff --git a/widgets/themes.json b/widgets/themes.json new file mode 100644 index 0000000..d8cb52c --- /dev/null +++ b/widgets/themes.json @@ -0,0 +1,49 @@ +{ + "themes": { + "gruvbox": { + "background": "#282828", + "foreground": "#fbf1c7", + "primary": "#85A598", + "secondary": "#A89A85", + "accent": "#fabd2f", + "surface": "#3c3836", + "panel": "#504945" + }, + "dracula": { + "background": "#282a36", + "foreground": "#f8f8f2", + "primary": "#bd93f9", + "secondary": "#6272a4", + "accent": "#ff79c6", + "surface": "#44475a", + "panel": "#6272a4" + }, + "nord": { + "background": "#2e3440", + "foreground": "#d8dee9", + "primary": "#88c0d0", + "secondary": "#5e81ac", + "accent": "#81a1c1", + "surface": "#3b4252", + "panel": "#434c5e" + }, + "solarized-dark": { + "background": "#002b36", + "foreground": "#839496", + "primary": "#268bd2", + "secondary": "#586e75", + "accent": "#b58900", + "surface": "#073642", + "panel": "#586e75" + }, + "monokai": { + "background": "#272822", + "foreground": "#f8f8f2", + "primary": "#66d9ef", + "secondary": "#75715e", + "accent": "#fd971f", + "surface": "#383830", + "panel": "#49483e" + } + } +} \ No newline at end of file diff --git a/widgets/widget.py b/widgets/widget.py new file mode 100644 index 0000000..f42a83e --- /dev/null +++ b/widgets/widget.py @@ -0,0 +1,77 @@ +""" +An App to show the current time with theme support. +""" + +import json +import sys +from datetime import datetime +from pathlib import Path + +from textual.app import App, ComposeResult +from textual.widgets import Digits + + +def load_themes(): + """Load themes from themes.json file.""" + themes_file = Path(__file__).parent / "themes.json" + with open(themes_file) as f: + data = json.load(f) + return data["themes"] + + +def get_theme_css(theme_name: str) -> str: + """Generate CSS for a specific theme.""" + themes = load_themes() + if theme_name not in themes: + available = ", ".join(themes.keys()) + raise ValueError(f"Theme '{theme_name}' not found. Available: {available}") + + theme = themes[theme_name] + return f""" + Screen {{ + align: center middle; + background: {theme['background']}; + }} + Digits {{ + width: auto; + color: {theme['foreground']}; + }} + """ + + +class ClockApp(App): + CSS = """ + Screen { align: center middle; background: #282828; } + Digits { width: auto; color: #fbf1c7; } + """ + + def __init__(self, theme_name: str = "gruvbox", **kwargs): + self.theme_name = theme_name + # Override CSS with theme + ClockApp.CSS = get_theme_css(theme_name) + super().__init__(**kwargs) + + def compose(self) -> ComposeResult: + yield Digits("") + + 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}") + + +if __name__ == "__main__": + # Parse command line arguments for theme selection + theme = "gruvbox" + if len(sys.argv) > 1: + theme = sys.argv[1] + + try: + app = ClockApp(theme_name=theme) + app.run() + except ValueError as e: + print(f"Error: {e}") + sys.exit(1)