From 7113e6a8c8f2fafd84aed6315acd777f63ffb56b Mon Sep 17 00:00:00 2001 From: EKNr1 Date: Fri, 22 Mar 2024 19:39:42 +0100 Subject: [PATCH] Added args parameter to all button/hover classes to be able to execute a function with arguments. --- pg.py | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 81 insertions(+), 6 deletions(-) diff --git a/pg.py b/pg.py index 7e621f8..1f0c82b 100644 --- a/pg.py +++ b/pg.py @@ -22,9 +22,10 @@ default_font = pygame.font.Font(pygame.font.get_default_font(), 16) class Hover: - def __init__(self, rect: pygame.Rect, function=None): + def __init__(self, rect: pygame.Rect, function=None, args: tuple=None): self.rect = rect self.function = function + self.args = args self.active = True @@ -34,7 +35,11 @@ class Hover: if self.rect.collidepoint((mx, my)): if not self.function is None: - self.function() + if self.args is None: + self.function() + + else: + self.function(*self.args) return True @@ -42,14 +47,15 @@ class Hover: class Button: - def __init__(self, rect: pygame.Rect, function=None, key: int=0): # key: 0 = left 1 = mouse wheel pressed 2 = right + def __init__(self, rect: pygame.Rect, function=None, args: tuple=None, key: int=0): # key: 0 = left 1 = mouse wheel pressed 2 = right self.rect = rect self.function = function + self.args = args self.key = key self.active = True - self.hover = Hover(rect, function) + self.hover = Hover(rect, function, args) if buttonlist: buttons.append(self) @@ -63,12 +69,13 @@ class Button: class TextButton: - def __init__(self, text: str, position: tuple, function=None, key: int=0, text_color: tuple=white, bg_color: tuple=gray, font: pygame.font.Font=default_font, padding: tuple=(8, 8), border_radius: int=0, line_thickness: int = 0): + def __init__(self, text: str, position: tuple, function=None, args: tuple=None, key: int=0, text_color: tuple=white, bg_color: tuple=gray, font: pygame.font.Font=default_font, padding: tuple=(8, 8), border_radius: int=0, line_thickness: int = 0): self.text = text self.position = position self.text_color = text_color self.font = font self.function = function + self.args = args self.key = key self.bg_color = bg_color self.padding = padding @@ -78,7 +85,7 @@ class TextButton: self.surface, self.size = self.generate_surface() self.rect = self.make_rect() - self.button = Button(self.rect, self.function, self.key) + self.button = Button(self.rect, self.function, args, self.key) def generate_surface(self): text_object = self.font.render(self.text, True, self.text_color) @@ -242,6 +249,74 @@ class TextInput: self.text_object = crop_surface(self.text_object, (t_width - (t_width - (t_width - self.width)), 0), (t_width - (t_width - self.width), t_height)) +class MultilineText: + """ + Creates a surface with text on it. + You can use a "\\n" to create a newline. + When the max_width parameter is set, newlines generate automatically. + When you know the width of a single character in your font, yau can set the char_width parameter. It will make the text creation a bit faster. + Use "surface.blit(multiline_text.surface, pos)" to draw it on a surface. + """ + def __init__(self, text: str, font: pygame.font.Font=default_font, color: tuple=white, max_width: int=None, char_width: int=None): + self.text = text + self.font = font + self.color = color + self.max_width = max_width + self.char_width = char_width + + if char_width is None: # get the width of a character by the font + self.char_width = font.render("A", True, white).get_width() + + self.surface = self.generate_surface() + + def generate_surface(self): + lines = [] + line = "" + + i = 0 + + if not self.char_width is None: + for char in self.text: + if char == "\n" or (i + 1) * self.char_width > self.max_width: + lines.append(line) + line = "" + + else: + line += char + + else: + for char in self.text: + if char == "\n": + lines.append(line) + line = "" + + else: + line += char + + if not lines: + lines = [line] + + texts = [] + + for line in lines: + texts.append(self.font.render(line, True, self.color)) + + w = max(texts, key=lambda t: t.get_width()).get_width() + h = texts[0].get_height() + sh = h * len(lines) + + surface = pygame.Surface((w, sh), flags=pygame.SRCALPHA) + + x, y = 0, 0 + + for text in texts: + surface.blit(text, (x, y)) + + y += h + + return surface + + def set_rot_point(img, pos): w, h = img.get_size() w, h = w * 2, h * 2