1
0
Fork 0

Animated screensaver, command line args for ssaver delay and fullscreen

This commit is contained in:
Michał Rudowicz 2024-09-09 22:58:58 +02:00
parent 607057868d
commit 598c882076
3 changed files with 68 additions and 36 deletions

16
iboard.py Normal file
View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
from abc import abstractmethod
from pygame import Surface
from pygame.event import Event
class IBoard:
@abstractmethod
def draw(self, screen: Surface):
raise NotImplementedError()
@abstractmethod
def handle_event(self, event: Event):
raise NotImplementedError()

51
menu.py
View File

@ -4,16 +4,18 @@ import math
import argparse
import json
from enum import Enum, auto
from time import sleep, strftime
from time import sleep
from threading import Thread
from queue import Queue, Empty
from abc import abstractmethod
from typing import Tuple, Callable, TypedDict, List
import pygame
import pygame.freetype
import requests
from iboard import IBoard
from screensavers import ClockScreensaver
class ButtonDef(TypedDict):
text: str
@ -31,36 +33,6 @@ class Action(TypedDict):
param: str
class IBoard:
@abstractmethod
def draw(self, screen: pygame.Surface):
raise NotImplementedError()
@abstractmethod
def handle_event(self, event: pygame.event.Event):
raise NotImplementedError()
class Screensaver(IBoard):
def handle_event(self, _):
pass
class ClockScreensaver(Screensaver):
def __init__(self):
self.font = pygame.freetype.SysFont(name="Sans", size=20)
def draw(self, screen: pygame.Surface):
text = strftime("%H:%M:%S")
screen.fill("black")
pygame.Rect(0, 0, screen.get_width(), screen.get_height())
text_rect = self.font.get_rect(text)
text_pos = pygame.Rect((screen.get_width() - text_rect.width)/2,
(screen.get_height() - text_rect.height)/2,
text_rect.width, text_rect.height)
self.font.render_to(screen, text_pos, text, fgcolor="pink")
class Button:
PRESS_OFFSET = 2
@ -161,12 +133,14 @@ class MenuBoard(IBoard):
class App:
FPS = 30
TICKS_UNTIL_SCREENSAVER = 1 * FPS
def __init__(self, urls: List[Action], bg_color: str):
def __init__(self, urls: List[Action], bg_color: str, fullscreen: bool, screensaver_delay: int):
pygame.init()
info = pygame.display.Info()
self.screen = pygame.display.set_mode((info.current_w, info.current_h), flags=pygame.FULLSCREEN)
flags = 0
if fullscreen:
flags = pygame.FULLSCREEN
self.screen = pygame.display.set_mode((info.current_w, info.current_h), flags=flags)
self.clock = pygame.time.Clock()
self.running = False
self.bg_color = bg_color
@ -175,6 +149,7 @@ class App:
self.board: IBoard = MenuBoard(self.get_screen_rect(), buttons, bg_color)
self.task_q = Queue()
self.screensaver = ClockScreensaver()
self.TICKS_UNTIL_SCREENSAVER = screensaver_delay * self.FPS
self.screensaver_ticks = self.TICKS_UNTIL_SCREENSAVER
def get_screen_rect(self) -> pygame.Rect:
@ -262,6 +237,9 @@ def get_url_defs(config_data: dict) -> List[Action]:
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("config_path", help="Path to the config file.", type=str)
parser.add_argument("--no-fullscreen", help="Fullscreen", action='store_true')
parser.add_argument("--screensaver-delay", help="Screensaver delay, in seconds. Default=30",
type=int, default=30)
args = parser.parse_args()
url_defs: List[Action] = []
@ -269,5 +247,6 @@ if __name__ == '__main__':
data = json.load(f)
url_defs = get_url_defs(data)
app = App(url_defs, bg_color=data["bg_color"])
app = App(url_defs, bg_color=data["bg_color"], fullscreen=not args.no_fullscreen,
screensaver_delay=args.screensaver_delay)
app.loop()

37
screensavers.py Normal file
View File

@ -0,0 +1,37 @@
#!/usr/bin/env python3
from time import strftime
from typing import Tuple
import pygame
from iboard import IBoard
class Screensaver(IBoard):
def handle_event(self, _):
pass
class ClockScreensaver(Screensaver):
def __init__(self):
self.font = pygame.freetype.SysFont(name="Sans", size=40)
self.dx = 1
self.dy = 1
self.text_xy: Tuple[int, int] = (0, 0)
def draw(self, screen: pygame.Surface):
text = strftime("%H:%M:%S")
screen.fill("black")
pygame.Rect(0, 0, screen.get_width(), screen.get_height())
text_rect = self.font.get_rect(text)
if ((self.text_xy[0] + self.dx + text_rect.width) > screen.get_width()) or \
((self.text_xy[0] + self.dx) < 0):
self.dx *= -1
if ((self.text_xy[1] + self.dy + text_rect.height) > screen.get_height()) or \
((self.text_xy[1] + self.dy) < 0):
self.dy *= -1
self.text_xy = (self.text_xy[0] + self.dx, self.text_xy[1] + self.dy)
text_pos = pygame.Rect(self.text_xy[0], self.text_xy[1],
text_rect.width, text_rect.height)
self.font.render_to(screen, text_pos, text, fgcolor="pink")