mirror of https://git.sr.ht/~michalr/menu
Read configuration from file
This commit is contained in:
parent
64ea237071
commit
cd287083a0
|
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
44
menu.py
44
menu.py
|
@ -1,7 +1,8 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import math
|
import math
|
||||||
import sys
|
import argparse
|
||||||
|
import json
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from queue import Queue, Empty
|
from queue import Queue, Empty
|
||||||
|
@ -17,6 +18,11 @@ class ButtonDef(TypedDict):
|
||||||
cbk: Callable[[], None]
|
cbk: Callable[[], None]
|
||||||
|
|
||||||
|
|
||||||
|
class UrlDef(TypedDict):
|
||||||
|
label: str
|
||||||
|
url: str
|
||||||
|
|
||||||
|
|
||||||
class IBoard:
|
class IBoard:
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def draw(self, screen: pygame.Surface):
|
def draw(self, screen: pygame.Surface):
|
||||||
|
@ -77,15 +83,11 @@ class MenuBoard(IBoard):
|
||||||
BUTTON_MARGINS = 10
|
BUTTON_MARGINS = 10
|
||||||
|
|
||||||
def __init__(self, screen_rect: pygame.Rect, buttons: List[ButtonDef]):
|
def __init__(self, screen_rect: pygame.Rect, buttons: List[ButtonDef]):
|
||||||
self.rows: int
|
self.rows = math.floor(math.sqrt(len(buttons)))
|
||||||
self.cols: int
|
self.cols = math.ceil(math.sqrt(len(buttons)))
|
||||||
if len(buttons) == 2:
|
if (self.rows * self.cols) < len(buttons):
|
||||||
# special case which doesn't seem to fit into the sqrt
|
# extra row if buttons don't fit
|
||||||
self.rows = 1
|
self.rows += 1
|
||||||
self.cols = 2
|
|
||||||
else:
|
|
||||||
self.rows = math.ceil(math.sqrt(len(buttons)))
|
|
||||||
self.cols = math.ceil(math.sqrt(len(buttons)))
|
|
||||||
button_positions = self.generate_button_positions(screen_rect)
|
button_positions = self.generate_button_positions(screen_rect)
|
||||||
self.buttons = list(map(lambda d: Button(next(button_positions),
|
self.buttons = list(map(lambda d: Button(next(button_positions),
|
||||||
f"Button {d['text']}",
|
f"Button {d['text']}",
|
||||||
|
@ -116,13 +118,13 @@ class MenuBoard(IBoard):
|
||||||
|
|
||||||
|
|
||||||
class App:
|
class App:
|
||||||
def __init__(self, btns: int):
|
def __init__(self, urls: List[UrlDef]):
|
||||||
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)
|
self.screen = pygame.display.set_mode((info.current_w, info.current_h), flags=pygame.FULLSCREEN)
|
||||||
self.clock = pygame.time.Clock()
|
self.clock = pygame.time.Clock()
|
||||||
self.running = False
|
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))
|
buttons.append(ButtonDef(text="Exit", cbk=self.quit))
|
||||||
self.board: IBoard = MenuBoard(self.get_screen_rect(), buttons)
|
self.board: IBoard = MenuBoard(self.get_screen_rect(), buttons)
|
||||||
self.task_q = Queue()
|
self.task_q = Queue()
|
||||||
|
@ -130,7 +132,7 @@ class App:
|
||||||
def get_screen_rect(self) -> pygame.Rect:
|
def get_screen_rect(self) -> pygame.Rect:
|
||||||
return pygame.Rect(0, 0, self.screen.get_width(), self.screen.get_height())
|
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():
|
def impl():
|
||||||
previous_board = self.board
|
previous_board = self.board
|
||||||
|
|
||||||
|
@ -143,7 +145,7 @@ class App:
|
||||||
|
|
||||||
process_thr = Thread(target=thr_fun)
|
process_thr = Thread(target=thr_fun)
|
||||||
process_thr.start()
|
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
|
return impl
|
||||||
|
|
||||||
def loop(self):
|
def loop(self):
|
||||||
|
@ -170,6 +172,18 @@ class App:
|
||||||
self.running = False
|
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__':
|
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()
|
app.loop()
|
||||||
|
|
Loading…
Reference in New Issue