From 60271e416476e20249227afa56d7af7615af7f0b Mon Sep 17 00:00:00 2001 From: EKNr1 Date: Mon, 25 Mar 2024 14:24:13 +0100 Subject: [PATCH] Made a better multiline text class. --- pg.py | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/pg.py b/pg.py index a6e1700..568ba12 100644 --- a/pg.py +++ b/pg.py @@ -249,8 +249,9 @@ 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: +class MultilineTextOld: """ + Early version of multiline text. 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. @@ -328,6 +329,107 @@ class MultilineText: return surface +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 the widest 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): + self.text = text + self.font = font + self.color = color + self.max_width = max_width + + self.surface = self.generate_surface() + + def generate_surface(self): + lines = [] + line = "" + + length = 1 + + if self.max_width is None: + for char in self.text: + if char == "\n": + lines.append(line) + length = 1 + line = "" + + else: + line += char + + length += 1 + + else: + for char in self.text: + if char == "\n": + lines.append(line) + + length = 1 + line = "" + + elif self.font.size(line)[0] >= self.max_width - 8: + if " " in line: + # remove last word + + words = line.split(" ") + + last_word = words[len(words) - 1] + words.pop(len(words) - 1) + + line = "" + + for word in words: # convert the list back to a string + line += word + " " + + line = line[:len(line) - 1] # remove last space character + + lines.append(line) + + line = last_word + char + + else: + lines.append(line) + + length = 1 + line = char + + else: + line += char + + length += 1 + + lines.append(line) + + texts = [] + + for line in lines: + texts.append(self.font.render(line, True, self.color)) + + if self.max_width is None: + w = max(texts, key=lambda t: t.get_width()).get_width() + + else: + w = self.max_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