81 lines
2.5 KiB
Python
81 lines
2.5 KiB
Python
"""
|
|
This is the most complicated Doodle-derived class.
|
|
|
|
Like shapes, the interface is mostly identical to Line.
|
|
If you are mainly trying to understand the interfaces it is
|
|
safe to skip this one.
|
|
|
|
There is some more complexity here because fonts need to be
|
|
pre-rendered. This means that when `text` is called, an internal
|
|
cached copy of the font already drawn to a temporary piece of memory
|
|
"surface" in graphics programming parlance.
|
|
|
|
This is an example of a type of class where when a property changes
|
|
some additional computation can be done to precompute/cache
|
|
some expensive logic.
|
|
|
|
Look at _render() for more.
|
|
"""
|
|
import pygame
|
|
from .doodles import Doodle
|
|
from .world import world
|
|
|
|
|
|
class Text(Doodle):
|
|
def __init__(self, parent=None):
|
|
"""
|
|
A text object stores a reference to a pre-loaded font,
|
|
the text to be drawn, and an internal `_rendered` object
|
|
that *can* be used to store the cached text.
|
|
|
|
Not all implementations will require pre-rendering, but
|
|
Pygame (the first implementation) does, so it is necessary
|
|
for the interface as written here.
|
|
|
|
When drawn, text will be centered at `pos`
|
|
"""
|
|
super().__init__(parent)
|
|
self._text = ""
|
|
self._rendered = None # the surface we pre-render the text to
|
|
self._font = None
|
|
|
|
def __repr__(self):
|
|
return f"Text(pos={self.pos_vec}, text={self._text}, parent={self._parent})"
|
|
|
|
def draw(self):
|
|
world.draw_engine.text_draw(self)
|
|
|
|
def text(self, text: str) -> "Doodle":
|
|
"""
|
|
A setter for the text.
|
|
|
|
This is the only place text can change,
|
|
so we can pre-render the surface here.
|
|
"""
|
|
self._text = text
|
|
self._render()
|
|
return self
|
|
|
|
def _render(self):
|
|
"""
|
|
This function needs to set the _rendered property.
|
|
|
|
_rendered may be relied upon by draw_engine.draw_text.
|
|
|
|
Text needs to be rendered once on change to be performant.
|
|
Doing this in draw would be much slower since it is called
|
|
much more often than the text changes.
|
|
|
|
(draw called ~60 times per second, _render only called when
|
|
text is updated.)
|
|
"""
|
|
if not self._font:
|
|
self._font = world.draw_engine.get_font() # default font
|
|
self._rendered = world.draw_engine.text_render(
|
|
self._text, self._font, self._color
|
|
)
|
|
|
|
def font(self, font: str) -> "Doodle":
|
|
self._font = world.draw_engine.get_font(font)
|
|
return self
|