Commits

Anonymous committed 97ff231

I think I'm done cleaning! Will do it correctly right off the bat next time.

Comments (0)

Files changed (66)

 
 I hope you enjoy the game!  See COPYING for license terms.
 
+In case it's not abundantly clear now (I cleaned it up), to play:
+
+	python ProduceDefendWin.py
+
 Robert Leachman
 December 2010
 callmerob at gmail dot com

Source/fonts/default.ttf

Binary file added.

Third_Party_Sources/MenuClass.py

-#! /usr/bin/python
-
-## \file  menu.py
-#  \brief General Menu Class
-#  \author Scott Barlow
-#  \date 2009
-#  \version 1.0.3
-#
-#  This is a menu class written for pygame/Python.  The menu is designed to work
-#  with a program using a finite state machine (but it could also be easily
-#  modified to have the 'buttons' return functions).  The menu 'buttons' contain
-#  a 'state' (a state could really be anything you want) and this 'state' is
-#  what is returned when the user selects/presses the button.  The program
-#  controlling the menu can then act on this returned state as required.  This
-#  helps to write non-blocking code.
-#
-#  The menu can have text buttons, image buttons (that get highlighted on all
-#  sides to detect which is selected), or any combination of the two.
-#
-#  The menu is flexible and can be dynamically changed.  The 'buttons' will
-#  auto-magically update themselves the next time they are drawn to the screen
-#  (via the update method, which calls the draw method).  The draw method should
-#  not be called itself.  'Buttons' can be added or removed at any time.
-#
-#  The menu can be positioned by the top left corner (a rectangle containing all
-#  buttons is what gets moved).  It can be changed to center the entire menu
-#  (i.e. center that containing rectangle) on that same position coordinate.  Or
-#  the user can center the entire menu on the self.draw_surface.  Note that if
-#  the pygame screen is given to the menu, then the entire window will be
-#  available to be drawn to.  But if the user gives the menu another pygame
-#  surface, then that surface itself will need to be blitted to the pygame
-#  screen at some point.  Furthermore, the user can align the buttons to align
-#  on the left, tobe centerd, or to align themselves on the right.  Also, they
-#  can be aligned vertically on the top, center, or bottom.
-#
-#  The user can dynamically change the colors of the font/highlights, the
-#  padding between buttons (left/right and top/bottom), the thickness of the
-#  highlight around image buttons, and the orientation of the menu (if the
-#  'buttons' will be stacked top to bottom ('vertical') or left to right
-#  ('horizontal').
-#
-#  The best way to figure out the menu is to tinker around with it.  Run the
-#  example programs, change attributes, and play with the menu.
-#
-#
-#       Copyright 2009 Scott Barlow
-#
-#       This program is free software; you can redistribute it and/or modify
-#       it under the terms of the GNU General Public License as published by
-#       the Free Software Foundation; either version 3 of the License, or
-#       (at your option) any later version.
-#
-#       This program is distributed in the hope that it will be useful,
-#       but WITHOUT ANY WARRANTY; without even the implied warranty of
-#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#       GNU General Public License for more details.
-#
-#       You should have received a copy of the GNU General Public License
-#       along with this program; if not, write to the Free Software
-#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#       MA 02110-1301, USA or see <http://www.gnu.org/licenses/>.
-#
-#
-#  Changelog
-#     V1.0.0 - Initial Release
-#     V1.0.1 - Added get_current_image method
-#     V1.0.2 - Fixed a bug in the set_font method (to update the rect of the
-#              text buttons when the font is changed
-#     V1.0.3 - Added self.refresh_whole_surface_on_load functionality
-#
-
-
-#-------------------------------------------------------------------------------
-#---[ Imports ]-----------------------------------------------------------------
-#-------------------------------------------------------------------------------
-import pygame
-
-
-#-------------------------------------------------------------------------------
-#---[ Defines ]-----------------------------------------------------------------
-#-------------------------------------------------------------------------------
-## RGB color for Black
-BLACK = (0, 0, 0)
-
-## RGB color for White
-WHITE = (255, 255, 255)
-
-## RGB color for Red
-RED = (255, 0, 0)
-
-## RGB color for Green
-GREEN = (0, 255, 0)
-
-## RGB color for Blue
-BLUE = (0, 0, 255)
-
-## This is a user event that should be sent whenever the game state is changed
-#  (at the main game loop level)
-EVENT_CHANGE_STATE = pygame.USEREVENT + 1
-
-#-------------------------------------------------------------------------------
-#---[ cMenu Class ]-------------------------------------------------------------
-#-------------------------------------------------------------------------------
-## This class is used to display and control a menu
-#
-class cMenu:
-   ## ---[ __init__ ]-----------------------------------------------------------
-   #  @param   self        The class itself, Python standard
-   #  @param   x           The x location to shift the buttons by when the
-   #                       button is drawn to the surface in the update method
-   #  @param   y           The y location to shift the buttons by when the
-   #                       button is drawn to the surface in the update method
-   #  @param   h_pad       Number the extra pixels to pad the buttons by (on the
-   #                       left/right)
-   #  @param   v_pad       Number the extra pixels to pad the buttons by (on the
-   #                       top/bottom).
-   #  @param   orientation Should be 'vertical' or 'horizontal'.  The buttons
-   #                       will be put vertically or horizontally until 'number'
-   #                       (the next argument) of buttons have been created at
-   #                       which point it will start a new row or column
-   #  @param   number      The number of buttons to put vertically or
-   #                       horizontally before starting a new row or column
-   #  @param   background  The background to use for the buttons (what will show
-   #                       up behind the buttons).  This is often the
-   #                       surface that they will be blitted to via the update
-   #                       method
-   #  @param   buttonList  This is a list of buttons to be added (though
-   #                       more buttons can be added via another method).  The
-   #                       elements of the list should be tuples of 3 parts as
-   #                       shown: ('text', state, image) where text is the text
-   #                       that will be shown for the button, state is what will
-   #                       be returned when the button is pressed (enter is
-   #                       hit), and image is None if the button is just going
-   #                       to display text, or else is an image itself if the
-   #                       button will be displayed as an image instead of text.
-   #
-   #  Initialize the class
-   #
-   def __init__(self, x, y, h_pad, v_pad, orientation, number, background,
-                buttonList):
-      ## menu items
-      self.menu_items = []                      # List of menu items
-      self.font = pygame.font.Font(None, 32)    # Font to use
-
-      self.x = x                                # Top left corner (of surface)
-      self.y = y                                # relative to the screen/window
-      self.change_number = number               # See description above
-      self.orientation = orientation            # See description above
-      self.horizontal_padding = h_pad           # See description above
-      self.vertical_padding = v_pad             # See description above
-
-      self.selection = 0                        # The currently selected button
-      self.u_color = WHITE                      # Color for unselected text
-      self.s_color = RED                        # Color for selected text
-      self.image_highlight_color = BLUE         # Color for the image highlights
-      self.image_highlight_offset = 2           # Addition padding around image
-                                                # buttons only for the highlight
-
-      self.background = background.copy()       # The unedited background image
-      self.draw_surface = background            # Surface to draw to
-      self.centered = False                     # True if the menu is centered
-      self.centeredOnScreen = False             # True if the menu is centered
-      self.update_buttons = True                # True if the positions of the
-                                                # buttons need to be updated
-      self.refresh_whole_surface_on_load = False# When the menu is first
-                                                # displayed (when the event
-                                                # EVENT_CHANGE_STATE is given to
-                                                # the update method), the entire
-                                                # self.draw_surface will be
-                                                # updated
-
-      # This dictionary contains the alignment orientation of the buttons
-      # related to each other.  It shifts the button within the bounds of
-      # 'max_width' and 'max_height' in the self.position_buttons() method.
-      self.alignment = {'vertical'  :'top',
-                        'horizontal':'left'}
-
-      # Now add any buttons that were sent in
-      self.add_buttons(buttonList)
-   
-      # Hack to allow menu default > 0; just set this before calling menu
-      self.initialSelection = 0 
-
-      # Hacked to work with the mouse! See mouse events in update()
-      self.mousePos = [0,0]
-
-
-   ## ---[ redraw_all ]---------------------------------------------------------
-   def redraw_all(self):
-      for button in self.menu_items:
-         button['redraw'] = True
-
-   ## ---[ get_current_text ]---------------------------------------------------
-   def get_current_text(self):
-      return self.menu_items[self.selection]['text']
-
-   ## ---[ get_current_image ]--------------------------------------------------
-   def get_current_image(self):
-      return self.menu_items[self.selection]['b_image']
-
-   ## ---[ set_unselected_color ]-----------------------------------------------
-   def set_unselected_color(self, new_color):
-      self.u_color = new_color
-      self.update_buttons = True
-
-   ## ---[ set_selected_color ]-------------------------------------------------
-   def set_selected_color(self, new_color):
-      self.s_color = new_color
-      self.update_buttons = True
-
-   ## ---[ set_image_highlight_color ]------------------------------------------
-   def set_image_highlight_color(self, new_color):
-      self.image_highlight_color = new_color
-      self.update_buttons = True
-
-   ## ---[ set_image_highlight_thickness ]--------------------------------------
-   def set_image_highlight_thickness(self, new_thick):
-      old_th = self.image_highlight_offset
-      # We need to update the width of the button images now (the images
-      # themselves will be updated before the next refresh/re-draw).  Note that
-      # we only change the rect on the image buttons since we only highlight the
-      # image buttons (not the text buttons)
-      for button in self.menu_items:
-         if button['b_image'] != None:
-            button['rect'][2] = button['rect'][2] - 2 * old_th + 2 * new_thick
-            button['rect'][3] = button['rect'][3] - 2 * old_th + 2 * new_thick
-      self.image_highlight_offset = new_thick
-      self.update_buttons = True
-
-   ## ---[ set_padding ]--------------------------------------------------------
-   def set_padding(self, h_pad, v_pad):
-      self.horizontal_padding = h_pad
-      self.vertical_padding   = v_pad
-      self.update_buttons = True
-
-   ## ---[ set_orientation ]----------------------------------------------------
-   def set_orientation(self, new_orientation):
-      if new_orientation == 'vertical' or new_orientation == 'horizontal':
-         self.orientation = new_orientation
-         self.update_buttons = True
-      else:
-         print 'WARNING:  cMenu.set_orientation:  Invalid argument '\
-               'new_orientation (value: %d)' % new_orientation
-
-   ## ---[ set_change_number ]--------------------------------------------------
-   def set_change_number(self, new_change_number):
-      self.change_number = new_change_number
-      self.update_buttons = True
-
-   ## ---[ set_refresh_whole_screen_on_load ]-----------------------------------
-   def set_refresh_whole_surface_on_load(self, new_val = True):
-      self.refresh_whole_surface_on_load = new_val # Should be True or False
-
-   ## ---[ set_font ]-----------------------------------------------------------
-   def set_font(self, font):
-      self.font = font
-
-      # We need to update the width and height of the text buttons since we
-      # calculated their width and height based on the font
-      for button in self.menu_items:
-         if button['b_image'] == None:
-            width, height = self.font.size(button['text'])
-            button['rect'][2] = width
-            button['rect'][3] = height
-
-      self.update_buttons = True
-
-   ## ---[ set_alignment ]------------------------------------------------------
-   #  @param   self     The class itself, Python standard
-   #  @param   v_align  The way to align the text vertically within its 'cell'
-   #  @param   h_align  The way to align the text horizontally within its 'cell'
-   #
-   #  This method sets the alignment of the buttons within their 'cell' (i.e. it
-   #  sets the alignment of the button (based on it's width and height) within
-   #  the max_width and max_height values calculated in the
-   #  self.position_buttons() method).  The self.position_buttons() method is
-   #  also where the alignment occurs.  The valid alignments are:
-   #     left
-   #     center
-   #     right
-   #
-   def set_alignment(self, v_align, h_align):
-      if v_align in ['top', 'center', 'bottom']:
-         self.alignment['vertical'] = v_align
-      if h_align in ['left', 'center', 'right']:
-         self.alignment['horizontal'] = h_align
-      self.update_buttons = True
-
-
-   ## ---[ set_position ]-------------------------------------------------------
-   #  @param   self   The class itself, Python standard
-   #  @param   x      The x (horizontal location)
-   #  @param   y      The y (vertical location)
-   #
-   #  This method sets the x and y locations for the menu.  By default, this
-   #  sets the position of the menu with respect to the top left corner of the
-   #  self.draw_surface.  If 'centered' is true, then this is the location of
-   #  the center of the menu.
-   #
-   def set_position(self, x, y):
-      self.x = x
-      self.y = y
-      self.update_buttons = True
-
-
-   ## ---[ set_center ]---------------------------------------------------------
-   #  @param   self           The class itself, Python standard
-   #  @param   centered       A boolean, centers the menu if it is True, default
-   #                          value is True
-   #  @param   centeredOnScreen  If this is true, then the menu will be centered
-   #                             on the entire self.draw_surface surface.
-   #
-   #  When passed a value of True, this centers the menu at the self.x and
-   #  self.y locations.  If False is passed to it, then this makes the top left
-   #  corner of the menu start at the x and y location with respect to the
-   #  self.draw_surface.  If centerScreen is True, then self.centered is set to
-   #  true, regardless of the value passed in
-   #
-   def set_center(self, centered, centeredOnScreen):
-      if centeredOnScreen:
-         self.centeredOnScreen = centeredOnScreen
-         self.centered = False
-      else:
-         self.centeredOnScreen = False
-         self.centered = centered
-      self.update_buttons = True
-
-
-   ## ---[ add_buttons ]--------------------------------------------------------
-   #  @param   self         The class itself, Python standard
-   #  @param   buttonList   List of menu buttons to be added
-   #
-   #  Used to add button(s) to the menu
-   #
-   def add_buttons(self, buttonList):
-      for button in buttonList:
-         self.menu_items.append(self.create_button(button))
-      self.update_buttons = True
-
-
-   ## ---[ remove_buttons ]-----------------------------------------------------
-   #  @param   self         The class itself, Python standard
-   #  @param   indexList    List of indexes to be removed
-   #
-   #  Used to remove button(s) from the menu
-   #
-   def remove_buttons(self, indexList):
-      old_contained_rect = self.contained_rect
-      for index in indexList:
-         if len(self.menu_items) > 1:
-            self.menu_items.pop(index)
-      self.update_buttons = True
-      return old_contained_rect
-
-
-   ## ---[ update_button_locations ]--------------------------------------------
-   #  @param   self         The class itself, Python standard
-   #
-   #  This method is just used to update the location of the buttons when the
-   #  a change is made
-   #
-   def update_button_locations(self):
-      self.position_buttons()
-      self.set_button_images()
-      self.update_buttons = False
-
-
-   ## ---[ create_button ]------------------------------------------------------
-   #  @param   self         The class itself, Python standard
-   #  @param   button_info  A list with the button text, the next state to
-   #                        return, and the image (if applicable)
-   #
-   #  Create the button dictionary for a new button.  Note that this button is
-   #  useless until the set_button_images method is called which is where the
-   #  button images are created and assigned.  The reason it is not done here
-   #  is becuase we need to know the location of the button on the background
-   #  which is not assigned until position_buttons() is called.  Since position
-   #  buttons depends on the width and height of each button, we just calculate
-   #  those here, then we set the location of the buttons via the
-   #  position_buttons() method, then we make the actual images via the
-   #  set_button_images() function
-   #
-   def create_button(self, button_info):
-      # If this button is not an image, set the width and height based on the
-      # text
-      if button_info[2] == None:
-         width, height = self.font.size(button_info[0])
-         button_rect = pygame.Rect((0, 0), (width, height))
-      # Else this button is a graphic button, so create the width and height
-      # based on the image provided
-      else:
-         width, height = button_info[2].get_size()
-         offset = (self.image_highlight_offset, self.image_highlight_offset)
-         new_width  = width  + 2 * offset[0]  # Make room for the highlight on
-         new_height = height + 2 * offset[1]  # all sides
-         button_rect = pygame.Rect((0, 0), (new_width, new_height))
-
-      set_redraw = True     # When the button is created, it needs to be drawn
-      set_selected = False  # When the button is created, it is not selected
-
-      new_button = {'text'    : button_info[0],
-                    'state'   : button_info[1],
-                    'selected': set_selected,
-                    'rect'    : button_rect,
-                    'offset'  : (0, 0),
-                    'redraw'  : set_redraw,
-                    'b_image' : button_info[2],  # base image
-                    's_image' : None,            # image when selected and not
-                    'u_image' : None}            # selected (created in
-                                                 # set_button_images)
-
-      return new_button
-
-
-   ## ---[ set_button_images ]--------------------------------------------------
-   #  @param   self         The class itself, Python standard
-   #
-   #  Create the button images to be displayed - adjusted for the location of
-   #  the button over the background image
-   #
-   def set_button_images(self):
-      for button in self.menu_items:
-         # If this button is not an image, create the selected and unselected
-         # images based on the text
-         if button['b_image'] == None:
-            r = self.font.render
-            width  = button['rect'][2]
-            height = button['rect'][3]
-            rect = pygame.Rect(button['offset'], (width, height))
-
-            # For each of the text button (selected and unselected), create a
-            # surface of the required size (already calculated before), blit
-            # the background image to the surface, then render the text and blit
-            # that text onto the same surface.
-            selected_image = pygame.Surface((width, height), -1)
-            selected_image.blit(self.background, (0, 0), rect)
-            text_image   = r(button['text'], True, self.s_color)
-            selected_image.blit(text_image, (0, 0))
-
-            unselected_image = pygame.Surface((width, height), -1)
-            unselected_image.blit(self.background, (0, 0), rect)
-            text_image   = r(button['text'], True, self.u_color)
-            unselected_image.blit(text_image, (0, 0))
-
-         # Else this button is a graphic button, so create the selected and
-         # unselected images based on the image provided
-         else:
-            orig_width, orig_height = button['b_image'].get_size()
-            new_width  = button['rect'][2]
-            new_height = button['rect'][3]
-            offset = (self.image_highlight_offset, self.image_highlight_offset)
-
-            # Selected image! --------------------------------------------------
-            # Create the surface, fill the surface with the highlight color,
-            # then blit the background image to the surface (inside of the
-            # highlight area), and then blit the actual button base image over
-            # the background
-            selected_image = pygame.Surface((new_width, new_height), -1)
-            selected_image.fill(self.image_highlight_color)
-            rect = pygame.Rect((button['offset'][0] + offset[0],
-                                button['offset'][1] + offset[1]),
-                               (orig_width, orig_height))
-            selected_image.blit(self.background, offset, rect)
-            selected_image.blit(button['b_image'], offset)
-
-            # Unselected image! ------------------------------------------------
-            # Create the surface, blit the background image onto the surface (to
-            # make sure effects go away when the button is no longer selected),
-            # and then blit the actual button base image over the background
-            unselected_image = pygame.Surface((new_width, new_height), -1)
-            rect = pygame.Rect(button['offset'], (new_width, new_height))
-            unselected_image.blit(self.background, (0, 0), rect)
-            unselected_image.blit(button['b_image'], offset)
-
-         button['s_image'] = selected_image
-         button['u_image'] = unselected_image
-
-
-   ## ---[ position_buttons ]---------------------------------------------------
-   #  @param   self    The class itself, Python standard
-   #
-   #  Sets the positions for the buttons
-   #
-   def position_buttons(self):
-      width = 0
-      height = 0
-      max_width = 0
-      max_height = 0
-      counter = 0
-      x_loc = self.x
-      y_loc = self.y
-
-      # Get the maximum width and height of the surfaces
-      for button in self.menu_items:
-         width  = button['rect'][2]
-         height = button['rect'][3]
-         max_width = max(width, max_width)
-         max_height = max(height, max_height)
-
-      # Position the button in relation to each other
-      for button in self.menu_items:
-         # Find the offsets for the alignment of the buttons (left, center, or
-         # right
-         # Vertical Alignment
-         if self.alignment['vertical'] == 'top':
-            offset_height = 0
-         elif self.alignment['vertical'] == 'center':
-            offset_height = (max_height - button['rect'][3])/2
-         elif self.alignment['vertical'] == 'bottom':
-            offset_height = (max_height - button['rect'][3])
-         else:
-            offset_height = 0
-            print 'WARNING:  cMenu.position_buttons:  Vertical Alignment '\
-                  '(value: %s) not recognized!  Left alignment will be used'\
-                                                    % self.alignment['vertical']
-
-         # Horizontal Alignment
-         if self.alignment['horizontal'] == 'left':
-            offset_width = 0
-         elif self.alignment['horizontal'] == 'center':
-            offset_width = (max_width - button['rect'][2])/2
-         elif self.alignment['horizontal'] == 'right':
-            offset_width = (max_width - button['rect'][2])
-         else:
-            offset_width = 0
-            print 'WARNING:  cMenu.position_buttons:  Horizontal Alignment '\
-                  '(value: %s) not recognized!  Left alignment will be used'\
-                                                  % self.alignment['horizontal']
-
-         # Move the button location slightly based on the alignment offsets
-         x_loc += offset_width
-         y_loc += offset_height
-
-         # Assign the location of the button
-         button['offset'] = (x_loc, y_loc)
-
-         # Take the alignment offsets away after the button position has been
-         # assigned so that the new button can start fresh again
-         x_loc -= offset_width
-         y_loc -= offset_height
-
-         # Add the width/height to the position based on the orientation of the
-         # menu.  Add in the padding.
-         if self.orientation == 'vertical':
-            y_loc += max_height + self.vertical_padding
-         else:
-            x_loc += max_width + self.horizontal_padding
-         counter += 1
-
-         # If we have reached the self.change_number of buttons, then it is time
-         # to start a new row or column
-         if counter == self.change_number:
-            counter = 0
-            if self.orientation == 'vertical':
-               x_loc += max_width + self.horizontal_padding
-               y_loc = self.y
-            else:
-               y_loc += max_height + self.vertical_padding
-               x_loc = self.x
-
-      # Find the smallest Rect that will contain all of the buttons
-      self.contained_rect = self.menu_items[0]['rect'].move(button['offset'])
-      for button in self.menu_items:
-         temp_rect = button['rect'].move(button['offset'])
-         self.contained_rect.union_ip(temp_rect)
-
-      # We shift the buttons around on the screen if they are supposed to be
-      # centered (on the surface itself or at (x, y).  We do it here instead of
-      # at the beginning of this function becuase we need to know what the
-      # self.contained_rect is to know the correct amount to shift them.
-      if self.centeredOnScreen:
-         shift_x = self.x - (self.draw_surface.get_rect()[2] -
-                             self.contained_rect[2]) / 2
-         shift_y = self.y - (self.draw_surface.get_rect()[3] -
-                             self.contained_rect[3]) / 2
-      elif self.centered:
-         shift_x = (self.contained_rect[2]) / 2
-         shift_y = (self.contained_rect[3]) / 2
-      if self.centeredOnScreen or self.centered:
-         # Move the buttons to make them centered
-         for button in self.menu_items:
-            button['offset'] = (button['offset'][0] - shift_x,
-                                button['offset'][1] - shift_y)
-
-         # Re-find the smallest Rect that will contain all of the buttons
-         self.contained_rect = self.menu_items[0]['rect'].move(button['offset'])
-         for button in self.menu_items:
-            temp_rect = button['rect'].move(button['offset'])
-            self.contained_rect.union_ip(temp_rect)
-
-
-   ## ---[ update ]-------------------------------------------------------------
-   #  @param   self      The class itself, Python standard
-   #  @param   e         The last event
-   #  @param   c_state   The current state of the game from where this is called
-   #  @return            A list of rectangles of where the screen changed
-   #  @return            The new state for the game
-   #
-   #  Update the menu surface, redraw it to the stored surface self.draw_surface
-   #
-   def update(self, e, c_state):
-      redraw_full_menu = False
-
-      self.selection_prev = self.selection
-      o = self.orientation
-      s = self.selection
-      n = self.change_number
-
-      if e.type == pygame.MOUSEBUTTONDOWN:
-        rectangle_list = self.draw_buttons()
-        mouseSelected = 0
-        for r in rectangle_list:
-            mouseSelected  += 1
-            mouseX = self.mousePos[0]
-            mouseY = self.mousePos[1]
-            if r[0] < mouseX and r[0]+r[2] > mouseX and r[1] < mouseY and r[1]+r[3] > mouseY:
-                self.selection = mouseSelected - 1
-      elif e.type == pygame.MOUSEMOTION:
-        self.mousePos = e.pos
-      elif e.type == pygame.MOUSEBUTTONUP:
-        rectangle_list = self.draw_buttons()
-        mouseSelected = 0
-        for r in rectangle_list:
-            mouseSelected  += 1
-            mouseX = self.mousePos[0]
-            mouseY = self.mousePos[1]
-            if r[0] < mouseX and r[0]+r[2] > mouseX and r[1] < mouseY and r[1]+r[3] > mouseY:
-                if self.selection == mouseSelected - 1:
-                    return [None], self.menu_items[self.selection]['state']
-                else:
-                    return rectangle_list, c_state
-        
-        
-      elif e.type == pygame.KEYDOWN:    
-          if e.key == pygame.K_DOWN:
-             if (o == 'vertical') and ((s + 1) % n != 0):
-                self.selection += 1
-             elif o == 'horizontal':
-                self.selection += n
-          elif e.key == pygame.K_UP:
-             if (o == 'vertical') and ((s) % n != 0):
-                self.selection -= 1
-             elif o == 'horizontal':
-                self.selection -= n
-          elif e.key == pygame.K_RIGHT:
-             if o == 'vertical':
-                self.selection += n
-             elif (o == 'horizontal') and ((s + 1) % n != 0):
-                self.selection += 1
-          elif e.key == pygame.K_LEFT:
-             if o == 'vertical':
-                self.selection -= n
-             elif (o == 'horizontal') and ((s) % n != 0):
-                self.selection -= 1
-# We don't want this in prod, but nice feature for demo!
-##          elif e.key == pygame.K_r:
-##             original_contained_rect = self.remove_buttons([s])
-##             if self.selection -1 >= 0:
-##                self.selection -= 1
-##                self.selection_prev -= 1
-##             redraw_full_menu = True
-          elif e.key == pygame.K_RETURN:
-             return [None], self.menu_items[s]['state']
-
-          if self.selection >= len(self.menu_items) or self.selection < 0:
-             self.selection = self.selection_prev
-
-      # If this is an EVENT_CHANGE_STATE, then this is the first time that we
-      # have entered this menu, so lets set it up
-      if e.type == EVENT_CHANGE_STATE:
-         # Hack to start with default choice in middle of menu...
-         #self.selection = 0
-         self.selection = self.initialSelection
-        
-         self.menu_items[self.selection_prev]['selected'] = False
-         self.menu_items[self.selection]['selected'] = True
-         self.redraw_all()
-         rectangle_list = self.draw_buttons()
-         if self.refresh_whole_surface_on_load:
-            rectangle_list = pygame.Rect((0, 0), self.draw_surface.get_size())
-            return [rectangle_list], c_state
-         else:           
-            return [self.contained_rect], c_state
-
-      elif redraw_full_menu:
-         self.menu_items[self.selection_prev]['selected'] = False
-         self.menu_items[self.selection]['selected'] = True
-         self.redraw_all()
-         rectangle_list = self.draw_buttons(original_contained_rect)
-         return rectangle_list, c_state
-
-      elif self.selection != self.selection_prev:
-         self.menu_items[self.selection_prev]['selected'] = False
-         self.menu_items[self.selection]['selected'] = True
-         rectangle_list = self.draw_buttons()
-         return rectangle_list, c_state
-
-      # If no updates were made, return defaults
-      return [None], c_state
-
-
-   ## ---[ draw_buttons ]-------------------------------------------------------
-   #  @param   self          The class itself, Python standard
-   #  @param   redraw_rect   If this pygame.Rect is provided, then the entire
-   #                         background will be drawn to the surface in the area
-   #                         of this rect before the buttons are drawn
-   #  @return                A list of rectangles of where the screen changed
-   #
-   #  Draw the buttons to the self.draw_surface and return a list of Rect's that
-   #  indicate where on the surface changes were made
-   #
-   def draw_buttons(self, redraw_rect = None):
-      rect_list = []
-
-      # If buttons have been changed (added button(s), deleted button(s),
-      # changed colors, etc, etc), then we need to update the button locations
-      # and images
-      if self.update_buttons:
-         self.update_button_locations()
-
-         # Print a warning if the buttons are partially/completely off the
-         # surface
-         if not self.draw_surface.get_rect().contains(self.contained_rect):
-            print 'WARNING:  cMenu.draw_buttons:  Some buttons are partially '\
-                  'or completely off of the self.draw_surface!'
-
-      # If a rect was provided, redraw the background surface to the area of the
-      # rect before we draw the buttons
-      if redraw_rect != None:
-         offset = (redraw_rect[0], redraw_rect[1])
-         drawn_rect = self.draw_surface.blit(self.background,
-                                             offset,
-                                             redraw_rect)
-         rect_list.append(drawn_rect)
-
-      # Cycle through the buttons, only draw the ones that need to be redrawn
-      for button in self.menu_items:
-         if button['redraw']:
-            if button['selected']:
-               image = button['s_image']
-            else:
-               image = button['u_image']
-
-            drawn_rect = self.draw_surface.blit(image,
-                                                button['offset'],
-                                                button['rect'])
-            rect_list.append(drawn_rect)
-
-      return rect_list
-
-
-#---[ END OF FILE ]-------------------------------------------------------------

