mirror of https://git.sr.ht/~michalr/menu
Some initial buttons
This commit is contained in:
parent
516844ee21
commit
7084a51b0a
59
menu.py
59
menu.py
|
@ -1,9 +1,16 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import math
|
||||||
|
import sys
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from typing import Tuple, Callable
|
from typing import Tuple, Callable, TypedDict, List
|
||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
|
import pygame.freetype
|
||||||
|
|
||||||
|
|
||||||
|
class ButtonDef(TypedDict):
|
||||||
|
text: str
|
||||||
|
|
||||||
|
|
||||||
class IBoard:
|
class IBoard:
|
||||||
|
@ -17,16 +24,23 @@ class IBoard:
|
||||||
|
|
||||||
|
|
||||||
class Button:
|
class Button:
|
||||||
def __init__(self, position: pygame.Rect, cbk: Callable[[], None]):
|
def __init__(self, position: pygame.Rect, text: str, cbk: Callable[[], None]):
|
||||||
self.position: pygame.Rect
|
self.position: pygame.Rect
|
||||||
self.set_position(position)
|
self.set_position(position)
|
||||||
|
self.text = text
|
||||||
self.cbk = cbk
|
self.cbk = cbk
|
||||||
|
self.font = pygame.freetype.SysFont(name="Sans", size=20)
|
||||||
|
text_rect = self.font.get_rect(self.text)
|
||||||
|
self.text_pos = pygame.Rect((self.position.left + (self.position.width - text_rect.width)/2),
|
||||||
|
(self.position.top + (self.position.height - text_rect.height)/2),
|
||||||
|
text_rect.width, text_rect.height)
|
||||||
|
|
||||||
def set_position(self, position: pygame.Rect):
|
def set_position(self, position: pygame.Rect):
|
||||||
self.position = position
|
self.position = position
|
||||||
|
|
||||||
def draw(self, screen: pygame.Surface):
|
def draw(self, screen: pygame.Surface):
|
||||||
pygame.draw.rect(screen, "black", self.position, 0)
|
pygame.draw.rect(screen, "black", self.position, 0)
|
||||||
|
self.font.render_to(screen, self.text_pos, self.text, fgcolor="pink")
|
||||||
|
|
||||||
def pos_is_inside(self, pos: Tuple) -> bool:
|
def pos_is_inside(self, pos: Tuple) -> bool:
|
||||||
return (self.position.left < pos[0] and (self.position.left + self.position.width) > pos[0]) and \
|
return (self.position.left < pos[0] and (self.position.left + self.position.width) > pos[0]) and \
|
||||||
|
@ -39,9 +53,37 @@ class Button:
|
||||||
|
|
||||||
|
|
||||||
class MenuBoard(IBoard):
|
class MenuBoard(IBoard):
|
||||||
def __init__(self):
|
BUTTON_MARGINS = 10
|
||||||
self.buttons = [Button(pygame.Rect(10, 10, 30, 30), lambda: print("siema")),
|
|
||||||
Button(pygame.Rect(50, 10, 30, 30), lambda: print("elo"))]
|
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)))
|
||||||
|
button_positions = self.generate_button_positions(screen_rect)
|
||||||
|
self.buttons = list(map(lambda d: Button(next(button_positions),
|
||||||
|
f"Button {d['text']}",
|
||||||
|
lambda: print(d['text'])), buttons))
|
||||||
|
|
||||||
|
def generate_button_positions(self, screen_rect: pygame.Rect):
|
||||||
|
current_button_row = 0
|
||||||
|
current_button_col = 0
|
||||||
|
button_width = math.floor((screen_rect.width - (self.cols + 1) * self.BUTTON_MARGINS) / self.cols)
|
||||||
|
button_height = math.floor((screen_rect.height - (self.rows + 1) * self.BUTTON_MARGINS) / self.rows)
|
||||||
|
while (current_button_row * current_button_col) < (self.cols * self.rows):
|
||||||
|
top = self.BUTTON_MARGINS + (current_button_row * (button_height + self.BUTTON_MARGINS))
|
||||||
|
left = self.BUTTON_MARGINS + (current_button_col * (button_width + self.BUTTON_MARGINS))
|
||||||
|
current_button_col += 1
|
||||||
|
if current_button_col >= self.cols:
|
||||||
|
current_button_col = 0
|
||||||
|
current_button_row += 1
|
||||||
|
yield pygame.Rect(left, top, button_width, button_height)
|
||||||
|
|
||||||
|
|
||||||
def handle_event(self, event: pygame.event.Event):
|
def handle_event(self, event: pygame.event.Event):
|
||||||
for b in self.buttons:
|
for b in self.buttons:
|
||||||
|
@ -54,13 +96,14 @@ class MenuBoard(IBoard):
|
||||||
|
|
||||||
|
|
||||||
class App:
|
class App:
|
||||||
def __init__(self):
|
def __init__(self, btns: 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)
|
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
|
||||||
self.board: IBoard = MenuBoard()
|
self.board: IBoard = MenuBoard(pygame.Rect(0, 0, info.current_w, info.current_h),
|
||||||
|
list(map(lambda t: ButtonDef(text=f"{t}"), list(range(btns)))))
|
||||||
|
|
||||||
def loop(self):
|
def loop(self):
|
||||||
self.running = True
|
self.running = True
|
||||||
|
@ -81,5 +124,5 @@ class App:
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = App()
|
app = App(int(sys.argv[1]))
|
||||||
app.loop()
|
app.loop()
|
||||||
|
|
Loading…
Reference in New Issue