1 """Contains various types of button widgets."""
3 from pygame.locals import *
6 from . import widget, surface
9 class _button(widget.Widget):
10 # The underlying 'value' accessed by the getter and setters below
13 def __init__(self,**params):
14 widget.Widget.__init__(self,**params)
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:
26 elif e.type == MOUSEBUTTONDOWN:
31 sub = pygame.event.Event(CLICK,{'pos':(0,0),'button':1})
32 #self.send(sub.type,sub)
39 elif e.type == MOUSEBUTTONUP:
46 if self.state == 0 and self.is_hovering():
48 if self.state == 1 and self.is_hovering():
55 class Button(_button):
56 """A button, buttons can be clicked, they are usually used to set up callbacks.
59 w = gui.Button("Click Me")
60 w.connect(gui.CLICK, fnc, value)
61 # Assign a new button label
62 w.value = "Hello World"
66 def __init__(self, value=None, **params):
67 """Button constructor, which takes either a string label or widget.
69 See Widget documentation for additional style parameters.
72 params.setdefault('cls', 'button')
73 _button.__init__(self, **params)
82 if (isinstance(val, basestring)):
83 # Allow the choice of font to propagate to the button label
86 params["font"] = self.style.font
87 val = basic.Label(val, cls=self.cls+".label", **params)
94 # Notify any listeners that we've changed the label
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
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))
114 class Switch(_button):
115 """A switch can have two states, on or off."""
117 def __init__(self,value=False,**params):
118 params.setdefault('cls','switch')
119 _button.__init__(self,**params)
123 self.style.width = img.get_width()
124 self.style.height = img.get_height()
128 #if self.container.myhover is self: self.pcls = "hover"
129 if self.value: img = self.style.on
130 else: img = self.style.off
138 def value(self, val):
146 self.value = not self.value
148 class Checkbox(_button):
149 """A type of switch that can be grouped with other checkboxes.
152 # The 'value' parameter indicates which checkboxes are on by default
153 g = gui.Group(name='colors',value=['r','b'])
157 t.td(gui.Label('Red'))
158 t.td(gui.Checkbox(g,'r'))
160 t.td(gui.Label('Green'))
161 t.td(gui.Checkbox(g,'g'))
163 t.td(gui.Label('Blue'))
164 t.td(gui.Checkbox(g,'b'))
168 def __init__(self,group,value=None,**params):
169 """Checkbox constructor.
172 group -- the Group that this checkbox belongs to
173 value -- the initial value (True or False)
175 See Widget documentation for additional style parameters.
179 params.setdefault('cls','checkbox')
180 _button.__init__(self,**params)
183 if self.group.value == None:
184 self.group.value = []
188 self.style.width = img.get_width()
189 self.style.height = img.get_height()
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
200 if self.value in self.group.value:
201 self.group.value.remove(self.value)
203 self.group.value.append(self.value)
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.
211 g = gui.Group(name='colors',value='g')
215 t.td(gui.Label('Red'))
216 t.td(gui.Radio(g,'r'))
218 t.td(gui.Label('Green'))
219 t.td(gui.Radio(g,'g'))
221 t.td(gui.Label('Blue'))
222 t.td(gui.Radio(g,'b'))
226 def __init__(self,group=None,value=None,**params):
227 """Radio constructor.
230 group -- the Group this radio button belongs to
231 value -- the initial value (True or False)
234 params.setdefault('cls','radio')
235 _button.__init__(self,**params)
241 self.style.width = img.get_width()
242 self.style.height = img.get_height()
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
252 self.group.value = self.value
255 """Within a Group of Tool widgets only one may be selected at a time.
258 g = gui.Group(name='colors',value='g')
262 t.td(gui.Tool(g,'Red','r'))
264 t.td(gui.Tool(g,'Green','g'))
266 t.td(gui.Tool(g,'Blue','b'))
270 def __init__(self,group,widget=None,value=None,**params): #TODO widget= could conflict with module widget
274 group -- a gui.Group for the Tool to belong to
275 widget -- a widget to appear on the Tool (similar to a Button)
279 params.setdefault('cls','tool')
280 _button.__init__(self,**params)
286 self.setwidget(widget)
288 if self.group.value == self.value: self.pcls = "down"
290 def setwidget(self,w):
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
298 return self.widget.rect.w,self.widget.rect.h
301 _button.event(self,e)
302 if self.group.value == self.value: self.pcls = "down"
305 if self.group.value == self.value: self.pcls = "down"
306 self.widget.paint(surface.subsurface(s,self.widget.rect))
309 self.group.value = self.value
310 for w in self.group.widgets:
311 if w != self: w.pcls = ""
315 """TODO - might be deprecated
317 def __init__(self,cls,**params):
319 _button.__init__(self,**params)
321 self.style.width = s.get_width()
322 self.style.height = s.get_height()
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))
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.
337 w = gui.Link("Click Me")
338 w.connect(gui.CLICK,fnc,value)
341 def __init__(self,value,**params):
342 params.setdefault('focusable',True)
343 params.setdefault('cls','link')
344 _button.__init__(self,**params)
346 self.font = self.style.font
347 self.style.width, self.style.height = self.font.size(self.value)
350 s.blit(self.font.render(self.value, 1, self.style.color),(0,0))