mirror of https://git.sr.ht/~michalr/menu
Animated screensaver, command line args for ssaver delay and fullscreen
This commit is contained in:
parent
607057868d
commit
598c882076
|
@ -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
51
menu.py
|
@ -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()
|
||||
|
|
|
@ -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")
|
Loading…
Reference in New Issue