diff pyntnclick/tools/rect_drawer.py @ 854:79b5c1be9a5e default tip

Remove pyntnclick, it's its own library, now
author Stefano Rivera <stefano@rivera.za.net>
date Sat, 21 Jun 2014 22:06:09 +0200
parents f95830b58336
children
line wrap: on
line diff
--- a/pyntnclick/tools/rect_drawer.py	Sat Jun 21 22:04:35 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,743 +0,0 @@
-# Quickly hacked together helper for working out
-# interactive regions in Suspended Sentence
-
-from pygame.locals import (K_LEFT, K_RIGHT, K_UP, K_DOWN,
-                           K_a, K_t, K_d, K_i, K_r, K_o, K_b, K_z,
-                           QUIT, MOUSEBUTTONDOWN, MOUSEMOTION,
-                           MOUSEBUTTONUP, KEYDOWN)
-import pygame
-import os
-
-import pyntnclick.constants
-from pyntnclick.i18n import _
-from pyntnclick.widgets.text import LabelWidget, TextButton
-from pyntnclick.widgets.base import Container, Button, TranslucentImage
-from pyntnclick.widgets.filechooser import FileChooser
-from pyntnclick.utils import draw_rect_image
-
-DRAW, CYCLE, DELETE, IMAGE = range(4)
-
-
-class RectDrawerError(Exception):
-    """Raised when initilaization failed"""
-
-
-class RectDrawerConstants(pyntnclick.constants.GameConstants):
-    debug = True
-    menu_width = 200
-    menu_button_height = 25
-    zoom = 4
-    zoom_step = 100
-
-constants = RectDrawerConstants()
-
-
-class ColourButton(Button):
-    """Button for selecting a colour"""
-
-    sel_colour = pygame.color.Color(255, 255, 255)
-    unsel_colour = pygame.color.Color(128, 128, 128)
-
-    padding = 2
-    border = 3
-
-    def __init__(self, rect, gd, colour, palette, size=None):
-        super(ColourButton, self).__init__(rect, gd, size=size)
-        self._colour = pygame.color.Color(colour)
-        self._button_rect = self.rect.inflate(-self.padding, -self.padding)
-        self._colour_rect = self._button_rect.inflate(-self.border,
-                -self.border)
-        self.selected = False
-        self._palette = palette
-        self.add_callback('clicked', self.fix_selection)
-
-    def fix_selection(self, ev, widget):
-        self._palette.cur_selection.selected = False
-        self.selected = True
-        self._palette.cur_selection = self
-
-    def draw(self, surface):
-        if self.visible:
-            self.do_prepare()
-            surface.fill(pygame.color.Color(0, 0, 0), self.rect)
-            if self.selected:
-                surface.fill(self.sel_colour, self._button_rect)
-            else:
-                surface.fill(self.unsel_colour, self._button_rect)
-            surface.fill(self._colour, self._colour_rect)
-
-
-class AppPalette(Container):
-
-    but_size = 35
-
-    colors = [
-            'red', 'maroon1', 'palevioletred1', 'moccasin', 'orange',
-            'honeydew', 'yellow', 'gold', 'goldenrod', 'brown',
-            'blue', 'purple', 'darkorchid4', 'thistle', 'skyblue1',
-            'green', 'palegreen1', 'darkgreen', 'aquamarine', 'darkolivegreen',
-            ]
-
-    def __init__(self, pos, gd, app_image, size=None):
-        self.image = app_image
-        super(AppPalette, self).__init__(pos, gd, size=size)
-        self.selection = 0
-        self.image.rect_color = pygame.color.Color(self.colors[self.selection])
-
-        x, y = pos
-        for num, col in enumerate(self.colors):
-            if (x - self.rect.left + self.but_size) >= self.rect.width:
-                x = self.rect.left
-                y += self.but_size
-            button = ColourButton((x, y),
-                    gd, col, self, size=(self.but_size, self.but_size))
-            x += self.but_size
-            if num == 0:
-                self.cur_selection = button
-                button.fix_selection(None, None)
-            button.add_callback('clicked', self.click_item, num)
-            self.add(button)
-        # Fix height
-        self.rect.height = y + self.but_size - self.rect.top
-
-    def click_item(self, ev, widget, number):
-        self.selection = number
-        self.image.rect_color = pygame.color.Color(self.colors[number])
-
-
-class AppImage(Container):
-
-    rect_thick = 3
-    draw_thick = 1
-
-    def __init__(self, parent, gd, state, scene, detail):
-        self.state = state
-        super(AppImage, self).__init__((0, 0), gd, size=constants.screen)
-        self.mode = DRAW
-        self._scene = scene
-        self._parent = parent
-        self._detail = detail
-        self.rects = []
-        self.images = []
-        self.start_pos = None
-        self.end_pos = None
-        self.rect_color = pygame.color.Color('white')
-        self.current_image = None
-        self.place_image_menu = None
-        self.close_button = LabelWidget((0, 0), gd, _('Close'))
-        self.close_button.fg_color = (0, 0, 0)
-        self.close_button.bg_color = (0, 0, 0)
-        self.draw_rects = True
-        self.draw_things = True
-        self.draw_thing_rects = True
-        self.draw_images = True
-        self.trans_images = False
-        self.draw_toolbar = True
-        self.old_mouse_pos = None
-        self.zoom_display = False
-        self.draw_anim = False
-        self.zoom_offset = (600, 600)
-        self.clear_display = False
-        self.filechooser = None
-        if self._detail:
-            w, h = self._scene.get_detail_size()
-            rect = pygame.rect.Rect(0, 0, w, h)
-            self.close_button.rect.midbottom = rect.midbottom
-            self.offset = (0, 0)
-        else:
-            self.offset = (-self._scene.OFFSET[0],
-                           -self._scene.OFFSET[1])
-        self.find_existing_intersects()
-        self.add_callback(MOUSEBUTTONDOWN, self.mouse_down)
-        self.add_callback(MOUSEBUTTONUP, self.mouse_up)
-        self.add_callback(MOUSEMOTION, self.mouse_move)
-        self.add_callback(KEYDOWN, self.key_down)
-
-    def get_mode_name(self):
-        """Return the translated mode name"""
-        # We do things this way to avoid defining translated strings
-        # at import time
-        if self.mode == DRAW:
-            return _("draw")
-        elif self.mode == CYCLE:
-            return _("cycle")
-        elif self.mode == DELETE:
-            return _("delete")
-        elif self.mode == IMAGE:
-            return _("image")
-        else:
-            raise RuntimeError("Invalid mode")
-
-    def _print_thing(self, thing, interact_name):
-        """Helper to avoid repeated translations"""
-        print (_("Thing %(thing)s Interact %(interact)s") %
-                {'thing': thing.name, 'interact': interact_name})
-
-    def _print_rects(self, rect1, rect2):
-        """Helper to avoid repeated translations"""
-        print _("     Rects"), rect1, rect2
-
-    def find_existing_intersects(self):
-        """Parse the things in the scene for overlaps"""
-        scene = self._scene
-        # Pylint hates this function
-        for thing in scene.things.itervalues():
-            for interact_name in thing.interacts:
-                thing._set_interact(interact_name)
-                if hasattr(thing.rect, 'collidepoint'):
-                    thing_rects = [thing.rect]
-                else:
-                    thing_rects = thing.rect
-                for thing2 in scene.things.itervalues():
-                    if thing is thing2:
-                        continue
-                    for interact2_name in thing2.interacts:
-                        thing2._set_interact(interact2_name)
-                        if hasattr(thing2.rect, 'collidepoint'):
-                            thing2_rects = [thing2.rect]
-                        else:
-                            thing2_rects = thing2.rect
-                        for my_rect in thing_rects:
-                            for other_rect in thing2_rects:
-                                if my_rect.colliderect(other_rect):
-                                    print _('Existing Intersecting rects')
-                                    self._print_thing(thing, interact_name)
-                                    self._print_thing(thing2, interact2_name)
-                                    self._print_rects(my_rect, other_rect)
-        print
-
-    def find_intersecting_rects(self, d):
-        """Find if any rect collections intersect"""
-        # I loath N^X brute search algorithms, but whatever, hey
-        scene = self._scene
-        for (num, col) in enumerate(d):
-            rect_list = d[col]
-            for thing in scene.things.itervalues():
-                for interact_name in thing.interacts:
-                    thing._set_interact(interact_name)
-                    if hasattr(thing.rect, 'collidepoint'):
-                        thing_rects = [thing.rect]
-                    else:
-                        thing_rects = thing.rect
-                    for other_rect in thing_rects:
-                        for my_rect in rect_list:
-                            if my_rect.colliderect(other_rect):
-                                print _('Intersecting rects')
-                                print _("  Object %s") % num
-                                self._print_thing(thing, interact_name)
-                                self._print_rects(my_rect, other_rect)
-                if thing.INITIAL:
-                    thing._set_interact(thing.INITIAL)
-            print
-            for (num2, col2) in enumerate(d):
-                if num2 == num:
-                    continue
-                other_list = d[col2]
-                for my_rect in rect_list:
-                    for other_rect in other_list:
-                        if my_rect.colliderect(other_rect):
-                            print _('Intersecting rects'),
-                            print (_('  Object %(object1)s and %(object2)s') %
-                                    {'object1': num, 'object2': num2})
-                            self._print_rects(my_rect, other_rect)
-            print
-            print
-
-    def toggle_things(self, ev, widget):
-        self.draw_things = not self.draw_things
-
-    def toggle_thing_rects(self, ev, widget):
-        self.draw_thing_rects = not self.draw_thing_rects
-        scene = self._scene
-        for thing in scene.things.itervalues():
-            if not self.draw_thing_rects:
-                if not hasattr(thing, 'old_colour'):
-                    thing.old_colour = thing._interact_hilight_color
-                thing._interact_hilight_color = None
-            else:
-                thing._interact_hilight_color = thing.old_colour
-
-    def toggle_images(self, ev, widget):
-        self.draw_images = not self.draw_images
-        for image in self.images:
-            image.set_visible(self.draw_images)
-        if self.current_image:
-            self.current_image.set_visible(self.draw_images)
-        self.invalidate()
-
-    def toggle_trans_images(self, ev, widget):
-        self.trans_images = not self.trans_images
-        for image in self.images:
-            image.translucent = self.trans_images
-        if self.current_image:
-            self.current_image.translucent = self.trans_images
-        self.invalidate()
-
-    def toggle_rects(self, ev, widget):
-        self.draw_rects = not self.draw_rects
-
-    def toggle_toolbar(self, ev, widget):
-        self.draw_toolbar = not self.draw_toolbar
-
-    def toggle_zoom(self, ev, widget):
-        self.zoom_display = not self.zoom_display
-        self.invalidate()
-
-    def toggle_anim(self, ev, widget):
-        self.draw_anim = not self.draw_anim
-
-    def draw_mode(self, ev, widget):
-        self.mode = DRAW
-
-    def del_mode(self, ev, widget):
-        self.mode = DELETE
-        self.start_pos = None
-        self.end_pos = None
-
-    def invalidate(self):
-        self.clear_display = True
-
-    def draw(self, surface):
-        if not self.visible:
-            return
-        self.do_prepare()
-        if self.clear_display:
-            surface.fill(pygame.color.Color(0, 0, 0),
-                    pygame.Rect(0, 0, constants.screen[0],
-                        constants.screen[1]))
-            self.clear_display = False
-
-        if self.zoom_display:
-            base_surface = surface.copy()
-            self.do_unzoomed_draw(base_surface)
-            zoomed = pygame.transform.scale(base_surface,
-                            (constants.zoom * base_surface.get_width(),
-                             constants.zoom * base_surface.get_height()))
-            area = pygame.rect.Rect(self.zoom_offset[0], self.zoom_offset[1],
-                                    constants.screen[0], constants.screen[1])
-            surface.blit(zoomed, (0, 0), area)
-        else:
-            self.do_unzoomed_draw(surface)
-
-    def do_unzoomed_draw(self, surface):
-        if self.draw_things:
-            self._scene.draw(surface)
-        else:
-            self._scene.draw_background(surface)
-        if self._detail:
-            # We duplicate draw logic here, so we zoom the close
-            # button correctly
-            self.close_button.draw(surface)
-        if self.mode == DRAW and self.start_pos and self.draw_rects:
-            rect = pygame.rect.Rect(self.start_pos[0], self.start_pos[1],
-                    self.end_pos[0] - self.start_pos[0],
-                    self.end_pos[1] - self.start_pos[1])
-            rect.normalize()
-            draw_rect_image(surface, self.rect_color, rect, self.draw_thick)
-        if self.draw_rects:
-            for (col, rect) in self.rects:
-                draw_rect_image(surface, col, rect, self.rect_thick)
-        for image in self.images:
-            image.draw(surface)
-        if self.current_image and self.mode == IMAGE:
-            self.current_image.draw(surface)
-        if self.draw_toolbar:
-            tb_surf = surface.subsurface(0, constants.screen[1]
-                                            - constants.button_size,
-                                         constants.screen[0],
-                                         constants.button_size).convert_alpha()
-            tb_surf.fill(pygame.color.Color(127, 0, 0, 191))
-            surface.blit(tb_surf, (0, constants.screen[1]
-                                      - constants.button_size))
-
-    def _make_dict(self):
-        d = {}
-        for col, rect in self.rects:
-            col = (col.r, col.g, col.b)
-            d.setdefault(col, [])
-            d[col].append(rect)
-        return d
-
-    def print_objs(self, ev, widget):
-        d = self._make_dict()
-        self.find_intersecting_rects(d)
-        for (num, col) in enumerate(d):
-            print _('Rect %d : ') % num
-            for rect in d[col]:
-                r = rect.move(self.offset)
-                print '   (%d, %d, %d, %d),' % (r.x, r.y, r.w, r.h)
-            print
-        for i, image in enumerate(self.images):
-            print _('Image %d') % i
-            rect = image.rect
-            r = rect.move(self.offset)
-            print '   (%d, %d, %d, %d),' % (r.x, r.y, r.w, r.h)
-            print
-        print
-
-    def image_load(self, ev, widget):
-        if self.filechooser is None:
-            self.filechooser = FileChooser((0, 0), self.gd, None, os.curdir,
-                    self.do_load_image)
-        else:
-            self.filechooser.refresh()
-        self.invalidate()
-        self._parent.paused = True
-        self._parent.add(self.filechooser)
-
-    def do_load_image(self, filename):
-        try:
-            self.current_image = TranslucentImage((0, 0), self.gd,
-                    pygame.image.load(filename))
-            if not self.draw_images:
-                # Selecting an image makes image visible
-                self.toggle_images(None, None)
-            self.current_image.translucent = self.trans_images
-            self.place_image_menu.enabled = True
-            self.current_image.rect = self.current_image.rect.move(
-                    constants.screen[0] + constants.menu_width,
-                    constants.screen[1])
-            self.image_mode(None, None)
-        except pygame.error, e:
-            print 'Unable to load image %s (reason %s)' % (filename, e)
-
-    def image_mode(self, ev, widget):
-        self.mode = IMAGE
-        self.start_pos = None
-        self.end_pos = None
-        # So we do the right thing for off screen images
-        self.old_mouse_pos = None
-
-    def cycle_mode(self, ev, widget):
-        self.mode = CYCLE
-
-    def _conv_pos(self, mouse_pos):
-        if self.zoom_display:
-            pos = ((mouse_pos[0] + self.zoom_offset[0]) / constants.zoom,
-                   (mouse_pos[1] + self.zoom_offset[1]) / constants.zoom)
-        else:
-            pos = mouse_pos
-        return pos
-
-    def _check_limits(self, offset):
-        if offset[0] < 0:
-            offset[0] = 0
-        if offset[1] < 0:
-            offset[1] = 0
-        width, height = constants.screen
-        if offset[0] > constants.zoom * width - width:
-            offset[0] = constants.zoom * width - width
-        if offset[1] > constants.zoom * height - height:
-            offset[1] = constants.zoom * height - height
-
-    def _make_zoom_offset(self, pos):
-        zoom_pos = (pos[0] * constants.zoom, pos[1] * constants.zoom)
-        offset = [zoom_pos[0] - constants.screen[0] / 2,
-                zoom_pos[1] - constants.screen[1] / 2]
-        self._check_limits(offset)
-        self.zoom_offset = tuple(offset)
-
-    def _move_zoom(self, x, y):
-        offset = list(self.zoom_offset)
-        offset[0] += constants.zoom_step * x
-        offset[1] += constants.zoom_step * y
-        self._check_limits(offset)
-        self.zoom_offset = tuple(offset)
-
-    def key_down(self, ev, widget):
-        if self.mode == IMAGE and self.current_image:
-            # Move the image by 1 pixel
-            cur_pos = self.current_image.rect.center
-            if ev.key == K_LEFT:
-                self.current_image.rect.center = (cur_pos[0] - 1, cur_pos[1])
-            elif ev.key == K_RIGHT:
-                self.current_image.rect.center = (cur_pos[0] + 1, cur_pos[1])
-            elif ev.key == K_UP:
-                self.current_image.rect.center = (cur_pos[0], cur_pos[1] - 1)
-            elif ev.key == K_DOWN:
-                self.current_image.rect.center = (cur_pos[0], cur_pos[1] + 1)
-        elif self.zoom_display:
-            if ev.key == K_LEFT:
-                self._move_zoom(-1, 0)
-            elif ev.key == K_RIGHT:
-                self._move_zoom(1, 0)
-            elif ev.key == K_UP:
-                self._move_zoom(0, -1)
-            elif ev.key == K_DOWN:
-                self._move_zoom(0, 1)
-
-        if ev.key == K_o:
-            self.toggle_trans_images(None, None)
-        elif ev.key == K_t:
-            self.toggle_things(None, None)
-        elif ev.key == K_r:
-            self.toggle_thing_rects(None, None)
-        elif ev.key == K_i:
-            self.toggle_images(None, None)
-        elif ev.key == K_d:
-            self.toggle_rects(None, None)
-        elif ev.key == K_b:
-            self.toggle_toolbar(None, None)
-        elif ev.key == K_z:
-            self.toggle_zoom(None, None)
-        elif ev.key == K_a:
-            self.toggle_anim(None, None)
-
-    def mouse_down(self, ev, widget):
-        pos = self._conv_pos(ev.pos)
-        if self._parent.paused:
-            # Ignore this if the filechooser is active
-            return False
-        if self.mode == DELETE:
-            cand = None
-            # Images are drawn above rectangles, so search those first
-            for image in self.images:
-                if image.rect.collidepoint(pos):
-                    cand = image
-                    break
-            if cand:
-                self.images.remove(cand)
-                self.invalidate()
-                return
-            for (col, rect) in self.rects:
-                if rect.collidepoint(pos):
-                    cand = (col, rect)
-                    break
-            if cand:
-                self.rects.remove(cand)
-                self.invalidate()
-        elif self.mode == CYCLE:
-            scene = self._scene
-            cand = None
-            for thing in scene.things.itervalues():
-                if thing.contains(pos):
-                    cand = thing
-                    break
-            if cand:
-                # Find current interacts in this thing
-                cur_interact = cand.current_interact
-                j = cand.interacts.values().index(cur_interact)
-                if j + 1 < len(cand.interacts):
-                    next_name = cand.interacts.keys()[j + 1]
-                else:
-                    next_name = cand.interacts.keys()[0]
-                if cand.interacts[next_name] != cur_interact:
-                    cand._set_interact(next_name)
-        elif self.mode == DRAW:
-            self.start_pos = pos
-            self.end_pos = pos
-        elif self.mode == IMAGE:
-            if self.current_image:
-                self.images.append(self.current_image)
-                self.current_image = None
-                self.old_mouse_pos = None
-                self.invalidate()
-            else:
-                cand = None
-                for image in self.images:
-                    if image.rect.collidepoint(pos):
-                        cand = image
-                        break
-                if cand:
-                    self.images.remove(cand)
-                    self.current_image = cand
-                    # We want to move relative to the current mouse pos, so
-                    self.old_mouse_pos = pos
-                    self.invalidate()
-
-    def mouse_up(self, ev, widget):
-        if self._parent.paused:
-            return False
-        if self.mode == DRAW:
-            if self.start_pos is None:
-                # We've come here not via a drawing situation, so bail
-                return False
-            rect = pygame.rect.Rect(self.start_pos[0], self.start_pos[1],
-                    self.end_pos[0] - self.start_pos[0],
-                    self.end_pos[1] - self.start_pos[1])
-            rect.normalize()
-            self.rects.append((self.rect_color, rect))
-            self.start_pos = self.end_pos = None
-
-    def mouse_move(self, ev, widget):
-        # We're only interested in this if left mouse button is down or we've
-        # got and image
-        if self.mode == IMAGE and self.current_image:
-            pos = self._conv_pos(ev.pos)
-            if self.old_mouse_pos:
-                delta = (pos[0] - self.old_mouse_pos[0],
-                         pos[1] - self.old_mouse_pos[1])
-                self.current_image.rect.center = (
-                        self.current_image.rect.center[0] + delta[0],
-                        self.current_image.rect.center[1] + delta[1])
-            else:
-                self.current_image.rect.center = pos
-            self.invalidate()
-            self.old_mouse_pos = pos
-            return True
-        elif ev.buttons[0] == 1 and self.mode == DRAW:
-            self.end_pos = self._conv_pos(ev.pos)
-            return True
-        return False
-
-    def animate(self):
-        if self.draw_anim:
-            self._scene.animate()
-
-
-class ModeLabel(LabelWidget):
-
-    def __init__(self, pos, gd, app_image, size=None):
-        self.app_image = app_image
-        super(ModeLabel, self).__init__(pos,
-                gd, _('Mode : '), fontname=constants.bold_font,
-                fontsize=15, color=pygame.color.Color(128, 0, 255),
-                size=size)
-        self.start_rect = self.rect.copy()
-
-    def draw(self, surface):
-        self.do_prepare()
-        text = _('Mode : %s') % self.app_image.get_mode_name()
-        if self.text != text:
-            self.text = text
-            self.is_prepared = False
-            self.rect = self.start_rect.copy()
-            self.do_prepare()
-        super(ModeLabel, self).draw(surface)
-
-
-def make_button(text, gd, action, ypos):
-    rect = pygame.rect.Rect(0, 0, constants.menu_width,
-            constants.menu_button_height)
-    rect.move_ip(805, ypos)
-    button = TextButton(rect.topleft, gd, text, size=(constants.menu_width,
-        constants.menu_button_height),
-            fontname=constants.font, fontsize=12,
-            color=pygame.color.Color(255, 255, 0), border=1, padding=3)
-    button.add_callback('clicked', action)
-    return button
-
-
-class RectApp(Container):
-    """The actual rect drawer main app"""
-    def __init__(self, rect, gd, detail):
-        super(RectApp, self).__init__(rect, gd)
-
-        try:
-            state = gd.initial_state()
-            scene = state.scenes[gd._initial_scene]
-        except KeyError:
-            raise RectDrawerError(_('Invalid scene: %s') % gd._initial_scene)
-        gd.sound.disable_sound()  # No sound here
-
-        if detail:
-            try:
-                scene = state.detail_views[detail]
-            except KeyError:
-                raise RectDrawerError(_('Invalid detail: %s') % detail)
-
-        self.paused = False
-
-        self.image = AppImage(self, gd, state, scene, detail is not None)
-        self.add(self.image)
-        mode_label = ModeLabel((805, 0), self.gd, self.image, size=(200, 50))
-        self.add(mode_label)
-        y = mode_label.rect.height
-        draw = make_button(_('Draw Rect'), gd, self.image.draw_mode, y)
-        self.add(draw)
-        y += draw.rect.height
-        load_image = make_button(_("Load image"), gd, self.image.image_load, y)
-        self.add(load_image)
-        y += load_image.rect.height
-        add_image = make_button(_("Place/Move images"), gd,
-                self.image.image_mode, y)
-        add_image.enabled = False
-        self.add(add_image)
-        self.image.place_image_menu = add_image
-        y += add_image.rect.height
-        cycle = make_button(_("Cycle interacts"), gd, self.image.cycle_mode, y)
-        self.add(cycle)
-        y += cycle.rect.height
-        delete = make_button(_("Delete Objects"), gd, self.image.del_mode, y)
-        self.add(delete)
-        y += delete.rect.height
-        palette = AppPalette((810, y), gd, self.image, size=(200, 0))
-        self.add(palette)
-        y += palette.rect.height
-        print_rects = make_button(_("Print objects"), gd,
-                self.image.print_objs, y)
-        self.add(print_rects)
-        y += print_rects.rect.height
-        toggle_things = make_button(_("Show Things (t)"), gd,
-                self.image.toggle_things, y)
-        self.add(toggle_things)
-        y += toggle_things.rect.height
-        toggle_thing_rects = make_button(_("Show Thing Rects (r)"), gd,
-                self.image.toggle_thing_rects, y)
-        self.add(toggle_thing_rects)
-        y += toggle_thing_rects.rect.height
-        toggle_images = make_button(_("Show Images (i)"), gd,
-                self.image.toggle_images, y)
-        self.add(toggle_images)
-        y += toggle_images.rect.height
-        trans_images = make_button(_("Opaque Images (o)"), gd,
-                self.image.toggle_trans_images, y)
-        self.add(trans_images)
-        y += trans_images.rect.height
-        toggle_rects = make_button(_("Show Drawn Rects (d)"), gd,
-                self.image.toggle_rects, y)
-        self.add(toggle_rects)
-        y += toggle_rects.rect.height
-        toggle_toolbar = make_button(_("Show Toolbar (b)"), gd,
-                self.image.toggle_toolbar, y)
-        self.add(toggle_toolbar)
-        y += toggle_toolbar.rect.height
-        toggle_anim = make_button(_("Show Animations (a)"), gd,
-                self.image.toggle_anim, y)
-        self.add(toggle_anim)
-        y += toggle_anim.rect.height
-        toggle_zoom = make_button(_("Zoom (z)"), gd,
-                self.image.toggle_zoom, y)
-        self.add(toggle_zoom)
-        y += toggle_zoom.rect.height
-        quit_but = make_button(_("Quit"), gd, self.quit, 570)
-        self.add(quit_but)
-
-    def quit(self, ev, widget):
-        pygame.event.post(pygame.event.Event(QUIT))
-
-    def animate(self):
-        self.image.animate()
-
-
-class RectEngine(object):
-    """Engine for the rect drawer."""
-
-    def __init__(self, gd, detail):
-        self.state = None
-        self._gd = gd
-        rect = pygame.display.get_surface().get_rect()
-        self.app = RectApp(rect.topleft, self._gd, detail)
-
-    def run(self):
-        """App loop"""
-        clock = pygame.time.Clock()
-        while True:
-            events = pygame.event.get()
-            for ev in events:
-                if ev.type == QUIT:
-                    return
-                else:
-                    self.app.event(ev)
-            self.app.animate()
-            surface = pygame.display.get_surface()
-            self.app.draw(surface)
-            pygame.display.flip()
-            clock.tick(self._gd.constants.frame_rate)
-
-
-def make_rect_display():
-    pygame.display.init()
-    pygame.font.init()
-    pygame.display.set_mode((constants.screen[0]
-        + constants.menu_width, constants.screen[1]))