Mercurial > boomslang
diff pyntnclick/widgets/__init__.py @ 555:c0474fe18b96 pyntnclick
Copy in widgets from mamba (currently unused)
author | Stefano Rivera <stefano@rivera.za.net> |
---|---|
date | Sat, 11 Feb 2012 14:09:46 +0200 |
parents | pyntnclick/widgets.py@38fb04728ac5 |
children | 1b1ab71535bd |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyntnclick/widgets/__init__.py Sat Feb 11 14:09:46 2012 +0200 @@ -0,0 +1,217 @@ +# widgets.py +# Copyright Boomslang team, 2010 (see COPYING File) + +# XXX: This should be deleted when albow is gone + +"""Custom Albow widgets""" + +import textwrap + +import albow.controls +import albow.menu +from albow.resource import get_font, get_image +from pygame.color import Color +from pygame.rect import Rect +from pygame.draw import lines as draw_lines +from pygame import mouse + +from pyntnclick.constants import BUTTON_SIZE +from pyntnclick.cursor import CursorWidget + + +class BoomLabel(albow.controls.Label): + + trim_line_top = 0 + + def __init__(self, text, width=None, **kwds): + albow.controls.Label.__init__(self, text, width, **kwds) + w, h = self.size + h -= self.trim_line_top * len(self.text.split('\n')) + self.size = (w, h) + + def set_margin(self, margin): + """Add a set_margin method that recalculates the label size""" + old_margin = self.margin + w, h = self.size + d = margin - old_margin + self.margin = margin + self.size = (w + 2 * d, h + 2 * d) + + def draw_all(self, surface): + bg_color = self.bg_color + self.bg_color = None + if bg_color is not None: + new_surface = surface.convert_alpha() + new_surface.fill(bg_color) + surface.blit(new_surface, surface.get_rect()) + albow.controls.Label.draw_all(self, surface) + self._draw_all_no_bg(surface) + self.bg_color = bg_color + + def _draw_all_no_bg(self, surface): + pass + + def draw_with(self, surface, fg, _bg=None): + m = self.margin + align = self.align + width = surface.get_width() + y = m + lines = self.text.split("\n") + font = self.font + dy = font.get_linesize() - self.trim_line_top + for line in lines: + image = font.render(line, True, fg) + r = image.get_rect() + image = image.subsurface(r.clip(r.move(0, self.trim_line_top))) + r.top = y + if align == 'l': + r.left = m + elif align == 'r': + r.right = width - m + else: + r.centerx = width // 2 + surface.blit(image, r) + y += dy + + +class BoomButton(BoomLabel): + + def __init__(self, text, action, screen): + super(BoomButton, self).__init__(text, font=get_font(20, 'Vera.ttf'), + margin=4) + self.bg_color = (0, 0, 0) + self._frame_color = Color(50, 50, 50) + self.action = action + self.screen = screen + + def mouse_down(self, event): + self.action() + self.screen.state_widget.mouse_move(event) + + def mouse_move(self, event): + self.screen.state.highlight_override = True + + def draw(self, surface): + super(BoomButton, self).draw(surface) + r = surface.get_rect() + w = 2 + top, bottom, left, right = r.top, r.bottom, r.left, r.right + draw_lines(surface, self._frame_color, False, [ + (left, bottom), (left, top), (right - w, top), (right - w, bottom) + ], w) + + +class MessageDialog(BoomLabel, CursorWidget): + + def __init__(self, screen, text, wrap_width, style=None, **kwds): + CursorWidget.__init__(self, screen) + self.set_style(style) + paras = text.split("\n\n") + text = "\n".join([textwrap.fill(para, wrap_width) for para in paras]) + BoomLabel.__init__(self, text, **kwds) + + def set_style(self, style): + self.set_margin(5) + self.border_width = 1 + self.border_color = (0, 0, 0) + self.bg_color = (127, 127, 127) + self.fg_color = (0, 0, 0) + if style == "JIM": + self.set(font=get_font(20, "Monospace.ttf")) + self.trim_line_top = 10 + self.bg_color = Color(255, 175, 127, 191) + self.fg_color = (0, 0, 0) + self.border_color = (127, 15, 0) + + def draw_all(self, surface): + root_surface = self.get_root().surface + overlay = root_surface.convert_alpha() + overlay.fill(Color(0, 0, 0, 191)) + root_surface.blit(overlay, (0, 0)) + BoomLabel.draw_all(self, surface) + + def _draw_all_no_bg(self, surface): + CursorWidget.draw_all(self, surface) + + def mouse_down(self, event): + self.dismiss() + self.screen.state_widget._mouse_move(mouse.get_pos()) + for widget in self.screen.state_widget.subwidgets: + widget._mouse_move(mouse.get_pos()) + + def cursor_highlight(self): + return False + + +class HandButton(albow.controls.Image): + """The fancy hand button for the widget""" + + def __init__(self, action): + # FIXME: Yes, please. + this_image = get_image('items', 'hand.png') + albow.controls.Image.__init__(self, image=this_image) + self.action = action + self.set_rect(Rect(0, 0, BUTTON_SIZE, BUTTON_SIZE)) + + def mouse_down(self, event): + self.action() + + +class PopupMenuButton(albow.controls.Button): + + def __init__(self, text, action): + albow.controls.Button.__init__(self, text, action) + + self.font = get_font(16, 'Vera.ttf') + self.set_rect(Rect(0, 0, BUTTON_SIZE, BUTTON_SIZE)) + self.margin = (BUTTON_SIZE - self.font.get_linesize()) / 2 + + +class PopupMenu(albow.menu.Menu, CursorWidget): + + def __init__(self, screen): + CursorWidget.__init__(self, screen) + self.screen = screen + self.shell = screen.shell + items = [ + ('Quit Game', 'quit'), + ('Exit to Main Menu', 'main_menu'), + ] + # albow.menu.Menu ignores title string + albow.menu.Menu.__init__(self, None, items) + self.font = get_font(16, 'Vera.ttf') + + def show_menu(self): + """Call present, with the correct position""" + item_height = self.font.get_linesize() + menu_top = 600 - (len(self.items) * item_height + BUTTON_SIZE) + item = self.present(self.shell, (0, menu_top)) + if item > -1: + # A menu item needs to be invoked + self.invoke_item(item) + + +class BoomImageButton(albow.controls.Image): + """The fancy image button for the screens""" + + FOLDER = None + + def __init__(self, filename, x, y, action, enable=None): + this_image = get_image(self.FOLDER, filename) + albow.controls.Image.__init__(self, image=this_image) + self.action = action + self.set_rect(Rect((x, y), this_image.get_size())) + self.enable = enable + + def draw(self, surface): + if self.is_enabled(): + surface.blit(self.get_image(), self.get_rect()) + + def mouse_down(self, event): + if self.is_enabled(): + self.action() + + def is_enabled(self): + if self.enable: + return self.enable() + return True