1
0
Fork 0

Some initial buttons

This commit is contained in:
Michał Rudowicz 2024-09-08 16:44:47 +02:00
parent 516844ee21
commit 7084a51b0a
1 changed files with 51 additions and 8 deletions

59
menu.py
View File

@ -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()