Mercurial > pyntnclick
diff pyntnclick/widgets/text.py @ 679:fa168b5e2624 pyntnclick
The return of the message dialog (and there was much rejoicing)
author | Neil Muller <neil@dip.sun.ac.za> |
---|---|
date | Sun, 12 Feb 2012 23:06:44 +0200 |
parents | fe7023750b20 |
children | 6892d36dad75 |
line wrap: on
line diff
--- a/pyntnclick/widgets/text.py Sun Feb 12 21:47:06 2012 +0200 +++ b/pyntnclick/widgets/text.py Sun Feb 12 23:06:44 2012 +0200 @@ -1,5 +1,8 @@ +from textwrap import wrap + import pygame from pygame.constants import SRCALPHA +from pygame.locals import MOUSEBUTTONDOWN from pyntnclick.widgets.base import Widget, Button, convert_color @@ -96,3 +99,78 @@ def draw(self, surface): super(TextButton, self).draw(surface) + + +class WrappedTextLabel(LabelWidget): + """A Label Widget that wraps the text to a given maximum width""" + + def __init__(self, rect, gd, *args, **kwargs): + self.max_width = kwargs.pop('max_width', gd.constants.screen[0] - 50) + self._wrap_width = None + self._text_lines = None + super(WrappedTextLabel, self).__init__(rect, gd, *args, **kwargs) + self.prepare() + + def prepare(self): + if self._wrap_width is None: + # Start without wrapping + self._wrap_width = len(self.text) + 1 + self._text_lines = [self.text] + + self.font = self.resource.get_font(self.fontname, self.fontsize) + self.color = convert_color(self.color) + self._render() + self.text_rect = self.surface.get_rect() + width, height = self.surface.get_rect().size + while width > self.max_width: + # Very simplistic approach + self._wrap_width = self._wrap_width / 2 + self._text_lines = wrap(self.text, self._wrap_width) + self._render() + width, height = self.surface.get_rect().size + self.rect.width = max(self.rect.width, width) + self.rect.height = max(self.rect.height, height) + + self.rect.width += 2 * self.padding + self.rect.height += 2 * self.padding + new_surface = pygame.Surface(self.rect.size) + new_surface = new_surface.convert_alpha() + new_surface.fill(self.bg_color) + new_surface.blit(self.surface, self.surface.get_rect().move( + (self.padding, self.padding))) + if self.border: + pygame.draw.rect(new_surface, self.border_color, + new_surface.get_rect(), + self.border) + self.surface = new_surface + + def _render(self): + surfaces = [] + width = 0 + height = 0 + for line in self._text_lines: + line_surf = self.font.render(line, True, self.color, + self.bg_color) + surfaces.append(line_surf) + width = max(line_surf.get_rect().width, width) + height += line_surf.get_rect().height + self.surface = pygame.Surface((width, height)) + self.surface.fill(self.bg_color) + height = 0 + for line_surf in surfaces: + rect = pygame.Rect((0, height), (line_surf.get_rect().size)) + self.surface.blit(line_surf, rect) + height += line_surf.get_rect().height + + +class ModalWrappedTextLabel(WrappedTextLabel): + """A WrappedTextLabel that removes itself when a mouse + click occurs""" + def __init__(self, rect, gd, *args, **kwargs): + super(ModalWrappedTextLabel, self).__init__(rect, gd, *args, **kwargs) + self.add_callback(MOUSEBUTTONDOWN, self.close) + + def close(self, ev, widget): + if self.parent: + self.parent.remove(self) + return True