You can click! But the buttons don't care {yet} if it was a button you
[krufty_fps.git] / pygame_gui / DerGUI.py
blob7efa9cca634ca5d4ec420f6224ad4fd733669e26
1 #!/usr/bin/python
3 import os, sys
4 from os import *
5 from os.path import *
7 from xml.dom.minidom import parse, parseString
9 from zipfile import *
11 import pygame
12 from pygame import *
14 import StringIO
16 import copy
18 FONT_NAME = 'serif'
19 FONT_SIZE = 30
20 FONT_COLOR = (255, 255, 255)
22 class GuiSystem:
24 def __init__(self, gui_def, theme):
26 assert is_zipfile(theme)
27 assert exists(gui_def)
29 self.zipfile = ZipFile(theme)
31 self.definitions = self.parse_gui_def(gui_def)
33 pygame.init()
35 assert pygame.font.get_init()
37 self.the_font = pygame.font.SysFont(FONT_NAME, FONT_SIZE)
39 self.images = {}
41 assert self.getImages()
43 self.widgets = []
45 def parse_gui_def(self, gui_def):
46 results = {}
48 dom = parse(gui_def)
50 if dom.childNodes[0].nodeName == 'widgets':
52 widgets = {}
54 for node in dom.childNodes[0].childNodes:
56 image_list = []
58 if node.nodeName == 'images':
60 for sub_node in node.childNodes:
61 if sub_node.nodeName == 'image':
63 image = {'filename': '', name: ''}
65 for sub_sub_node in sub_node.childNodes:
67 if sub_sub_node.nodeName == 'filename':
68 image['filename'] = sub_sub_node.childNodes[0].nodeValue
69 if sub_sub_node.nodeName == 'name':
70 image['name'] = sub_sub_node.childNodes[0].nodeValue
72 if 'posix' in image:
73 del image['posix']
74 image_list.append(image)
76 results['image_list'] = image_list
78 if node.nodeName == 'widget':
80 widget = {}
82 widget['parameters'] = {}
83 widget['parts'] = {}
84 widget['behaviors'] = {}
86 for sub_node in node.childNodes:
87 if sub_node.nodeName == 'name' and len(sub_node.childNodes):
88 widget['name'] = sub_node.childNodes[0].nodeValue
90 if sub_node.nodeName == 'parameter':
92 parameter = {}
93 parameter['name'] = sub_node.attributes['name'].value
95 widget['parameters'][parameter['name']] = ''
97 if sub_node.nodeName == 'part':
99 part_name = sub_node.getElementsByTagName('name')[0].childNodes[0].nodeValue
100 widget['parts'][part_name] = {}
102 for sub_sub_node in sub_node.childNodes:
104 if sub_sub_node.nodeName == 'type':
105 widget['parts'][part_name]['type'] = sub_sub_node.childNodes[0].nodeValue.encode()
107 if sub_sub_node.nodeName == 'source':
108 widget['parts'][part_name]['source'] = sub_sub_node.childNodes[0].nodeValue.encode()
110 if sub_sub_node.nodeName == 'position':
111 widget['parts'][part_name]['position'] = sub_sub_node.childNodes[0].nodeValue.encode()
113 if sub_sub_node.nodeName == 'size':
114 widget['parts'][part_name]['size'] = sub_sub_node.childNodes[0].nodeValue.encode()
116 if sub_node.nodeName == 'behavior':
118 event_type = sub_node.getElementsByTagName('on_event')[0].childNodes[0].nodeValue
119 the_do = sub_node.getElementsByTagName('do')[0].childNodes[0].nodeValue
121 widget['behaviors'][event_type] = the_do
123 widgets[widget['name']] = widget
125 results['widgets'] = widgets
127 return results
129 def getImages(self):
131 image_list = self.definitions['image_list']
132 name_list = []
134 name_list = self.zipfile.namelist()
136 for image in image_list:
138 if image['filename'] not in name_list:
139 return 0
141 else:
142 the_string_io = StringIO.StringIO()
143 print >>the_string_io, self.zipfile.read(image['filename'])
144 the_string_io.seek(0)
146 self.images[image['name']] = pygame.image.load(the_string_io).convert_alpha()
148 return 1
150 def event(self, the_event):
152 new_event = self.convertEvent(the_event)
154 if not new_event['type'].find('MOUSE') == -1:
156 for widget in self.widgets:
158 widget_rect = widget.getRect()
159 if widget_rect.collidepoint(new_event['data']['pos']):
160 if new_event['type'] != 'MOUSEMOTION':
161 self.focus = widget
163 self.focus.event(new_event)
165 return
167 def convertEvent(self, e):
169 data = {}
171 if e.type == QUIT:
172 data['none'] = ''
174 if e.type == ACTIVEEVENT:
175 data['gain'] = e.gain
176 data['state'] = e.state
178 if e.type == KEYDOWN:
179 data['unicode'] = e.unicode
180 data['key'] = e.key
181 data['mod'] = e.mod
183 if e.type == KEYUP:
184 data['key'] = e.key
185 data['mod'] = e.mod
187 if e.type == MOUSEMOTION:
188 data['pos'] = e.pos
189 data['rel'] = e.rel
190 data['buttons'] = e.buttons
192 if e.type == MOUSEBUTTONUP:
193 data['pos'] = e.pos
194 data['button'] = e.button
196 if e.type == MOUSEBUTTONDOWN:
197 data['pos'] = e.pos
198 data['button'] = e.button
200 if e.type == JOYAXISMOTION:
201 data['joy'] = e.joy
202 data['axis'] = e.axis
203 data['value'] = e.value
205 if e.type == JOYBALLMOTION:
206 data['joy'] = e.joy
207 data['ball'] = e.ball
208 data['rel'] = e.rel
210 if e.type == JOYHATMOTION:
211 data['joy'] = e.joy
212 data['hat'] = e.hat
213 data['value'] = e.value
215 if e.type == JOYBUTTONUP:
216 data['joy'] = e.joy
217 data['button'] = e.button
219 if e.type == JOYBUTTONDOWN:
220 data['joy'] = e.joy
221 data['button'] = e.button
223 if e.type == VIDEORESIZE:
224 data['size'] = e.size
225 data['w'] = e.w
226 data['h'] = e.h
228 if e.type == VIDEOEXPOSE:
229 data['none'] = ''
231 if e.type == USEREVENT:
232 data['code'] = e.code
234 type = ''
236 if e.type == QUIT: type = "QUIT"
237 if e.type == ACTIVEEVENT: type = "ACTIVEEVENT"
238 if e.type == KEYDOWN: type = "KEYDOWN"
239 if e.type == KEYUP: type = "KEYUP"
240 if e.type == MOUSEMOTION : type = "MOUSEMOTION"
241 if e.type == MOUSEBUTTONUP: type = "MOUSEBUTTONUP"
242 if e.type == MOUSEBUTTONDOWN: type = "MOUSEBUTTONDOWN"
243 if e.type == JOYAXISMOTION: type = "JOYAXISMOTION"
244 if e.type == JOYBALLMOTION: type = "JOYBALLMOTION"
245 if e.type == JOYHATMOTION: type = "JOYHATMOTION"
246 if e.type == JOYBUTTONUP: type = "JOYBUTTONUP"
247 if e.type == JOYBUTTONDOWN: type = "JOYBUTTONDOWN"
248 if e.type == VIDEORESIZE: type = "VIDEORESIZE"
249 if e.type == VIDEOEXPOSE: type = "VIDEOEXPOSE"
250 if e.type == USEREVENT: type = "USEREVENT"
252 new_event = {}
254 new_event['type'] = type
255 new_event['data'] = data
257 return new_event
259 def draw(self, dest_surface):
261 for widget in self.widgets:
263 if widget.params['parameters']['visible']:
264 widget.draw(dest_surface)
266 return
268 def makeWidget(self, widget_name, params):
270 if self.definitions['widgets'].has_key(widget_name):
272 new_params = copy.copy(self.definitions['widgets'][widget_name])
273 new_params['parameters'] = params
275 the_widget = Widget(self, widget_name, new_params)
277 self.widgets.append(the_widget)
279 if len(self.widgets) == 1:
280 self.focus = the_widget
282 return the_widget
284 class Widget:
286 def __init__(self, the_gui_system, widget_name, params):
288 self.name = widget_name
289 self.params = params
290 self.the_gui_system = the_gui_system
292 assert self.params['parameters'].has_key('x')
293 assert self.params['parameters'].has_key('y')
295 if not self.params['parameters'].has_key('visible'):
296 self.params['parameters']['visible'] = 1
298 return
300 def move(self, (new_x, new_y)):
302 self.params['parameters']['x'], self.params['parameters']['y'] = new_x, new_y
304 return
306 def hide(self):
308 self.params['parameters']['visible'] = 0
310 return
312 def show(self):
314 self.params['parameters']['visible'] = 1
316 return
318 def getRect(self):
320 coords = (self.params['parameters']['x'], self.params['parameters']['y'])
321 dimensions = (self.params['parameters']['width'], self.params['parameters']['height'])
323 return pygame.Rect(coords, dimensions)
325 def event(self, the_event):
327 if self.params['behaviors'].has_key(the_event['type']):
329 the_value = self.params['behaviors'][the_event['type']]
331 exec(the_value)
333 return
335 def setPart(self, old_part, new_part):
337 self.params['parts'][old_part]['source'] = new_part
338 return
340 def raiseEvent(self, the_event, parameters={}):
342 print "raiseEvent(): Not implemented"
344 return
346 def draw(self, dest_surface):
348 code = ''
350 for image in self.the_gui_system.images:
352 code = ''.join([code, '\n', image, ' = self.the_gui_system.images["', image, '"]'])
354 try:
355 exec(code)
356 except:
357 assert 0
359 for part in self.params['parts']:
361 if self.params['parts'][part]['type'] == 'text':
363 # here be dragons
364 try:
365 exec(''.join([part, ' = self.the_gui_system.the_font.render(self.params["parameters"][self.params["parts"][part]["source"]], FONT_SIZE, FONT_COLOR)\nthe_source =', part]))
366 except:
367 assert 0
369 width = self.params['parameters']['width']
370 height = self.params['parameters']['height']
372 position = eval(self.params['parts'][part]['position'])
373 size = eval(self.params['parts'][part]['size'])
375 position = [position[0], position[1]]
377 position[0] += self.params['parameters']['x']
378 position[1] += self.params['parameters']['y']
380 if self.params['parts'][part]['type'] == 'image':
382 if size[0] > 0 and size[1] > 0:
383 the_source = pygame.transform.scale(self.the_gui_system.images[self.params['parts'][part]['source']], size)
384 dest_surface.blit(the_source, position)
386 if self.params['parts'][part]['type'] == 'text':
388 dest_surface.blit(the_source, position, pygame.Rect((0, 0), size))
390 if self.params['parts'][part]['type'] == 'widget':
392 pass # implement nested widgets
394 return
396 # end