Third_Party_Sources/__init__.py

-# __init__.py 
-# From Arcade Tonk Tanks created by koen Lefever
-# All modules in this directory are being called by sources from the directory above this one.
-#
-# (I learned too late for this project about the need for this key file)
-
-from MenuClass import *
-
-from pyconsole import *
-from pyconsole_syntax import *
-
-from gradients import *

Third_Party_Sources/fonts/default.ttf

Binary file removed.

Third_Party_Sources/gradients.py

-#Copyright 2006 DR0ID <dr0id@bluewin.ch> http://mypage.bluewin.ch/DR0ID
-#
-#
-#
-"""
-Allow to draw some gradients relatively easy.
-"""
-
-__author__ = "$Author: DR0ID $"
-__version__= "$Revision: 109 $"
-__date__   = "$Date: 2007-08-09 20:33:32 +0200 (Do, 09 Aug 2007) $"
-
-import pygame
-import math
-
-BLEND_MODES_AVAILABLE = False
-vernum = pygame.vernum
-if vernum[0]>=1 and vernum[1]>=8:
-    BLEND_MODES_AVAILABLE = True
-    
-
-class ColorInterpolator(object):
-    '''
-    ColorInterpolator(distance, color1, color2, rfunc, gfunc, bfunc, afunc)
-    
-    interpolates a color over the distance using different functions for r,g,b,a
-    separately (a= alpha).
-    '''
-    def __init__(self, distance, color1, color2, rfunc, gfunc, bfunc, afunc):
-        object.__init__(self)
-        
-        self.rInterpolator = FunctionInterpolator(color1[0], color2[0], distance, rfunc)
-        self.gInterpolator = FunctionInterpolator(color1[1], color2[1], distance, gfunc)
-        self.bInterpolator = FunctionInterpolator(color1[2], color2[2], distance, bfunc)
-        if len(color1)==4 and len(color2)==4:
-            self.aInterpolator = FunctionInterpolator(color1[3], color2[3], distance, afunc)
-        else:
-            self.aInterpolator = FunctionInterpolator(255, 255, distance, afunc)
-            
-    def eval(self, x):
-        '''
-        eval(x) -> color
-        
-        returns the color at the position 0<=x<=d (actually not bound to this interval).
-        '''
-##        print "colorInterp x", x, self.rInterpolator.eval(x), self.gInterpolator.eval(x), self.bInterpolator.eval(x)
-        return [self.rInterpolator.eval(x), 
-                self.gInterpolator.eval(x), 
-                self.bInterpolator.eval(x), 
-                self.aInterpolator.eval(x)]
-            
-
-
-class FunctionInterpolator(object):
-    '''
-    FunctionINterpolator(startvalue, endvalue, trange, func)
-    
-    interpolates a function y=f(x) in the range trange with
-    startvalue = f(0)
-    endvalue   = f(trange)
-    using the function func
-    '''
-    def __init__(self, startvalue, endvalue, trange, func):
-        object.__init__(self)
-        # function
-        self.func = func
-        # y-scaling
-        self.a = endvalue-startvalue
-        if self.a == 0:
-            self.a = 1.
-        # x-scaling
-        if trange!=0:
-            self.b = 1./abs(trange)
-        else:
-            self.b = 1.
-        # x-displacement
-        self.c = 0
-        # y-displacement
-        self.d = min(max(startvalue,0),255)
-        
-    def eval(self, x):
-        ''' 
-        eval(x)->float
-        
-        return value at position x
-        '''
-        # make sure that the returned value is in [0,255]
-##        return int(round(min(max(self.a*self.func(self.b*(x+self.c))+self.d, 0), 255)))
-        return int(min(max(self.a*self.func(self.b*(x+self.c))+self.d, 0), 255))
-
-
-
-##def gradient(surface, 
-##                startpoint, 
-##                endpoint, 
-##                startcolor, 
-##                endcolor,
-##                Rfunc = (lambda x:x), 
-##                Gfunc = (lambda x:x), 
-##                Bfunc = (lambda x:x), 
-##                Afunc = (lambda x:1), 
-##                type  = "line", 
-##                mode  = None ):
-##    '''
-##    surface   : surface to draw on
-##    startpoint: (x,y) point on surface
-##    endpoint  : (x,y) point on surface
-##    startcolor: (r,g,b,a) color at startpoint
-##    endcolor  : (r,g,b,a) color at endpoint
-##    Rfunc     : function y = f(x) with  startcolor =f(0) and endcolor = f(1) where 0 is at startpoint and 1 at endpoint
-##    Gfunc     :  ---  "  ---
-##    Bfunc     :  ---  "  ---
-##    Afunc     :  ---  "  ---
-##                these functions are evaluated in the range 0 <= x <= 1 and 0<= y=f(x) <= 1
-##    type      : "line", "circle" or "rect"
-##    mode      : "+", "-", "*", None (how the pixels are drawen)
-##    
-##    returns   : surface with the color characteristics w,h = (d, 256) and d = length of endpoint-startpoint
-##    
-##    '''
-##    dx = endpoint[0]-startpoint[0]
-##    dy = endpoint[1]-startpoint[1]
-##    d = int(round(math.hypot(dx, dy)))
-##    angle = math.degrees( math.atan2(dy, dx) )
-##    
-##    color = ColorInterpolator(d, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc)
-##    
-##    if type=="line":
-##        h = int(2.*math.hypot(*surface.get_size()))
-###        bigSurf = pygame.Surface((d, h)).convert_alpha()
-##        bigSurf = pygame.Surface((d, h), pygame.SRCALPHA)#.convert_alpha()
-###        bigSurf = pygame.Surface((d, 1), pygame.SRCALPHA)#.convert_alpha()
-##        bigSurf.lock()
-##        bigSurf.fill((0,0,0,0))
-##        bigSurf.set_colorkey((0,0,0,0))
-##        for x in range(d):
-##            pygame.draw.line(bigSurf, color.eval(x), (x,0), (x,h), 1)
-###        for x in range(d):
-###            bigSurf.set_at((x, 0), color.eval(x))
-###        bigSurf = pygame.transform.scale(bigSurf, (d, h))
-##            
-##        bigSurf = pygame.transform.rotate(bigSurf, -angle) #rotozoom(bigSurf, -angle, 1)
-##        bigSurf.set_colorkey((0,0,0, 0))
-##        rect = bigSurf.get_rect()
-##        srect = pygame.Rect(rect)
-##        dx = d/2. * math.cos(math.radians(angle))
-##        dy = d/2. * math.sin(math.radians(angle))
-##        rect.center = startpoint
-##        rect.move_ip(dx, dy)
-##        bigSurf.unlock()
-##        
-##    elif type=="circle":
-##        bigSurf = pygame.Surface((2*d, 2*d)).convert_alpha()
-##        bigSurf.fill((0,0,0,0))
-##        bigSurf.lock()
-##        for x in range(d, 0, -1):
-##            pygame.draw.circle(bigSurf, color.eval(x), (d,d), x)
-##        bigSurf.unlock()
-##        rect = bigSurf.get_rect()
-##        srect = pygame.Rect(rect)
-##        rect.center = (startpoint[0], startpoint[1])
-##        
-##    elif type=="rect":
-##        bigSurf = pygame.Surface((2*d, 2*d)).convert_alpha()
-##        bigSurf.fill((0,0,0,0))
-##        c = bigSurf.get_rect().center
-##        bigSurf.lock()
-##        for x in range(d,-1,-1):
-##            r = pygame.Rect(0,0,2*x,2*x)
-##            r.center = c
-##            pygame.draw.rect(bigSurf, color.eval(x), r)
-##        bigSurf.unlock()
-##        bigSurf = pygame.transform.rotozoom(bigSurf, -angle, 1)
-##        bigSurf.set_colorkey((0,0,0, 0))
-##        
-##        rect = bigSurf.get_rect()
-##        srect = pygame.Rect(rect)
-##        rect.center = startpoint
-##    else:
-##        raise NameError("type must be one of \"line\",\"circle\" or \"rect\"")
-##    
-##    if mode is None:
-##        surface.blit(bigSurf, rect, srect)
-##    else:
-##        if mode=="+":
-##            cf = pygame.color.add
-##        elif mode=="*":
-##            cf = pygame.color.multiply
-##        elif mode=="-":
-##            cf = pygame.color.subtract
-##        else:
-##            raise NameError("type must be one of \"+\", \"*\", \"-\" or None")
-##        irect = surface.get_clip().clip(rect)
-##        surface.lock()
-##        for x in range(irect.left, irect.left+irect.width):
-##            for y in range(irect.top, irect.top+irect.height):
-##                surface.set_at((x,y), cf(surface.get_at((x,y)), bigSurf.get_at((x-rect.left, y-rect.top)) ) )
-##        surface.unlock()
-##    
-##    del bigSurf   
-##    char = pygame.Surface((d+1, 257))
-###    char.fill((0,0,0))
-###    ox = 0
-###    oldcol = color.eval(0)
-###    for x in range(d):
-###        col = color.eval(x)
-###        pygame.draw.line(char, (255,0,0), (x, 256-col[0]), (ox, 256-oldcol[0]))
-###        pygame.draw.line(char, (0,255,0), (x, 256-col[1]), (ox, 256-oldcol[1]))
-###        pygame.draw.line(char, (0,0,255), (x, 256-col[2]), (ox, 256-oldcol[2]))
-###        pygame.draw.line(char, (255,255,255), (x, 256-col[3]), (ox, 256-oldcol[3]))
-###        ox = x
-###        oldcol = col
-###     
-##    return char
-        
-    
-    
-
-def vertical(size, startcolor, endcolor):
-    """
-    Draws a vertical linear gradient filling the entire surface. Returns a
-    surface filled with the gradient (numeric is only 2-3 times faster).
-    """
-    height = size[1]
-    bigSurf = pygame.Surface((1,height)).convert_alpha()
-    dd = 1.0/height
-    sr, sg, sb, sa = startcolor
-    er, eg, eb, ea = endcolor
-    rm = (er-sr)*dd
-    gm = (eg-sg)*dd
-    bm = (eb-sb)*dd
-    am = (ea-sa)*dd
-    for y in range(height):
-        bigSurf.set_at((0,y),
-                        (int(sr + rm*y),
-                         int(sg + gm*y),
-                         int(sb + bm*y),
-                         int(sa + am*y))
-                      )
-    return pygame.transform.scale(bigSurf, size)
-
-
-def horizontal(size, startcolor, endcolor):
-    """
-    Draws a horizontal linear gradient filling the entire surface. Returns a
-    surface filled with the gradient (numeric is only 2-3 times faster).
-    """
-    width = size[0]
-    bigSurf = pygame.Surface((width, 1)).convert_alpha()
-    dd = 1.0/width
-    sr, sg, sb, sa = startcolor
-    er, eg, eb, ea = endcolor
-    rm = (er-sr)*dd
-    gm = (eg-sg)*dd
-    bm = (eb-sb)*dd
-    am = (ea-sa)*dd
-    for y in range(width):
-        bigSurf.set_at((y,0),
-                        (int(sr + rm*y),
-                         int(sg + gm*y),
-                         int(sb + bm*y),
-                         int(sa + am*y))
-                      )
-    return pygame.transform.scale(bigSurf, size)
-
-
-def radial(radius, startcolor, endcolor):
-    """
-    Draws a linear raidal gradient on a square sized surface and returns
-    that surface.
-    """
-    bigSurf = pygame.Surface((2*radius, 2*radius)).convert_alpha()
-    bigSurf.fill((0,0,0,0))
-    dd = -1.0/radius
-    sr, sg, sb, sa = endcolor
-    er, eg, eb, ea = startcolor
-    rm = (er-sr)*dd
-    gm = (eg-sg)*dd
-    bm = (eb-sb)*dd
-    am = (ea-sa)*dd
-    
-    draw_circle = pygame.draw.circle
-    for rad in range(radius, 0, -1):
-        draw_circle(bigSurf, (er + int(rm*rad),
-                              eg + int(gm*rad),
-                              eb + int(bm*rad),
-                              ea + int(am*rad)), (radius, radius), rad)
-    return bigSurf
-
-def squared(width, startcolor, endcolor):
-    """
-    Draws a linear sqared gradient on a square sized surface and returns
-    that surface.
-    """
-    bigSurf = pygame.Surface((width, width)).convert_alpha()
-    bigSurf.fill((0,0,0,0))
-    dd = -1.0/(width/2)
-    sr, sg, sb, sa = endcolor
-    er, eg, eb, ea = startcolor
-    rm = (er-sr)*dd
-    gm = (eg-sg)*dd
-    bm = (eb-sb)*dd
-    am = (ea-sa)*dd
-    
-    draw_rect = pygame.draw.rect
-    for currentw in range((width/2), 0, -1):
-        pos = (width/2)-currentw
-        draw_rect(bigSurf, (er + int(rm*currentw),
-                            eg + int(gm*currentw),
-                            eb + int(bm*currentw),
-                            ea + int(am*currentw)), pygame.Rect(pos, pos, 2*currentw, 2*currentw ))
-    return bigSurf
-
-
-def vertical_func(size, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1)):
-    """
-    Draws a vertical linear gradient filling the entire surface. Returns a
-    surface filled with the gradient (numeric is only 2x faster).
-    Rfunc, Gfunc, Bfunc and Afunc are function like y = f(x). They define
-    how the color changes.
-    """
-    height = size[1]
-    bigSurf = pygame.Surface((1,height)).convert_alpha()
-    color = ColorInterpolator(height, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc)
-    for y in range(0, height):
-        bigSurf.set_at((0,y), color.eval(y+0.1))
-    return pygame.transform.scale(bigSurf, size)
-
-
-def horizontal_func(size, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1)):
-    """
-    Draws a horizontal linear gradient filling the entire surface. Returns a
-    surface filled with the gradient (numeric is only 2x faster).
-    Rfunc, Gfunc, Bfunc and Afunc are function like y = f(x). They define
-    how the color changes.
-    """
-    width = size[0]
-    bigSurf = pygame.Surface((width, 1)).convert_alpha()
-    color = ColorInterpolator(width, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc)
-    for y in range(0, width):
-        bigSurf.set_at((y, 0), color.eval(y+0.1))
-    return pygame.transform.scale(bigSurf, size)
-
-def radial_func(radius, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), colorkey=(0,0,0,0)):
-    """
-    Draws a linear raidal gradient on a square sized surface and returns
-    that surface.
-    """
-    bigSurf = pygame.Surface((2*radius, 2*radius)).convert_alpha()
-    if len(colorkey)==3:
-        colorkey += (0,)
-    bigSurf.fill(colorkey)
-    color = ColorInterpolator(radius, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc)
-    draw_circle = pygame.draw.circle
-    for rad in range(radius, 0, -1):
-        draw_circle(bigSurf, color.eval(rad), (radius, radius), rad)
-    return bigSurf
-
-def radial_func_offset(radius, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), colorkey=(0,0,0,0), offset=(0,0)):
-    """
-    Draws a linear raidal gradient on a square sized surface and returns
-    that surface.
-    offset is the amount the center of the gradient is displaced of the center of the image.
-    Unfotunately this function ignores alpha.
-    """
-    bigSurf = pygame.Surface((2*radius, 2*radius))#.convert_alpha()
-    
-    mask = pygame.Surface((2*radius, 2*radius), pygame.SRCALPHA)#.convert_alpha()
-    mask.fill(colorkey)
-    mask.set_colorkey((255,0,255))
-    pygame.draw.circle(mask, (255,0,255), (radius, radius), radius)
-    
-    if len(colorkey)==3:
-        colorkey += (0,)
-    bigSurf.fill(colorkey)
-    
-    color = ColorInterpolator(radius, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc)
-    draw_circle = pygame.draw.circle
-    radi = radius + int(math.hypot(offset[0], offset[1])+1)
-    for rad in range(radi, 0, -1):
-        draw_circle(bigSurf, color.eval(rad), (radius+offset[0], radius+offset[1]), rad)
-        
-    bigSurf.blit(mask, (0,0))
-    bigSurf.set_colorkey(colorkey)
-    return bigSurf
-
-
-def squared_func(width, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), offset=(0,0)):
-    """
-    Draws a linear sqared gradient on a square sized surface and returns
-    that surface.
-    """
-    bigSurf = pygame.Surface((width, width)).convert_alpha()
-    bigSurf.fill((0,0,0,0))
-    color = ColorInterpolator(width/2, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc)
-    draw_rect = pygame.draw.rect
-    widthh = width+2*int(max(abs(offset[0]),abs(offset[1])))
-    for currentw in range((widthh/2), 0, -1):
-##        pos = (width/2)-currentw
-        rect = pygame.Rect(0, 0, 2*currentw, 2*currentw )
-        rect.center = (width/2+offset[0], width/2+offset[1])
-        draw_rect(bigSurf, color.eval(currentw), rect)
-    return bigSurf
-
-def draw_gradient(surface, startpoint, endpoint, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), mode=0):
-    """
-    Instead of returning an Surface, this function draw it directy onto the 
-    given Surface and returns the rect.
-    """
-    dx = endpoint[0]-startpoint[0]
-    dy = endpoint[1]-startpoint[1]
-    d = int(round(math.hypot(dx, dy)))
-    angle = math.degrees( math.atan2(dy, dx) )
-    
-    h = int(2.*math.hypot(*surface.get_size()))
-    
-    bigSurf = horizontal_func((d,h), startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc)
-    
-##    bigSurf = pygame.transform.rotate(bigSurf, -angle) #rotozoom(bigSurf, -angle, 1)
-    bigSurf = pygame.transform.rotozoom(bigSurf, -angle, 1)
-##    bigSurf.set_colorkey((0,0,0, 0))
-    rect = bigSurf.get_rect()
-    srect = pygame.Rect(rect)
-    dx = d/2. * math.cos(math.radians(angle))
-    dy = d/2. * math.sin(math.radians(angle))
-    rect.center = startpoint
-    rect.move_ip(dx, dy)
-    if BLEND_MODES_AVAILABLE:
-        return surface.blit(bigSurf, rect, None, mode)
-    else:
-        return surface.blit(bigSurf, rect)
-
-
-def draw_circle(surface, startpoint, endpoint, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), mode=0):
-    """
-    Instead of returning an Surface, this function draw it directy onto the 
-    given Surface and returns the rect.
-    """
-    dx = endpoint[0]-startpoint[0]
-    dy = endpoint[1]-startpoint[1]
-    radius = int(round(math.hypot(dx, dy)))
-    pos = (startpoint[0]-radius, startpoint[1]-radius)
-    if BLEND_MODES_AVAILABLE:
-        return surface.blit(radial_func(radius, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc), pos, None, mode)
-    else:
-        return surface.blit(radial_func(radius, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc), pos)
-
-def draw_squared(surface, startpoint, endpoint, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), mode=0):
-    """
-    Instead of returning an Surface, this function draw it directy onto the 
-    given Surface and returns the rect.
-    """
-    dx = endpoint[0]-startpoint[0]
-    dy = endpoint[1]-startpoint[1]
-    angle = math.degrees( math.atan2(dy, dx) )
-    width = 2*int(round(math.hypot(dx, dy)))
-    
-    bigSurf = squared_func(width, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc)
-    
-    bigSurf = pygame.transform.rotozoom(bigSurf, -angle, 1)
-##    bigSurf.set_colorkey((0,0,0, 0))
-    rect = bigSurf.get_rect()
-    rect.center = startpoint
-    if BLEND_MODES_AVAILABLE:
-        return surface.blit(bigSurf, rect, None, mode)
-    else:
-        return surface.blit(bigSurf, rect)
-    
-    
-def chart(startpoint, endpoint, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), scale=None):
-    """
-    This returns a Surface where the change of the colors over the distance 
-    (the width of the image) is showen as a line.
-    scale: a float, 1 is not scaling
-    """
-    dx = endpoint[0]-startpoint[0]
-    dy = endpoint[1]-startpoint[1]
-    distance = int(round(math.hypot(dx, dy)))
-    color = ColorInterpolator(distance, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc)
-    bigSurf = pygame.Surface((distance, 256))
-    bigSurf.fill((0,)*3)
-    oldcol = color.eval(0)
-    for x in range(distance):
-        r, g, b, a = color.eval(x)
-        pygame.draw.line(bigSurf, (255, 0, 0, 128), (x-1, oldcol[0]), (x, r))
-        pygame.draw.line(bigSurf, (0, 255, 0, 128), (x-1, oldcol[1]), (x, g))
-        pygame.draw.line(bigSurf, (0, 0, 255, 128), (x-1, oldcol[2]), (x, b))
-        pygame.draw.line(bigSurf, (255, 255, 255, 128), (x-1, oldcol[3]), (x, a))
-        oldcol = (r,g,b,a)
-    if scale:
-##        return pygame.transform.scale(bigSurf, size)
-        return pygame.transform.rotozoom(bigSurf, 0, scale)
-    return pygame.transform.flip(bigSurf, 0, 1)
-#------------------------------------------------------------------------------
-
-
-    
-
-def genericFxyGradient(surf, clip, color1, color2, func, intx, yint, zint=None):
-    """
-    genericFxyGradient(size, color1, color2,func, intx, yint, zint=None)
-    
-    some sort of highfield drawer :-)
-    
-    surf   : surface to draw
-    clip   : rect on surf to draw in
-    color1 : start color
-    color2 : end color
-    func   : function z = func(x,y)
-    xint   : interval in x direction where the function is evaluated
-    yint   : interval in y direction where the function is evaluated
-    zint   : if not none same as yint or xint, if None then the max and min value
-             of func is taken as z-interval
-    
-    color = a*func(b*(x+c), d*(y+e))+f
-    """
-    # make shure that x1<x2 and y1<y2 and z1<z2
-    w,h = clip.size
-    x1 = min(intx)
-    x2 = max(intx)
-    y1 = min(yint)
-    y2 = max(yint)
-    if zint: # if user give us z intervall, then use it
-        z1 = min(zint)
-        z2 = max(zint)
-    else: # look for extrema of function (not best algorithme)
-        z1 = func(x1,y1)
-        z2 = z1
-        for i in range(w):
-            for j in range(h):
-                r = func(i,j)
-                z1 = min(z1, r)
-                z2 = max(z2, r)
-                
-    x1 = float(x1)
-    x2 = float(x2)
-    y1 = float(y1)
-    y2 = float(y2)
-    z1 = float(z1)
-    z2 = float(z2)
-    if len(color1)==3:
-        color1 = list(color1)
-        color1.append(255)
-    if len(color2)==3:
-        color2 = list(color2)
-        color2.append(255)
-    
-    # calculate streching and displacement variables
-    a = ((color2[0]-color1[0])/(z2-z1), \
-         (color2[1]-color1[1])/(z2-z1), \
-         (color2[2]-color1[2])/(z2-z1), \
-         (color2[3]-color1[3])/(z2-z1) ) # streching in z direction
-    b = (x2-x1)/float(w) # streching in x direction
-    d = (y2-y1)/float(h) # streching in y direction
-    f = ( color1[0]-a[0]*z1, \
-          color1[1]-a[1]*z1, \
-          color1[2]-a[2]*z1, \
-          color1[3]-a[3]*z1 )# z displacement
-    c = x1/b
-    e = y1/d
-    
-    surff = pygame.surface.Surface((w,h)).convert_alpha()
-    # generate values
-    for i in range(h):
-        for j in range(w):
-            val = func(b*(j+c), d*(i+e))
-            #clip color
-            color = (   max(min(a[0]*val+f[0],255),0), \
-                        max(min(a[1]*val+f[1],255),0), \
-                        max(min(a[2]*val+f[2],255),0), \
-                        max(min(a[3]*val+f[3],255),0) )
-            surff.set_at( (j,i), color )
-    surf.blit(surff, clip)
-
-
-

