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 argparse
import json import json
from enum import Enum, auto from enum import Enum, auto
from time import sleep, strftime from time import sleep
from threading import Thread from threading import Thread
from queue import Queue, Empty from queue import Queue, Empty
from abc import abstractmethod
from typing import Tuple, Callable, TypedDict, List from typing import Tuple, Callable, TypedDict, List
import pygame import pygame
import pygame.freetype import pygame.freetype
import requests import requests
from iboard import IBoard
from screensavers import ClockScreensaver
class ButtonDef(TypedDict): class ButtonDef(TypedDict):
text: str text: str
@ -31,36 +33,6 @@ class Action(TypedDict):
param: str 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: class Button:
PRESS_OFFSET = 2 PRESS_OFFSET = 2
@ -161,12 +133,14 @@ class MenuBoard(IBoard):
class App: class App:
FPS = 30 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() pygame.init()
info = pygame.display.Info() 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.clock = pygame.time.Clock()
self.running = False self.running = False
self.bg_color = bg_color self.bg_color = bg_color
@ -175,6 +149,7 @@ class App:
self.board: IBoard = MenuBoard(self.get_screen_rect(), buttons, bg_color) self.board: IBoard = MenuBoard(self.get_screen_rect(), buttons, bg_color)
self.task_q = Queue() self.task_q = Queue()
self.screensaver = ClockScreensaver() self.screensaver = ClockScreensaver()
self.TICKS_UNTIL_SCREENSAVER = screensaver_delay * self.FPS
self.screensaver_ticks = self.TICKS_UNTIL_SCREENSAVER self.screensaver_ticks = self.TICKS_UNTIL_SCREENSAVER
def get_screen_rect(self) -> pygame.Rect: def get_screen_rect(self) -> pygame.Rect:
@ -262,6 +237,9 @@ def get_url_defs(config_data: dict) -> List[Action]:
if __name__ == '__main__': if __name__ == '__main__':
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("config_path", help="Path to the config file.", type=str) 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() args = parser.parse_args()
url_defs: List[Action] = [] url_defs: List[Action] = []
@ -269,5 +247,6 @@ if __name__ == '__main__':
data = json.load(f) data = json.load(f)
url_defs = get_url_defs(data) 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() 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")