Commit before breaking everything
[matches/honours.git] / research / transmission_spectroscopy / simulator / pgu-0.18 / pgu / gui / button.py
1 """Contains various types of button widgets."""
2
3 from pygame.locals import *
4
5 from .const import *
6 from . import widget, surface
7 from . import basic
8
9 class _button(widget.Widget):
10     # The underlying 'value' accessed by the getter and setters below
11     _value = None
12
13     def __init__(self,**params):
14         widget.Widget.__init__(self,**params)
15         self.state = 0
16     
17     def event(self,e):
18         if e.type == ENTER: self.repaint()
19         elif e.type == EXIT: self.repaint()
20         elif e.type == FOCUS: self.repaint()
21         elif e.type == BLUR: self.repaint()
22         elif e.type == KEYDOWN:
23             if e.key == K_SPACE or e.key == K_RETURN:
24                 self.state = 1
25                 self.repaint()
26         elif e.type == MOUSEBUTTONDOWN: 
27             self.state = 1
28             self.repaint()
29         elif e.type == KEYUP:
30             if self.state == 1:
31                 sub = pygame.event.Event(CLICK,{'pos':(0,0),'button':1})
32                 #self.send(sub.type,sub)
33                 self._event(sub)
34                 #self.event(sub)
35                 #self.click()
36             
37             self.state = 0
38             self.repaint()
39         elif e.type == MOUSEBUTTONUP:
40             self.state = 0
41             self.repaint()
42         elif e.type == CLICK:
43             self.click()
44         
45         self.pcls = ""
46         if self.state == 0 and self.is_hovering():
47             self.pcls = "hover"
48         if self.state == 1 and self.is_hovering():
49             self.pcls = "down"
50     
51     def click(self): 
52         pass
53
54
55 class Button(_button):
56     """A button, buttons can be clicked, they are usually used to set up callbacks.
57     
58     Example:
59         w = gui.Button("Click Me")
60         w.connect(gui.CLICK, fnc, value)
61         # Assign a new button label
62         w.value = "Hello World"
63
64     """
65
66     def __init__(self, value=None, **params):
67         """Button constructor, which takes either a string label or widget.
68         
69         See Widget documentation for additional style parameters.
70
71         """
72         params.setdefault('cls', 'button')
73         _button.__init__(self, **params)
74         self.value = value
75
76     @property
77     def value(self):
78         return self._value
79
80     @value.setter
81     def value(self, val):
82         if (isinstance(val, basestring)):
83             # Allow the choice of font to propagate to the button label
84             params = {}
85             if (self.style.font):
86                 params["font"] = self.style.font
87             val = basic.Label(val, cls=self.cls+".label", **params)
88             val.container = self
89
90         oldval = self._value
91         self._value = val
92
93         if (val != oldval):
94             # Notify any listeners that we've changed the label
95             self.send(CHANGE)
96             # Resize as needed
97             self.chsize()
98
99     def resize(self,width=None,height=None):
100         self.value.rect.x,self.value.rect.y = 0,0
101         self.value.rect.w,self.value.rect.h = self.value.resize(width,height)
102         return self.value.rect.w,self.value.rect.h
103
104     def paint(self,s):
105         rect = self.value.rect
106         if (self.pcls == "down"):
107             # Shift the contents down to emphasize the button being pressed. This
108             # is defined in the theme config file.
109             rect = rect.move((self.style.down_offset_x, self.style.down_offset_y))
110         self.value.pcls = self.pcls
111         self.value.paint(surface.subsurface(s, rect))
112
113
114 class Switch(_button):
115     """A switch can have two states, on or off."""
116
117     def __init__(self,value=False,**params):
118         params.setdefault('cls','switch')
119         _button.__init__(self,**params)
120         self.value = value
121         
122         img = self.style.off
123         self.style.width = img.get_width()
124         self.style.height = img.get_height()
125     
126     def paint(self,s):
127         #self.pcls = ""
128         #if self.container.myhover is self: self.pcls = "hover"
129         if self.value: img = self.style.on
130         else: img = self.style.off
131         s.blit(img,(0,0))
132     
133     @property
134     def value(self):
135         return self._value
136
137     @value.setter
138     def value(self, val):
139         oldval = self._value
140         self._value = val
141         if oldval != val:
142             self.send(CHANGE)
143             self.repaint()
144     
145     def click(self):
146         self.value = not self.value
147
148 class Checkbox(_button):    
149     """A type of switch that can be grouped with other checkboxes.
150     
151     Example:
152         # The 'value' parameter indicates which checkboxes are on by default
153         g = gui.Group(name='colors',value=['r','b'])
154         
155         t = gui.Table()
156         t.tr()
157         t.td(gui.Label('Red'))
158         t.td(gui.Checkbox(g,'r'))
159         t.tr()
160         t.td(gui.Label('Green'))
161         t.td(gui.Checkbox(g,'g'))
162         t.tr()
163         t.td(gui.Label('Blue'))
164         t.td(gui.Checkbox(g,'b'))
165
166     """
167     
168     def __init__(self,group,value=None,**params):
169         """Checkbox constructor.
170
171         Keyword arguments:
172             group -- the Group that this checkbox belongs to
173             value -- the initial value (True or False)
174     
175         See Widget documentation for additional style parameters.
176
177         """
178
179         params.setdefault('cls','checkbox')
180         _button.__init__(self,**params)
181         self.group = group
182         self.group.add(self)
183         if self.group.value == None:
184             self.group.value = []
185         self.value = value
186         
187         img = self.style.off
188         self.style.width = img.get_width()
189         self.style.height = img.get_height()
190     
191     def paint(self,s):
192         #self.pcls = ""
193         #if self.container.myhover is self: self.pcls = "hover"
194         if self.value in self.group.value: img = self.style.on
195         else: img = self.style.off
196         
197         s.blit(img,(0,0))
198     
199     def click(self):
200         if self.value in self.group.value:
201             self.group.value.remove(self.value)
202         else:
203             self.group.value.append(self.value)
204         self.group._change()
205
206 class Radio(_button):
207     """A type of switch that can be grouped with other radio buttons, except
208     that only one radio button can be active at a time.
209     
210     Example:
211         g = gui.Group(name='colors',value='g')
212         
213         t = gui.Table()
214         t.tr()
215         t.td(gui.Label('Red'))
216         t.td(gui.Radio(g,'r'))
217         t.tr()
218         t.td(gui.Label('Green'))
219         t.td(gui.Radio(g,'g'))
220         t.tr()
221         t.td(gui.Label('Blue'))
222         t.td(gui.Radio(g,'b'))
223
224     """    
225     
226     def __init__(self,group=None,value=None,**params):
227         """Radio constructor.
228
229         Keyword arguments:    
230             group -- the Group this radio button belongs to
231             value -- the initial value (True or False)
232
233         """
234         params.setdefault('cls','radio')
235         _button.__init__(self,**params)
236         self.group = group
237         self.group.add(self)
238         self.value = value
239         
240         img = self.style.off
241         self.style.width = img.get_width()
242         self.style.height = img.get_height()
243     
244     def paint(self,s):
245         #self.pcls = ""
246         #if self.container.myhover is self: self.pcls = "hover"
247         if self.group.value == self.value: img = self.style.on
248         else: img = self.style.off
249         s.blit(img,(0,0))
250     
251     def click(self):
252         self.group.value = self.value
253
254 class Tool(_button):
255     """Within a Group of Tool widgets only one may be selected at a time.
256
257     Example:
258         g = gui.Group(name='colors',value='g')
259         
260         t = gui.Table()
261         t.tr()
262         t.td(gui.Tool(g,'Red','r'))
263         t.tr()
264         t.td(gui.Tool(g,'Green','g'))
265         t.tr()
266         t.td(gui.Tool(g,'Blue','b'))
267
268     """
269
270     def __init__(self,group,widget=None,value=None,**params): #TODO widget= could conflict with module widget
271         """Tool constructor.
272
273         Keyword arguments:    
274             group -- a gui.Group for the Tool to belong to
275             widget -- a widget to appear on the Tool (similar to a Button)
276             value -- the value
277
278         """
279         params.setdefault('cls','tool')
280         _button.__init__(self,**params)
281         self.group = group
282         self.group.add(self)
283         self.value = value
284         
285         if widget:
286             self.setwidget(widget)
287         
288         if self.group.value == self.value: self.pcls = "down"
289     
290     def setwidget(self,w):
291         self.widget = w
292     
293     def resize(self,width=None,height=None):
294         self.widget.rect.w,self.widget.rect.h = self.widget.resize()
295         #self.widget._resize()
296         #self.rect.w,self.rect.h = self.widget.rect_margin.w,self.widget.rect_margin.h
297         
298         return self.widget.rect.w,self.widget.rect.h
299     
300     def event(self,e):
301         _button.event(self,e)
302         if self.group.value == self.value: self.pcls = "down"
303     
304     def paint(self,s):
305         if self.group.value == self.value: self.pcls = "down"
306         self.widget.paint(surface.subsurface(s,self.widget.rect))
307     
308     def click(self):
309         self.group.value = self.value
310         for w in self.group.widgets:
311             if w != self: w.pcls = ""
312
313             
314 class Icon(_button):
315     """TODO - might be deprecated
316     """
317     def __init__(self,cls,**params):
318         params['cls'] = cls
319         _button.__init__(self,**params)
320         s = self.style.image
321         self.style.width = s.get_width()
322         self.style.height = s.get_height()
323         self.state = 0
324     
325     def paint(self,s):
326         #self.pcls = ""
327         #if self.state == 0 and hasattr(self.container,'myhover') and self.container.myhover is self: self.pcls = "hover"
328         #if self.state == 1 and hasattr(self.container,'myhover') and self.container.myhover is self: self.pcls = "down"
329         s.blit(self.style.image,(0,0))
330
331 class Link(_button):
332     """A link, links can be clicked, they are usually used to set up callbacks.
333     Basically the same as the button widget, just text only with a different cls.
334     Made for convenience.
335     
336     Example:
337         w = gui.Link("Click Me")
338         w.connect(gui.CLICK,fnc,value)
339
340     """
341     def __init__(self,value,**params):
342         params.setdefault('focusable',True)
343         params.setdefault('cls','link')
344         _button.__init__(self,**params)
345         self.value = value
346         self.font = self.style.font
347         self.style.width, self.style.height = self.font.size(self.value)
348     
349     def paint(self,s):
350         s.blit(self.font.render(self.value, 1, self.style.color),(0,0))
351

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