Third_Party_Sources/pyconsole.cfg

-# # # # # # # # # # # # # # # # # # # # # # # # # # #
-# Available variables:
-#
-# bg_alpha - background alpha value, range 0 to 255 (Pretty, but a big performance hit)
-# bg_color - Background Color, RGB format
-# txt_color_i - Text Color (Input). Color of the input line, RGB format
-# txt_color_o - Text Color (Output). Color of the output lines, RGB format
-# ps1/ps2/ps3 - strings that are prefixed to each input line, like their POSIX counterparts
-# active - Whether or not the console is initially displayed
-# repeat_rate - value to pass to pygame.key.set_repeat
-# preserve_events - determines whether or not the console puts unused events back on the event queue
-# python_mode - Send commands to the python interpreter instead of the pyconsole interpreter
-# # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-bg_alpha 200
-bg_color [0x0,0x44,0xAA]
-
-txt_color_i [0xFF,0xFF,0xFF]
-txt_color_o [0xEE,0xEE,0xEE]
-
-ps1 "] "
-ps2 ">>> "
-ps3 "... "
-
-active False
-
-repeat_rate [500,30]
-
-preserve_events False
-
-python_mode False
-
-motd ["|PyConsole 0.7|","Type help for a list of commands","Press Ctrl_w to hide the console"]

