Quellcode für miniworlds.actors.texts.textbox

from typing import Tuple
import miniworlds.actors.parent_actor as parent_actor
import miniworlds.actors.texts.text as text
import miniworlds.actors.shapes.shapes as shapes


[Doku] class TextBox(parent_actor.ParentActor): """A multi-line text box with fixed width and height. Long lines are automatically word-wrapped to fit within the given width. Each line is rendered as a separate ``Text`` actor. Args: position: Top-left position of the text box. width: Width of the text box in pixels. height: Maximum height of the text box in pixels. text: Initial text to display (keyword argument). font_size: Font size for all lines (keyword argument, default 18). border: If truthy, a rectangle outline is drawn around the box. Examples: .. code-block:: python from miniworlds import * world = World(400, 300) box = TextBox((10, 10), 380, 200, text="Hello World! This is a long text that wraps automatically.") world.run() """
[Doku] def __init__( self, position: Tuple[float, float], width: float, height: float, **kwargs ): """Creates a text box with fixed width and height. Args: position: Top-left position of the text box. width: Maximum width in pixels before text is wrapped. height: Maximum height in pixels. border: Optional keyword argument. If truthy, draw a rectangle around the text box. font_size: Optional keyword argument. Font size used for all lines. """ super().__init__([]) self._visible: bool = False self.line_width = width self.lines_height = height text = kwargs.get("text") self.text = text if text else "" self.position = position font_size = kwargs.get("font_size") self.font_size = 18 if not font_size else font_size self.create_line_actors() border = kwargs.get("border") if border: shapes.Rectangle(position, width, height)
[Doku] def create_line(self, position, txt="") -> text.Text: """Creates a single ``Text`` actor for one rendered line. Args: position: Top-left position of the line. txt: Text content of the line. Defaults to an empty string. Returns: text.Text: The created text actor. """ lineText = text.Text(position, txt) if self.font_size != 0: lineText.font_size = self.font_size lineText.topleft = position return lineText
[Doku] def create_line_actors(self): """Builds the visible text lines for the current text box content. The text is split line by line and then wrapped after words so that no rendered line becomes wider than ``self.line_width``. Each line is stored as a child ``Text`` actor. Examples: After changing ``self.text``, call this method to rebuild all lines. """ dummy = self.create_line((0, 0)) font = dummy.costume.font_manager.font words = [ world.split(" ") for word in self.text.splitlines() ] # 2D array where each row is a list of words. x, y = self.position for line in words: line_text = "" for word in line: old_text = line_text line_text = line_text + word word_size = font.size(line_text) word_width, word_height = word_size if x + word_width >= self.line_width: line_actor = self.create_line((x, y), old_text) self.children.append(line_actor) x = self.position[0] y += word_height # Start on new row. line_text = word line_text += " " if y > self.lines_height: break line_actor = self.create_line((x, y), line_text) self.children.append(line_actor) x = self.position[0] # Reset the x. y += line_actor.height # Start on new row dummy.remove()