ARGH
[matches/honours.git] / research / transmission_spectroscopy / simulator / pgu-0.18 / pgu / gui / basic.py
1 """Basic widgets and various utility functions.
2 """
3
4 ###########
5 # Imports #
6 ###########
7
8 import pygame
9
10 from .const import *
11 from . import widget
12 from .errors import PguError
13
14 #############
15 # Functions #
16 #############
17
18 # Turns a descriptive string or a tuple into a pygame color
19 def parse_color(desc):
20     if (is_color(desc)):
21         # Already a color
22         return desc
23     elif (desc and desc[0] == "#"):
24         # Because of a bug in pygame 1.8.1 we need to explicitly define the 
25         # alpha value otherwise it will default to transparent.
26         if (len(desc) == 7):
27             desc += "FF"
28     return pygame.Color(desc)
29
30 # Determines if the given object is a pygame-compatible color or not
31 def is_color(col):
32     # In every version of pygame (up to 1.8.1 so far) will interpret
33     # a tuple as a color.
34     if (type(col) == tuple or type(col) == list):
35         return col
36     if (hasattr(pygame, "Color") and type(pygame.Color) == type):
37         # This is a recent version of pygame that uses a proper type
38         # instance for colors.
39         return (isinstance(col, pygame.Color))
40     # Otherwise, this version of pygame only supports tuple colors
41     return False
42
43 ###########
44 # Classes #
45 ###########
46
47 class Spacer(widget.Widget):
48     """An invisible space widget."""
49
50     def __init__(self,width,height,**params):
51         params.setdefault('focusable',False)
52         widget.Widget.__init__(self,width=width,height=height,**params)
53         
54
55 class Color(widget.Widget):
56     """A widget that renders as a solid block of color.
57     
58     Note the color can be changed by setting the 'value' field, and the 
59     widget will automatically be repainted, eg:
60
61         c = Color()
62         c.value = (255,0,0)
63         c.value = (0,255,0)
64
65     """
66
67     # The pygame Color instance
68     _value = None
69     
70     def __init__(self,value=None,**params):
71         params.setdefault('focusable',False)
72         if value != None: params['value']=value
73         widget.Widget.__init__(self,**params)
74     
75     def paint(self,s):
76         if hasattr(self,'value') and is_color(self.value): 
77             s.fill(self.value)
78
79     @property
80     def value(self):
81         return self._value
82
83     @value.setter
84     def value(self, val):
85         if (isinstance(val, basestring)):
86             # Parse the string as a color
87             val = parse_color(val)
88         oldval = self._value
89         self._value = val
90         if (oldval != val):
91             # Emit a change signal
92             self.send(CHANGE)
93             self.repaint()
94     
95
96 class Label(widget.Widget):
97     """A text label widget."""
98
99     def __init__(self, value="", **params):
100         params.setdefault('focusable', False)
101         params.setdefault('cls', 'label')
102         widget.Widget.__init__(self, **params)
103         self.style.check("font")
104         self.value = value
105         self.font = self.style.font
106         self.style.width, self.style.height = self.font.size(self.value)
107     
108     def paint(self,s):
109         """Renders the label onto the given surface in the upper-left corner."""
110         s.blit(self.font.render(self.value, 1, self.style.color),(0,0))
111
112     def set_text(self, txt):
113         """Set the text of this label."""
114         self.value = txt
115         # Signal to the application that we need to resize this widget
116         self.chsize()
117
118     def set_font(self, font):
119         """Set the font used to render this label."""
120         self.font = font
121         # Signal to the application that we need a resize
122         self.chsize()
123
124     def resize(self,width=None,height=None):
125         # Calculate the size of the rendered text
126         (self.style.width, self.style.height) = self.font.size(self.value)
127         return (self.style.width, self.style.height)
128
129
130 class Image(widget.Widget):
131     """An image widget. The constructor takes a file name or a pygame surface."""
132
133     def __init__(self,value,**params):
134         params.setdefault('focusable',False)
135         widget.Widget.__init__(self,**params)
136
137         if (not value):
138             raise PguError("Image widget takes a path or pygame surface as first argument")
139
140         if (isinstance(value, basestring)):
141             # Assume the argument is a path
142             value = pygame.image.load(value)
143             if (not value):
144                 raise PguError("Cannot load the image '%s'" % value)
145
146         ow,oh = iw,ih = value.get_width(),value.get_height()
147         sw,sh = self.style.width,self.style.height
148         
149         if sw and not sh:
150             iw,ih = sw,ih*sw/iw
151         elif sh and not sw:
152             iw,ih = iw*sh/ih,sh
153         elif sw and sh:
154             iw,ih = sw,sh
155         
156         if (ow,oh) != (iw,ih):
157             value = pygame.transform.scale(value,(iw,ih))
158         self.style.width,self.style.height = iw,ih
159         self.value = value
160     
161     def paint(self,s):
162         s.blit(self.value,(0,0))
163

UCC git Repository :: git.ucc.asn.au