mirror of https://git.sr.ht/~michalr/menu
Multiline text on buttons and messages
This commit is contained in:
parent
75659d8142
commit
0542a3a12f
|
@ -1,10 +1,10 @@
|
||||||
{
|
{
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{
|
||||||
"label": "example 1",
|
"label": "example 1\nMultiline!",
|
||||||
"action_type": "MSG",
|
"action_type": "MSG",
|
||||||
"action_param": "1",
|
"action_param": "1",
|
||||||
"action_message": "Doing example 1"
|
"action_message": "Doing example 1\nwith\nmultiple\nlines"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "example 2",
|
"label": "example 2",
|
||||||
|
|
38
menu.py
38
menu.py
|
@ -34,18 +34,40 @@ class Action(TypedDict):
|
||||||
action_message: Optional[str]
|
action_message: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
class MultilineText:
|
||||||
|
VMARGIN = 10
|
||||||
|
|
||||||
|
def __init__(self, text: str, font: pygame.freetype.Font):
|
||||||
|
self.lines = text.splitlines()
|
||||||
|
self.font = font
|
||||||
|
self.all_rects = list(map(self.font.get_rect, self.lines))
|
||||||
|
self.width = max(map(lambda r: r.width, self.all_rects))
|
||||||
|
self.height = sum(map(lambda r: r.height + self.VMARGIN, self.all_rects))
|
||||||
|
|
||||||
|
def get_rect(self) -> pygame.Rect:
|
||||||
|
return pygame.Rect(0, 0, self.width, self.height)
|
||||||
|
|
||||||
|
def render_to(self, screen: pygame.Surface, pos: pygame.Rect, fgcolor: pygame.Color):
|
||||||
|
current_top = pos.top
|
||||||
|
for line, rect in zip(self.lines, self.all_rects):
|
||||||
|
self.font.render_to(screen,
|
||||||
|
pygame.Rect(pos.left, current_top, rect.width, rect.height),
|
||||||
|
line, fgcolor="black")
|
||||||
|
current_top += rect.top + self.VMARGIN
|
||||||
|
|
||||||
|
|
||||||
class Button:
|
class Button:
|
||||||
PRESS_OFFSET = 2
|
PRESS_OFFSET = 2
|
||||||
HOVER_ANIMATION_STEPS = 5
|
HOVER_ANIMATION_STEPS = 5
|
||||||
|
|
||||||
def __init__(self, position: pygame.Rect, text: str, theme: Dict, cbk: Callable[[], None]):
|
def __init__(self, position: pygame.Rect, text: str, theme: Dict, cbk: Callable[[], None]):
|
||||||
|
font = pygame.freetype.SysFont(name=theme["btn_font_face"], size=int(theme["btn_font_size"]))
|
||||||
self.position: pygame.Rect
|
self.position: pygame.Rect
|
||||||
self.set_position(position)
|
self.set_position(position)
|
||||||
self.text = text
|
self.label = MultilineText(text, font)
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.cbk = cbk
|
self.cbk = cbk
|
||||||
self.font = pygame.freetype.SysFont(name=theme["btn_font_face"], size=int(theme["btn_font_size"]))
|
text_rect = self.label.get_rect()
|
||||||
text_rect = self.font.get_rect(self.text)
|
|
||||||
self.text_pos = pygame.Rect((self.position.left + (self.position.width - text_rect.width)/2),
|
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),
|
(self.position.top + (self.position.height - text_rect.height)/2),
|
||||||
text_rect.width, text_rect.height)
|
text_rect.width, text_rect.height)
|
||||||
|
@ -88,7 +110,7 @@ class Button:
|
||||||
|
|
||||||
def draw(self, screen: pygame.Surface):
|
def draw(self, screen: pygame.Surface):
|
||||||
pygame.draw.rect(screen, self.get_bg_color(), self.get_position(), 0)
|
pygame.draw.rect(screen, self.get_bg_color(), self.get_position(), 0)
|
||||||
self.font.render_to(screen, self.get_text_pos(), self.text, fgcolor=self.theme["btn_text_color"])
|
self.label.render_to(screen, self.get_text_pos(), self.theme["btn_text_color"])
|
||||||
|
|
||||||
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 \
|
||||||
|
@ -102,9 +124,9 @@ class Button:
|
||||||
|
|
||||||
class MessageBoard(IBoard):
|
class MessageBoard(IBoard):
|
||||||
def __init__(self, screen_rect: pygame.Rect, text: str, theme: Dict):
|
def __init__(self, screen_rect: pygame.Rect, text: str, theme: Dict):
|
||||||
self.text = text
|
font = pygame.freetype.SysFont(name=theme["message_font_face"], size=int(theme["message_font_size"]))
|
||||||
self.font = pygame.freetype.SysFont(name=theme["message_font_face"], size=int(theme["message_font_size"]))
|
self.label = MultilineText(text, font)
|
||||||
text_rect = self.font.get_rect(self.text)
|
text_rect = self.label.get_rect()
|
||||||
self.text_pos = pygame.Rect((screen_rect.left + (screen_rect.width - text_rect.width)/2),
|
self.text_pos = pygame.Rect((screen_rect.left + (screen_rect.width - text_rect.width)/2),
|
||||||
(screen_rect.top + (screen_rect.height - text_rect.height)/2),
|
(screen_rect.top + (screen_rect.height - text_rect.height)/2),
|
||||||
text_rect.width, text_rect.height)
|
text_rect.width, text_rect.height)
|
||||||
|
@ -117,7 +139,7 @@ class MessageBoard(IBoard):
|
||||||
def draw(self, screen: pygame.Surface, force_redraw: bool):
|
def draw(self, screen: pygame.Surface, force_redraw: bool):
|
||||||
if not self.was_drawn_already or force_redraw:
|
if not self.was_drawn_already or force_redraw:
|
||||||
screen.fill(self.theme["message_bg_color"])
|
screen.fill(self.theme["message_bg_color"])
|
||||||
self.font.render_to(screen, self.text_pos, self.text, fgcolor=self.theme["message_text_color"])
|
self.label.render_to(screen, self.text_pos, fgcolor=self.theme["message_text_color"])
|
||||||
self.was_drawn_already = True
|
self.was_drawn_already = True
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue