LUIBlockText.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. from panda3d.core import LVecBase2i
  2. from LUIObject import LUIObject
  3. from LUILabel import LUILabel
  4. from LUIInitialState import LUIInitialState
  5. __all__ = ["LUIBlockText"]
  6. class LUIBlockText(LUIObject):
  7. """ Small helper class to format labels into paragraphs.
  8. Uses LUILabels internally """
  9. def __init__(self, **kwargs):
  10. """ Creates a new block of text. """
  11. LUIObject.__init__(self)
  12. LUIInitialState.init(self, kwargs)
  13. self._cursor = LVecBase2i(0)
  14. self._last_size = 14
  15. self.labels = []
  16. def clear(self):
  17. """ Removes all text from this label and resets it to the initial state.
  18. This will also detach the sub-labels from this label. """
  19. self._cursor.set(0, 0)
  20. self.labels = []
  21. self.remove_all_children()
  22. def newline(self, font_size=None):
  23. """ Moves the cursor to the next line. The font size controls how much
  24. the cursor will move. By default, the font size of the last added text
  25. is used, or if no text was added yet, a size of 14."""
  26. self._cursor.x = 0
  27. if font_size is None:
  28. font_size = self._last_size
  29. self._cursor.y += font_size + 2
  30. def add(self, *args, **kwargs):
  31. """ Appends a new text. The arguments are equal to the arguments of
  32. LUILabel. The arguments shouldn't contain information about the
  33. placement like top_left, or center_vertical, since the labels are
  34. placed at explicit positions. """
  35. self._last_size = kwargs.get("font_size", 14)
  36. label = LUILabel(parent=self, left=self._cursor.x, top=self._cursor.y, width=self.get_width(),
  37. *args, **kwargs)
  38. self.labels.append(label)
  39. # This is a bit of a hack, we should use a horizontal layout, but we
  40. # don't for performance reasons.
  41. self._cursor.y += label.text_handle.height
  42. # After every paragraph, we add a new line.
  43. self.newline()
  44. def set_text(self, text):
  45. """ Replaces the text with new text """
  46. self.clear()
  47. self.add(text=text)
  48. def update_height(self):
  49. """ Updates the height of the element, adding a newline to the end of
  50. every paragraph """
  51. top = 0
  52. for child in self.labels:
  53. child.top = top
  54. top += child._text.height
  55. # Newline
  56. top += self._last_size + 2
  57. def set_wrap(self, wrap):
  58. """ Sets text wrapping for the element. Wrapping breaks lines on
  59. spaces, and breaks words if the word is longer than the line
  60. length. """
  61. for child in self.children:
  62. for c in child.children:
  63. c.set_wordwrap(wrap)
  64. self.update_height()
  65. def set_width(self, width):
  66. """ Sets the width of this element, and turns on wrapping. """
  67. for child in self.children:
  68. child.set_width(width)
  69. # Need to force an update to the text when the width changes.
  70. for c in child.children:
  71. c.set_wordwrap(True)
  72. self.update_height()