view gamelib/gui_base.py @ 37:9c4bf1f15431

gui stuff
author Rizmari Versfeld <rizziepit@gmail.com>
date Sun, 06 May 2012 22:05:40 +0200
parents
children 7e18a67995f6
line wrap: on
line source

import pygame
from pygame.locals import *
from pygame import Surface, Rect, Color
from pygame.font import Font

from gamelib import data


# different font sizes
pygame.font.init()
font_small = Font(data.filepath('fonts/DejaVuSans.ttf'), 10)
font_medium = Font(data.filepath('fonts/DejaVuSans.ttf'), 14)
font_large = Font(data.filepath('fonts/DejaVuSans.ttf'), 18)


class Drawable(object):
  
  def __init__(self, rect):
    if isinstance(rect, Rect):
      self.rect = rect
    else:
      self.rect = Rect(rect[0],rect[1],rect[2],rect[3])
    
  def draw(self, surface):
    pass
  
  
class Clickable(object):
  
  def on_mouse_down(self, pos):
    pass
  
  def on_mouse_up(self, pos):
    pass
  
  def on_mouse_move(self, pos):
    pass
  
  def on_mouse_cancel(self):
    pass
  
  def on_click(self):
    pass
 

class ContainerView(Drawable):
  
  def __init__(self):
    self.children = []
    
  def add_child(self, child):
    self.children.append(child)
    
  def remove_child(self, child):
    self.children.remove(child)
    
  def get_child_by_pos(self, pos):
    for child in self.children:
      if child.rect.collidepoint(pos):
	if isinstance(child, ContainerView):
	  # calculates position relative to child
	  return child.get_child_by_pos((pos[0] - child.rect[0], pos[1] - child.rect[1]))
	else:
	  return child
  
  def draw_children(self, surface):
    for child in self.children:
      child.draw(surface)
    
  
class Window(Clickable, ContainerView):
  
  def __init__(self, screen):
    super(Window, self).__init__()
    self.surface = Surface((screen.get_width(), screen.get_height()))
    self.background_colour = None
    self.background_image = None
    self.pressed_child = None
    
  def on_mouse_down(self, pos):
    child = self.get_child_by_pos(pos)
    if isinstance(child, Clickable):
       # calculates position relative to child
      child.on_mouse_down((pos[0] - child.rect[0], pos[1] - child.rect[1]))
      self.pressed_child = child
      
  def on_mouse_up(self, pos):
    if self.pressed_child:
      child = self.pressed_child
      child.on_mouse_up((pos[0] - child.rect[0], pos[1] - child.rect[1]));
      self.pressed_child = None
      
  def on_mouse_move(self, pos):
    if self.pressed_child and self.pressed_child != self.get_child_by_pos(pos):
      self.pressed_child.on_mouse_cancel()
      self.pressed_child = None
    
  def draw(self, screen):
    if self.background_colour:
      self.surface.fill(self.background_colour)
    if self.background_image:
      self.surface.blit(self.background_image, (0,0))
    self.draw_children(self.surface)
    screen.blit(self.surface, (0,0))
    

class StateDrawable(Drawable):
  
  def __init__(self, rect):
    super(StateDrawable, self).__init__(rect)
    self.state = -1
    self.states = {}
    self.drawables = []
    self.surface = Surface((self.rect[2], self.rect[3]))
    
  def draw(self, surface):
    if self.state != -1 and self.drawables[self.state]:
      self.drawables[self.state].draw(surface)
      
  def add_state(self, state_name, drawable):
    self.states[state_name] = len(self.drawables)
    self.drawables.append(drawable)
    
  def set_state(self, state_name):
    self.state = self.states[state_name]
    
    
class Button(Clickable, StateDrawable):
  
  def __init__(self, rect, normal_drawable, down_drawable):
    super(Button, self).__init__(rect)
    self.add_state('NORMAL', normal_drawable)
    self.add_state('DOWN', down_drawable)
    self.set_state('NORMAL')
    
  def on_mouse_down(self, pos):
    self.set_state('DOWN')
  
  def on_mouse_up(self, pos):
    self.set_state('NORMAL')
    self.on_click()   
  
  def on_mouse_cancel(self):
    self.set_state('NORMAL')
    
    
class TextButton(Button):

  def __init__(self, rect, normal_drawable, down_drawable, text):
    super(TextButton, self).__init__(rect, normal_drawable, down_drawable)
    self.surface = Surface((rect[2],rect[3]))
    self.text = text
    font_large.set_bold(True)
    self.text_surface = font_large.render(self.text, True, (128,128,128,128))
    shadow = font_large.render(self.text, True, (0,0,0,255))
    font_large.set_bold(False)
    self.text_surface.blit(shadow, (-2, -2))
    size = font_large.size(self.text)
    self.text_offset = ((rect[2]-size[0])/2, (rect[3]-size[1])/2)
    
  def draw(self, surface):
    self.surface.fill((0,0,0,0))
    super(TextButton, self).draw(self.surface)
    self.surface.blit(self.text_surface, self.text_offset)
    surface.blit(self.surface, self.rect)