diff --git a/example_config.json b/example_config.json new file mode 100644 index 0000000..2884911 --- /dev/null +++ b/example_config.json @@ -0,0 +1,24 @@ +{ + "urls": [ + { + "label": "example 1", + "url": "http://example.com" + }, + { + "label": "example 2", + "url": "http://example.com" + }, + { + "label": "example 3", + "url": "http://example.com" + }, + { + "label": "example 4", + "url": "http://example.com" + }, + { + "label": "example 5", + "url": "http://example.com" + } + ] +} \ No newline at end of file diff --git a/menu.py b/menu.py index 2609cb9..84c0e14 100644 --- a/menu.py +++ b/menu.py @@ -1,7 +1,8 @@ #!/usr/bin/env python3 import math -import sys +import argparse +import json from time import sleep from threading import Thread from queue import Queue, Empty @@ -17,6 +18,11 @@ class ButtonDef(TypedDict): cbk: Callable[[], None] +class UrlDef(TypedDict): + label: str + url: str + + class IBoard: @abstractmethod def draw(self, screen: pygame.Surface): @@ -77,15 +83,11 @@ class MenuBoard(IBoard): BUTTON_MARGINS = 10 def __init__(self, screen_rect: pygame.Rect, buttons: List[ButtonDef]): - self.rows: int - self.cols: int - if len(buttons) == 2: - # special case which doesn't seem to fit into the sqrt - self.rows = 1 - self.cols = 2 - else: - self.rows = math.ceil(math.sqrt(len(buttons))) - self.cols = math.ceil(math.sqrt(len(buttons))) + self.rows = math.floor(math.sqrt(len(buttons))) + self.cols = math.ceil(math.sqrt(len(buttons))) + if (self.rows * self.cols) < len(buttons): + # extra row if buttons don't fit + self.rows += 1 button_positions = self.generate_button_positions(screen_rect) self.buttons = list(map(lambda d: Button(next(button_positions), f"Button {d['text']}", @@ -116,13 +118,13 @@ class MenuBoard(IBoard): class App: - def __init__(self, btns: int): + def __init__(self, urls: List[UrlDef]): pygame.init() info = pygame.display.Info() self.screen = pygame.display.set_mode((info.current_w, info.current_h), flags=pygame.FULLSCREEN) self.clock = pygame.time.Clock() self.running = False - buttons = list(map(lambda t: ButtonDef(text=f"{t}", cbk=self.button_press_handler(str(t))), list(range(btns)))) + buttons = list(map(lambda u: ButtonDef(text=u['label'], cbk=self.button_press_handler(u['url'])), urls)) buttons.append(ButtonDef(text="Exit", cbk=self.quit)) self.board: IBoard = MenuBoard(self.get_screen_rect(), buttons) self.task_q = Queue() @@ -130,7 +132,7 @@ class App: def get_screen_rect(self) -> pygame.Rect: return pygame.Rect(0, 0, self.screen.get_width(), self.screen.get_height()) - def button_press_handler(self, text: str) -> Callable[[], None]: + def button_press_handler(self, url: str) -> Callable[[], None]: def impl(): previous_board = self.board @@ -143,7 +145,7 @@ class App: process_thr = Thread(target=thr_fun) process_thr.start() - self.board = MessageBoard(self.get_screen_rect(), f"Wait: {text}") + self.board = MessageBoard(self.get_screen_rect(), f"Fetching: {url}") return impl def loop(self): @@ -170,6 +172,18 @@ class App: self.running = False +def get_config(path: str) -> List[UrlDef]: + url_defs = [] + with open(path, "rb") as f: + data = json.load(f) + for d in data['urls']: + url_defs.append(UrlDef(label=d['label'], url=d['url'])) + return url_defs + + if __name__ == '__main__': - app = App(int(sys.argv[1])) + parser = argparse.ArgumentParser() + parser.add_argument("config_path", help="Path to the config file.", type=str) + args = parser.parse_args() + app = App(get_config(args.config_path)) app.loop()