Third_Party_Sources/pyconsole.py

-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
-# pyconsole - a simple console for pygame based applications 
-#
-# Copyright (C) 2006  John Schanck
-# 
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-
-import pygame, os, sys 
-from pygame.locals import *
-
-import re 		# Python's Regexp library. Used in pyconsole for parsing
-import textwrap # Used for proper word wrapping
-from string import ascii_letters
-from code import InteractiveConsole		# Gives us access to the python interpreter
-
-
-__version__ = "0.7"
-
-WIDTH=0
-HEIGHT=1
-
-OUT = 0
-IN = 1
-ERR = 2
-
-PYCONSOLE = 1
-PYTHON = 2 
-
-path = os.path.abspath(os.path.dirname(__file__))
-font_path = os.path.join(path, "fonts")
-img_path = os.path.join(path, "images")
-cfg_path = os.path.join(path, "pyconsole.cfg")
-
-
-re_token = re.compile(r"""[\"].*?[\"]|[\{].*?[\}]|[\(].*?[\)]|[\[].*?[\]]|\S+""")
-re_is_list = re.compile(r'^[{\[(]')
-re_is_number = re.compile(r"""
-						(?x)
-						[-]?[0][x][0-9a-fA-F]+[lLjJ]? | 	#  Hexadecimal
-						[-]?[0][0-7]+[lLjJ]? |				#  Octal
-						[-]?[\d]+(?:[.][\d]*)?[lLjJ]?		#  Decimal (Int or float)
-						""")
-re_is_assign = re.compile(r'[$](?P<name>[a-zA-Z_]+\S*)\s*[=]\s*(?P<value>.+)')
-re_is_comment =  re.compile(r'\s*#.*')
-re_is_var = re.compile(r'^[$][a-zA-Z_]+\w*\Z')
-
-
-
-class Writable(list):
-	line_pointer = -1
-	def write(self, line):
-		self.append(str(line))
-	def reset(self):
-		self.__init__()
-	def readline(self, size=-1):
-		# Python's interactive help likes to try and call this, which causes the program to crash
-		# I see no reason to implement interactive help.
-		raise NotImplementedError
-
-class ParseError(Exception):
-	def __init__(self, token):
-		self.token = token
-	def at_token(self):
-		return self.token
-
-def balanced(t):
-	stack = []
-	pairs = {"\'":"\'", '\"':'\"', "{":"}", "[":"]", "(":")"}
-	for char in t:
-		if stack and char == pairs[stack[-1]]:
-			stack.pop()
-		elif char in pairs:
-			stack.append(char)
-	return not bool(stack)
-	
-class Console:
-	def __init__(self, screen, rect, functions={}, key_calls={}, vars={}, syntax={}):
-		if not pygame.display.get_init():
-			raise pygame.error, "Display not initialized. Initialize the display before creating a Console"
-		
-		if not pygame.font.get_init():
-			pygame.font.init()
-
-		self.parent_screen = screen
-		self.rect = pygame.Rect(rect)
-		self.size = self.rect.size
-		
-		self.user_vars = vars		
-		self.user_syntax = syntax
-		self.user_namespace = {}
-		
-		self.variables = {\
-				"bg_alpha":int,\
-				"bg_color": list,\
-				"txt_color_i": list,\
-				"txt_color_o": list,\
-				"ps1": str,\
-				"ps2": str,\
-				"ps3": str,\
-				"active": bool,\
-				"repeat_rate": list,\
-				"preserve_events":bool,\
-				"python_mode":bool,\
-				"motd":list
-				}
-		
-		self.load_cfg()
-		
-		self.set_interpreter()
-		
-		pygame.key.set_repeat(*self.repeat_rate)
-			
-		self.bg_layer = pygame.Surface(self.size)
-		self.bg_layer.set_alpha(self.bg_alpha)
-		
-		self.txt_layer = pygame.Surface(self.size)
-		self.txt_layer.set_colorkey(self.bg_color)
-		
-		try:
-			self.font = pygame.font.Font(os.path.join(font_path,"default.ttf"), 14)
-		except IOError:
-			self.font = pygame.font.SysFont("monospace", 14)
-		
-		self.font_height = self.font.get_linesize()
-		self.max_lines = (self.size[HEIGHT] / self.font_height) - 1
-		
-		self.max_chars = (self.size[WIDTH]/(self.font.size(ascii_letters)[WIDTH]/len(ascii_letters))) - 1
-		self.txt_wrapper = textwrap.TextWrapper()
-		
-		self.c_out = self.motd
-		self.c_hist = [""]
-		self.c_hist_pos = 0
-		self.c_in = ""
-		self.c_pos = 0
-		self.c_draw_pos = 0
-		self.c_scroll = 0
-		
-		
-		self.changed = True
-		
-		self.func_calls = {}
-		self.key_calls = {}
-		
-		self.add_func_calls({"echo":self.output, "clear": self.clear, "help":self.help})
-		self.add_func_calls(functions)
-		
-		self.add_key_calls({"l":self.clear, "c":self.clear_input, "w":self.set_active})
-		self.add_key_calls(key_calls)
-		
-
-	##################
-	#-Initialization-#
-	def load_cfg(self):
-		'''\
-		Loads the config file path/pygame-console.cfg\
-		All variables are initialized to their defaults,\
-		then new values will be loaded from the config file if it exists.
-		'''
-		self.init_default_cfg()
-		if os.path.exists(cfg_path):
-			for line in file(cfg_path):
-				tokens = self.tokenize(line)
-				if re_is_comment.match(line):
-					continue
-				elif len(tokens) != 2:
-					continue
-				self.safe_set_attr(tokens[0],tokens[1])
-	
-	def init_default_cfg(self):
-		self.bg_alpha = 255
-		self.bg_color = [0x0,0x0,0x0]
-		self.txt_color_i = [0xFF,0xFF,0xFF]
-		self.txt_color_o = [0xCC,0xCC,0xCC]
-		self.ps1 = "] "
-		self.ps2 = ">>> "
-		self.ps3 = "... "
-		self.active = False
-		self.repeat_rate = [500,30]
-		self.python_mode = False
-		self.preserve_events = False
-		self.motd = ["[PyConsole 0.5]"]
-	
-	def safe_set_attr(self, name, value):
-		'''\
-		Safely set the console variables
-		'''
-		if name in self.variables:
-			if isinstance(value, self.variables[name]) or not self.variables[name]:
-				self.__dict__[name] = value
-	
-	def add_func_calls(self, functions):
-		'''\
-		Add functions to the func_calls dictionary.
-		Arguments:
-		   functions -- dictionary of functions to add.
-		'''
-		if isinstance(functions,dict):
-			self.func_calls.update(functions)
-			self.user_namespace.update(self.func_calls)
-	
-	def add_key_calls(self, functions):
-		'''\
-		Add functions to the key_calls dictionary.
-		Arguments:
-		   functions -- dictionary of key_calls to add.
-		'''
-		if isinstance(functions,dict):
-			self.key_calls.update(functions)
-	
-	def output(self, text):
-		'''\
-		Prepare text to be displayed
-		Arguments:
-		   text -- Text to be displayed
-		'''
-		if not str(text):
-			return;
-		
-		try:
-			self.changed = True
-			if not isinstance(text,str):
-				text = str(text)
-			text = text.expandtabs()
-			text = text.splitlines()
-			self.txt_wrapper.width = self.max_chars
-			for line in text:
-				for w in self.txt_wrapper.wrap(line):
-					self.c_out.append(w)
-		except:
-			pass
-	
-	def set_active(self,b=None):
-		'''\
-		Activate or Deactivate the console
-		Arguments:
-		   b -- Optional boolean argument, True=Activate False=Deactivate
-		'''
-		if not b:
-			self.active = not self.active
-		else:
-			self.active = b
-	
-	
-	def format_input_line(self):
-		'''\
-		Format input line to be displayed
-		'''
-		# The \v here is sort of a hack, it's just a character that isn't recognized by the font engine
-		text = self.c_in[:self.c_pos] + "\v" + self.c_in[self.c_pos+1:] 
-		n_max = self.max_chars - len(self.c_ps)
-		vis_range = self.c_draw_pos, self.c_draw_pos + n_max
-		return self.c_ps + text[vis_range[0]:vis_range[1]]
-	
-	def draw(self):
-		'''\
-		Draw the console to the parent screen
-		'''
-		if not self.active:
-			return;
-		
-		if self.changed:
-			self.changed = False
-			# Draw Output
-			self.txt_layer.fill(self.bg_color)
-			lines = self.c_out[-(self.max_lines+self.c_scroll):len(self.c_out)-self.c_scroll]
-			y_pos = self.size[HEIGHT]-(self.font_height*(len(lines)+1))
-			
-			for line in lines:
-				tmp_surf = self.font.render(line, True, self.txt_color_o)
-				self.txt_layer.blit(tmp_surf, (1, y_pos, 0, 0))
-				y_pos += self.font_height
-			# Draw Input
-			tmp_surf = self.font.render(self.format_input_line(), True, self.txt_color_i)
-			self.txt_layer.blit(tmp_surf, (1,self.size[HEIGHT]-self.font_height,0,0))
-			# Clear background and blit text to it
-			self.bg_layer.fill(self.bg_color)
-			self.bg_layer.blit(self.txt_layer,(0,0,0,0))
-		
-		# Draw console to parent screen
-		# self.parent_screen.fill(self.txt_color_i, (self.rect.x-1, self.rect.y-1, self.size[WIDTH]+2, self.size[HEIGHT]+2))
-		pygame.draw.rect(self.parent_screen, self.txt_color_i, (self.rect.x-1, self.rect.y-1, self.size[WIDTH]+2, self.size[HEIGHT]+2), 1)
-		self.parent_screen.blit(self.bg_layer,self.rect)
-
-	#######################################################################
-	# Functions to communicate with the console and the python interpreter#
-	def set_interpreter(self):
-		if self.python_mode:
-			self.output("Entering Python mode")
-			self.python_mode = True
-			self.python_interpreter = InteractiveConsole()
-			self.tmp_fds = []
-			self.py_fds = [Writable() for i in range(3)]
-			self.c_ps = self.ps2
-		else:
-			self.output("Entering Pyconsole mode")
-			self.python_mode = False
-			self.c_ps = self.ps1
-	
-	def catch_output(self):
-		if not self.tmp_fds:
-			print "DEBUG: pyconsole catching input"
-			self.tmp_fds = [sys.stdout, sys.stdin, sys.stderr]
-			sys.stdout, sys.stdin, sys.stderr = self.py_fds
-	
-	def release_output(self):
-		if self.tmp_fds:
-			sys.stdout, sys.stdin, sys.stderr = self.tmp_fds
-			self.tmp_fds = []
-			[fd.reset() for fd in self.py_fds]
-
-	def submit_input(self, text):
-		'''\
-		Submit input
-		   1) Move input to output
-		   2) Evaluate input
-		   3) Clear input line
-		'''
-	
-		self.clear_input()
-		self.output(self.c_ps + text)
-		self.c_scroll = 0
-		if self.python_mode:
-			self.send_python(text)
-		else:
-			self.send_pyconsole(text)
-		
-	def send_python(self, text):
-		'''\
-		Sends input the the python interpreter in effect giving the user the ability to do anything python can.
-		'''
-		self.c_ps = self.ps2
-		self.catch_output()
-		if text:
-			self.add_to_history(text)
-			r = self.python_interpreter.push(text)
-			if r:
-				self.c_ps = self.ps3
-		else:
-			code = "".join(self.py_fds[OUT])
-			self.python_interpreter.push("\n")
-			self.python_interpreter.runsource(code)
-		for i in self.py_fds[OUT]+self.py_fds[ERR]:
-			self.output(i)
-		self.release_output()
-	
-	def send_pyconsole(self, text):
-		'''\
-		Sends input to pyconsole to be interpreted
-		'''
-		if not text:	# Output a blank row if nothing is entered
-			self.output("")
-			return;
-		
-		self.add_to_history(text)
-		
-		#Determine if the statement is an assignment
-		assign = re_is_assign.match(text)
-		try:
-			#If it is tokenize only the "value" part of $name = value
-			if assign:
-				tokens = self.tokenize(assign.group('value'))
-			else:
-				tokens = self.tokenize(text)
-		except ParseError, e:
-			self.output(r'At Token: "%s"' % e.at_token())
-			return;
-		
-		if tokens == None:
-			return
-		
-		#Evaluate
-		try:
-			out = None
-			# A variable alone on a line
-			if (len(tokens) is 1) and re_is_var.match(text) and not assign:
-				out = tokens[0]
-			# Statement in the form $name = value	
-			elif (len(tokens) is 1) and assign:
-				self.setvar(assign.group('name'), tokens[0])
-			else:
-				# Function
-				out = self.func_calls[tokens[0]](*tokens[1:])
-				# Assignment from function's return value
-				if assign:
-					self.setvar(assign.group('name'), out)
-					
-			if not out == None:
-				self.output(out)
-		except (KeyError,TypeError):
-			self.output("Unknown Command: " + str(tokens[0]))
-			self.output(r'Type "help" for a list of commands.')
-			
-	
-	
-	####################################################
-	#-Functions for sharing variables with the console-#
-	def setvar(self, name, value):
-		'''\
-		Sets the value of a variable
-		'''
-		if self.user_vars.has_key(name) or not self.__dict__.has_key(name):
-			self.user_vars.update({name:value})
-			self.user_namespace.update(self.user_vars)
-		elif self.__dict__.has_key(name):
-			self.__dict__.update({name:value})
-		
-	def getvar(self, name):
-		'''\
-		Gets the value of a variable, this is useful for people that want to access console variables from within their game
-		'''
-		if self.user_vars.has_key(name) or not self.__dict__.has_key(name):
-			return self.user_vars[name]
-		elif self.__dict__.has_key(name):
-			return self.__dict__[name]
-	
-	def setvars(self, vars):
-		try:
-			self.user_vars.update(vars)
-			self.user_namespace.update(self.user_vars)
-		except TypeError:
-			self.output("setvars requires a dictionary")
-	
-	def getvars(self, opt_dict=None):
-		if opt_dict:
-			opt_dict.update(self.user_vars)
-		else:
-			return self.user_vars
-	
-	
-	def add_to_history(self, text):
-		'''\
-		Add specified text to the history
-		'''
-		self.c_hist.insert(-1,text)
-		self.c_hist_pos = len(self.c_hist)-1
-			
-	def clear_input(self):
-		'''\
-		Clear input line and reset cursor position
-		'''
-		self.c_in = ""
-		self.c_pos = 0
-		self.c_draw_pos = 0
-	
-	def set_pos(self, newpos):
-		'''\
-		Moves cursor safely
-		'''
-		self.c_pos = newpos
-		if (self.c_pos - self.c_draw_pos) >= (self.max_chars - len(self.c_ps)):
-			self.c_draw_pos = max(0, self.c_pos - (self.max_chars - len(self.c_ps)))
-		elif self.c_draw_pos > self.c_pos:
-			self.c_draw_pos = self.c_pos - (self.max_chars/2)
-			if self.c_draw_pos < 0:
-				self.c_draw_pos = 0
-				self.c_pos = 0
-	
-	def str_insert(self, text, strn):
-		'''\
-		Insert characters at the current cursor position
-		'''
-		foo = text[:self.c_pos] + strn + text[self.c_pos:]
-		self.set_pos(self.c_pos + len(strn))
-		return foo
-		
-	def process_input(self):
-		'''\
-		Loop through pygame events and evaluate them
-		'''
-		if not self.active:
-			return;
-		
-		if self.preserve_events:
-			eventlist = pygame.event.get(KEYDOWN)
-		else:
-			eventlist = pygame.event.get()
-		
-		for event in eventlist:
-			if event.type == KEYDOWN:
-				self.changed = True
-				## Special Character Manipulation
-				if event.key == K_TAB:
-					self.c_in = self.str_insert(self.c_in, "    ")
-				elif event.key == K_BACKSPACE:
-					if self.c_pos > 0:
-						self.c_in = self.c_in[:self.c_pos-1] + self.c_in[self.c_pos:]
-						self.set_pos(self.c_pos-1)
-				elif event.key == K_DELETE:
-					if self.c_pos < len(self.c_in):
-						self.c_in = self.c_in[:self.c_pos] + self.c_in[self.c_pos+1:]
-				elif event.key == K_RETURN or event.key == 271:
-					self.submit_input(self.c_in)
-				## Changing Cursor Position
-				elif event.key == K_LEFT:
-					if self.c_pos > 0:
-						self.set_pos(self.c_pos-1)
-				elif event.key == K_RIGHT:
-					if self.c_pos < len(self.c_in):
-						self.set_pos(self.c_pos+1)
-				elif event.key == K_HOME:
-					self.set_pos(0)
-				elif event.key == K_END:
-					self.set_pos(len(self.c_in))
-				## History Navigation
-				elif event.key == K_UP:
-					if len(self.c_out):
-						if self.c_hist_pos > 0:
-							self.c_hist_pos -= 1
-						self.c_in = self.c_hist[self.c_hist_pos]
-						self.set_pos(len(self.c_in))
-				elif event.key == K_DOWN:
-					if len(self.c_out):
-						if self.c_hist_pos < len(self.c_hist)-1:
-							self.c_hist_pos += 1
-						self.c_in = self.c_hist[self.c_hist_pos]
-						self.set_pos(len(self.c_in))
-				## Scrolling
-				elif event.key == K_PAGEUP:
-					if self.c_scroll < len(self.c_out)-1:
-						self.c_scroll += 1
-				elif event.key == K_PAGEDOWN:
-					if self.c_scroll > 0:
-						self.c_scroll -= 1
-				## Normal character printing
-				elif event.key >= 32:
-					mods = pygame.key.get_mods()
-					if mods & KMOD_CTRL:
-						if event.key in range(256) and chr(event.key) in self.key_calls:
-							self.key_calls[chr(event.key)]()
-					else:
-						char = str(event.unicode)
-						self.c_in = self.str_insert(self.c_in, char)
-
-	
-	def convert_token(self, tok):
-		'''\
-		Convert a token to its proper type 
-		'''
-		tok = tok.strip("$")
-		try:
-			tmp = eval(tok, self.__dict__, self.user_namespace)
-		except SyntaxError, strerror:
-			self.output("SyntaxError: " + str(strerror))
-			raise ParseError, tok
-		except TypeError, strerror:
-			self.output("TypeError: " + str(strerror))
-			raise ParseError, tok
-		except NameError, strerror:
-			self.output("NameError: " + str(strerror))
-		except:
-			self.output("Error:")
-			raise ParseError, tok
-		else:
-			return tmp
-	
-	def tokenize(self, s):
-		'''\
-		Tokenize input line, convert tokens to proper types
-		'''
-		if re_is_comment.match(s):
-			return [s]
-		
-		for re in self.user_syntax:
-			group = re.match(s)
-			if group:
-				self.user_syntax[re](self, group)
-				return
-		
-		tokens = re_token.findall(s)
-		tokens = [i.strip("\"") for i in tokens]
-		cmd = []
-		i = 0
-		while i < len(tokens):
-			t_count = 0
-			val = tokens[i]
-			
-			if re_is_number.match(val):
-				cmd.append(self.convert_token(val))
-		 	elif re_is_var.match(val):