Merge lp:~codeforger/simplegc/simplegc into lp:simplegc

Proposed by Sam Bull
Status: Merged
Merged at revision: 274
Proposed branch: lp:~codeforger/simplegc/simplegc
Merge into: lp:simplegc
Diff against target: 996 lines (+713/-62)
9 files modified
example/test_lists.py (+68/-0)
sgc/__init__.py (+6/-0)
sgc/widgets/base_widget.py (+3/-0)
sgc/widgets/button.py (+13/-16)
sgc/widgets/composite/dialogs.py (+98/-0)
sgc/widgets/lists.py (+383/-0)
sgc/widgets/menu.py (+19/-12)
sgc/widgets/opengl.py (+121/-32)
sgc/widgets/radio_button.py (+2/-2)
To merge this branch: bzr merge lp:~codeforger/simplegc/simplegc
Reviewer Review Type Date Requested Status
Sam Bull Needs Fixing
Review via email: mp+115960@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Sam Bull (dreamsorcerer) wrote :

Unresolved conflicts that should never have been committed.
Remove extra line breaks added into multiple files.
Remove matrix.py and revert opengl.py.

review: Needs Fixing
Revision history for this message
Sam Bull (dreamsorcerer) wrote :

My mistake, conflicts are with newer trunk. Resolve the conflicts, and also revert helloworld.py (this is for one of the tutorials, put you example code into test.py), _locals.py, base_widget.py, menu.py, radio_button.py.

Revision history for this message
Michael Rochester (codeforger) wrote :

This merge also contains the new button style I invented, would you like me to revert that too?

lp:~codeforger/simplegc/simplegc updated
273. By Michael Rochester

merge

274. By Michael Rochester

merge

275. By Michael Rochester

moved test code to test.py

276. By Michael Rochester

reverted /example/helloworld.py

277. By Michael Rochester

fixed my idiocy with test.py

278. By Michael Rochester

removed matrix.py as requested

Revision history for this message
Sam Bull (dreamsorcerer) wrote :

> This merge also contains the new button style I invented, would you like me to
> revert that too?

Yes please.

lp:~codeforger/simplegc/simplegc updated
279. By Michael Rochester

reverted button.py to the old buttons style

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'example/test_lists.py'
2--- example/test_lists.py 1970-01-01 00:00:00 +0000
3+++ example/test_lists.py 2012-07-21 12:53:18 +0000
4@@ -0,0 +1,68 @@
5+import sgc
6+from sgc.locals import *
7+
8+import pygame
9+from pygame.locals import *
10+
11+pygame.display.init()
12+pygame.font.init()
13+
14+screen = sgc.surface.Screen((640,480))
15+
16+clock = pygame.time.Clock()
17+
18+lst = sgc._List(width=(100),pos=(10,10),multi_selection=True,content=("hello","world","nice","to","meet","you"))
19+lst.add(0)
20+
21+mullst = sgc._MultiList(pos=(10,150),columnwidth=(150,150),content=(["hello","world"],["nice","to"],["meet","you"]))
22+mullst.add(0)
23+
24+listb = sgc.ListBox((100,100),pos=(150,10),multi_selection=True,content=("hello","world","nice","to","meet","you"))
25+listb.add(0)
26+
27+list2 = sgc.ListBox((100,100),pos=(300,10),header="head",content=("hello","world","nice","to","meet","you"))
28+list2.add(0)
29+
30+data = (["Hello","12Mb","30/06/2012"],
31+ ["World","15Mb","30/06/2012"],
32+ ["Nice","123Kb","19/06/2012"],
33+ ["To","1.2Gb","29/06/2012"],
34+ ["Meet","12Mb","25/06/2012"],
35+ ["You","6Mb","30/06/2012"])
36+
37+
38+mullist = sgc.MultiListBox((200,100), pos=(370,150), columnwidth=(150,50,100), content=data)
39+mullist.add(0)
40+
41+head = ("Name","Size","Modified")
42+
43+mullist2 = sgc.MultiListBox((100,100), pos=(100,300), multi_selection=True, header=head, columnwidth=(150,150,150), content=data)
44+mullist2.add(0)
45+
46+def print_attr():
47+ x = mullist2.selected_text
48+ print x
49+
50+def print_pos():
51+ x = mullist2.selected_pos
52+ print x
53+
54+btn = sgc.Button(pos=(300,400), label="get attr")
55+btn.on_click = print_attr
56+btn.add(0)
57+
58+btn2 = sgc.Button(pos=(300,300), label="get pos")
59+btn2.on_click = print_pos
60+btn2.add(0)
61+
62+while True:
63+ time = clock.tick(30)
64+
65+ for event in pygame.event.get():
66+ sgc.event(event)
67+ if event.type == QUIT:
68+ exit()
69+
70+ screen.fill((200,200,200))
71+ sgc.update(time)
72+ pygame.display.flip()
73
74=== modified file 'sgc/__init__.py'
75--- sgc/__init__.py 2012-07-19 13:33:13 +0000
76+++ sgc/__init__.py 2012-07-21 12:53:18 +0000
77@@ -21,12 +21,18 @@
78 from widgets.boxes import VBox, HBox
79 from widgets.button import Button
80 from widgets.container import Container
81+from widgets.composite.dialogs import DialogSaveQuit
82 from widgets.dialog import Dialog
83 from widgets.fps_counter import FPSCounter
84 from widgets.input_box import InputBox
85 from widgets.label import Label
86+from widgets.lists import MultiListBox
87+from widgets.lists import ListBox
88+from widgets.lists import _List
89+from widgets.lists import _MultiList
90 from widgets.menu import Menu
91 from widgets.radio_button import Radio
92 from widgets.scroll_box import ScrollBox
93 from widgets.settings import Keys
94 from widgets.switch import Switch
95+
96
97=== modified file 'sgc/widgets/base_widget.py'
98--- sgc/widgets/base_widget.py 2012-07-18 09:38:26 +0000
99+++ sgc/widgets/base_widget.py 2012-07-21 12:53:18 +0000
100@@ -237,6 +237,9 @@
101 return surf
102 elif isinstance(surf, str):
103 return pygame.image.load(surf).convert_alpha()
104+ elif isinstance(surf, opengl.OpenGLImage):
105+ self._custom_image = True
106+ return surf
107
108 # Create base images
109 self._custom_image = False
110
111=== modified file 'sgc/widgets/button.py'
112--- sgc/widgets/button.py 2012-06-16 11:01:51 +0000
113+++ sgc/widgets/button.py 2012-07-21 12:53:18 +0000
114@@ -58,16 +58,15 @@
115 # Clear previous renderings
116 del self._settings["label"][1:]
117 label = self._settings["label"][0].split("\n")
118- f = Font["widget"]
119- h = f.get_ascent()
120 for count, line in enumerate(label):
121- lbl = Simple(f.render(line, True, self._settings["label_col"]))
122+ lbl = Simple(Font["widget"].render(line, True,
123+ self._settings["label_col"]))
124 self._settings["label"].append(lbl)
125- y = (self.rect.h - (h * len(label)) + f.get_descent()) / 2 + \
126- (h * count)
127+ y = (self.rect.h - (lbl.rect.h * len(label))) / 2 + \
128+ (lbl.rect.h * count)
129 lbl.rect.midtop = (self.rect.w/2, y)
130
131- def _draw_base(self, draw):
132+ def _draw(self, draw):
133 # Frames around edge of button
134 x = min(self.image.get_size()) / 8
135 self._frame_lt = ((0,0), (self.rect.w,0), (self.rect.w-x,x),
136@@ -81,18 +80,16 @@
137 cols["over"] = [min(c*1.1, 255) for c in self._settings["col"]]
138 cols["down"] = [c*0.8 for c in self._settings["col"]]
139 for img in cols:
140- self._images[img].fill(cols[img])
141- # Draw a frame around the edges of the button
142- frame_lt_c = [min(c*1.3,255) for c in cols[img]]
143- frame_rb_c = [c*0.8 for c in cols[img]]
144- draw.polygon(self._images[img], frame_lt_c, self._frame_lt)
145- draw.polygon(self._images[img], frame_rb_c, self._frame_rb)
146-
147- def _draw_final(self, draw):
148- for img in self._images.values():
149+ if not self._custom_image:
150+ self._images[img].fill(cols[img])
151+ # Draw a frame around the edges of the button
152+ frame_lt_c = [min(c*1.3,255) for c in cols[img]]
153+ frame_rb_c = [c*0.8 for c in cols[img]]
154+ draw.polygon(self._images[img], frame_lt_c, self._frame_lt)
155+ draw.polygon(self._images[img], frame_rb_c, self._frame_rb)
156 # Blit label onto button
157 for line in self._settings["label"][1:]:
158- img.blit(line.image, line.pos)
159+ self._images[img].blit(line.image, line.pos)
160 self._draw_button()
161
162 def on_click(self):
163
164=== added directory 'sgc/widgets/composite'
165=== added file 'sgc/widgets/composite/__init__.py'
166=== added file 'sgc/widgets/composite/dialogs.py'
167--- sgc/widgets/composite/dialogs.py 1970-01-01 00:00:00 +0000
168+++ sgc/widgets/composite/dialogs.py 2012-07-21 12:53:18 +0000
169@@ -0,0 +1,98 @@
170+#!/usr/bin/env python
171+
172+# Copyright (C) 2012 Michael Rochester
173+
174+"""
175+Dialog composite widgets. A list of predefined common dialogs
176+
177+"""
178+import sgc
179+from sgc.locals import *
180+
181+from ..dialog import *
182+
183+class DialogSaveQuit (Dialog):
184+ """
185+ This dialog is designed to be called when a user tries to quit without saving.
186+ It will emmit 2 GUI events: 'quit' and 'save'.
187+ If the final option 'cancel' is selected, the dialog will remove its self.
188+ """
189+ def _config(self, **kwargs):
190+ """
191+ doctitle: ``str`` The text that will be used as the documents Title.
192+ """
193+ if "init" in kwargs:
194+ self.lbl = sgc.Label(pos=(10,10),text="The document has not been saved.\nWould you like to save the changes before quitting?", col=(20,20,20))
195+ self.btn_save = sgc.Button(pos=(200,100), label="Save")
196+ self.btn_save.on_click = self.send_save
197+ self.btn_quit = sgc.Button((200,50), pos=(0,100), label="Close without saving")
198+ self.btn_quit.on_click = self.send_quit
199+ self.btn_cancel = sgc.Button(pos=(310,100), label="Cancel")
200+ self.btn_cancel.on_click = self.send_cancel
201+ contain = sgc.Container(pos=(0,0), widgets=[self.lbl,self.btn_quit,self.btn_cancel,self.btn_save] )
202+
203+ kwargs["widget"] = contain;
204+ kwargs["title"]="Save changes?"
205+ sgc.Dialog._config(self,**kwargs)
206+ if "doctitle" in kwargs:
207+ self.lbl.text = "The document \"" + kwargs["doctitle"] + "\" has not been saved.\nWould you like to save the changes before quitting?"
208+ def send_quit(self):
209+ ev = pygame.event.Event(GUI, {"gui_type": "quit",
210+ "widget_type": self.__class__,
211+ "widget":self})
212+ pygame.event.post(ev)
213+
214+ def send_save(self):
215+ ev = pygame.event.Event(GUI, {"gui_type": "save",
216+ "widget_type": self.__class__,
217+ "widget":self})
218+ pygame.event.post(ev)
219+ def send_cancel(self):
220+ ev = pygame.event.Event(GUI, {"gui_type": "cancel",
221+ "widget_type": self.__class__,
222+ "widget":self})
223+ pygame.event.post(ev)
224+
225+class DialogSave (Dialog):
226+ """
227+ This dialog is designed to be called when a user tries to quit without saving.
228+ It will emmit 2 GUI events: 'quit' and 'save'.
229+ If the final option 'cancel' is selected, the dialog will remove its self.
230+ """
231+ def _config(self, **kwargs):
232+ """
233+ doctitle: ``str`` The text that will be used as the documents Title.
234+ """
235+ if "init" in kwargs:
236+ self.lbl = sgc.Label(pos=(10,10),text="The document has not been saved.\nWould you like to save the changes before quitting?", col=(20,20,20))
237+ self.btn_save = sgc.Button(pos=(200,100), label="Save")
238+ self.btn_save.on_click = self.send_save
239+ self.btn_quit = sgc.Button((200,50), pos=(0,100), label="Close without saving")
240+ self.btn_quit.on_click = self.send_quit
241+ self.btn_cancel = sgc.Button(pos=(310,100), label="Cancel")
242+ self.btn_cancel.on_click = self.send_cancel
243+ contain = sgc.Container(pos=(0,0), widgets=[self.lbl,self.btn_quit,self.btn_cancel,self.btn_save] )
244+
245+ kwargs["widget"] = contain;
246+ kwargs["title"]="Save changes?"
247+ sgc.Dialog._config(self,**kwargs)
248+ if "doctitle" in kwargs:
249+ self.lbl.text = "The document \"" + kwargs["doctitle"] + "\" has not been saved.\nWould you like to save the changes before quitting?"
250+ def send_quit(self):
251+ ev = pygame.event.Event(GUI, {"gui_type": "quit",
252+ "widget_type": self.__class__,
253+ "widget":self})
254+ pygame.event.post(ev)
255+
256+ def send_save(self):
257+ ev = pygame.event.Event(GUI, {"gui_type": "save",
258+ "widget_type": self.__class__,
259+ "widget":self})
260+ pygame.event.post(ev)
261+ def send_cancel(self):
262+ ev = pygame.event.Event(GUI, {"gui_type": "cancel",
263+ "widget_type": self.__class__,
264+ "widget":self})
265+ pygame.event.post(ev)
266+
267+
268
269=== added file 'sgc/widgets/lists.py'
270--- sgc/widgets/lists.py 1970-01-01 00:00:00 +0000
271+++ sgc/widgets/lists.py 2012-07-21 12:53:18 +0000
272@@ -0,0 +1,383 @@
273+#!/usr/bin/env python
274+
275+# Copyright (C) 2012 Michael Rochester
276+
277+import sgc
278+from sgc.locals import *
279+
280+import pygame.mouse
281+from pygame.locals import *
282+
283+from _locals import *
284+from base_widget import Simple
285+
286+class _List(Simple):
287+
288+ _can_focus = True
289+ _settings_default = {"col": (118, 45, 215),
290+ "font": Font["widget"],
291+ "padding": 3,"offset": 0,"width":None,
292+ "mult": False}
293+
294+
295+ def _config(self,**kwargs):
296+ self.anchor = False
297+ if "multi_selection" in kwargs:
298+ self._settings["mult"] = kwargs["multi_selection"]
299+ if "padding" in kwargs:
300+ self._settings["padding"] = kwargs["padding"]
301+ if "init" in kwargs:
302+ self.color = (118, 45, 215)
303+ self.contain = sgc.Container(border=self._settings["padding"])
304+ self.lbls=[]
305+ self.selected=[]
306+ if "col" in kwargs:
307+ self.color = kwargs["col"]
308+ if "font" in kwargs:
309+ self._settings["font"] = kwargs["font"]
310+ if "width" in kwargs:
311+ self._settings["width"] = kwargs["width"]
312+ if "content" in kwargs:
313+ self.content = kwargs["content"]
314+ self.texth = self._settings["font"].get_ascent()+\
315+ self._settings["font"].get_descent()+\
316+ (self._settings["padding"]*2)
317+ p=0
318+ for string in kwargs["content"]:
319+ lbl = sgc.Label(pos=(0,p),col=(10,10,10),text=string,
320+ font=self._settings["font"])
321+ p+=self.texth
322+ self.lbls.append(lbl)
323+ self.contain.config(widgets=self.lbls)
324+ if not hasattr(self, "image"):
325+ self._create_base_images((self.contain.image.get_width() if
326+ self._settings["width"] == None else self._settings["width"]
327+ ,self.contain.image.get_height()))
328+
329+ def _event(self, event):
330+ if event.type == MOUSEBUTTONDOWN and event.button == 1:
331+ sel = self.colide_item(event.pos)
332+ if sel > 0 and sel < len(self.content)+1:
333+ if (pygame.key.get_mods() & KMOD_CTRL and self._settings["mult"]):
334+
335+ if sel in self.selected:
336+ self.selected.remove(sel)
337+ else:
338+ self.selected.append(sel)
339+ elif (pygame.key.get_mods() & KMOD_SHIFT
340+ and self._settings["mult"] and self.anchor):
341+ self.selected=[]
342+ for new in range(abs(self.anchor-sel)+1):
343+ self.selected.append(new+(min(self.anchor,sel)))
344+ else:
345+ self.anchor = sel
346+ self.selected = [sel]
347+
348+ def update(self, time):
349+ draw = self.get_draw()
350+
351+ self.contain.update(time)
352+ self.image.fill((255,255,255))
353+
354+ for sel in self.selected:
355+ w = (self.image.get_width())
356+ selection = Simple((w, self.texth))
357+ selection.pos = (0,(sel-1)*self.texth+self._settings["padding"])
358+ selection.image.fill(self.color)
359+ selection.image.set_alpha(100)
360+ self.image.blit(selection.image, selection.pos)
361+ self.image.blit(self.contain.image,(0,0))
362+ self.image.blit(self._images["image"],(0,0))
363+
364+ def colide_item(self,pos):
365+ pos = pos[1]-self.rect_abs.y
366+ return ((pos-self._settings["padding"])/self.texth)+1
367+
368+ def _focus_enter(self, focus):
369+ self.color = self._settings["col"]
370+
371+ def _focus_exit(self):
372+ self.color = (179,179,179)
373+
374+ @property
375+ def selected_text(self):
376+ return [self.content[x-1] for x in self.selected]
377+
378+ @property
379+ def selected_pos(self):
380+ return [x-1 for x in self.selected]
381+
382+class ListBox(Simple):
383+
384+ _can_focus = True
385+ _default_size = (100,100)
386+ _settings_default = {"headfont": Font["widget"],
387+ "offset": 0}
388+
389+ def _config(self,**kwargs):
390+ if "header" in kwargs:
391+ self._settings["header"] = kwargs["header"]
392+ self._settings["offset"] = self._settings["headfont"].get_ascent()+\
393+ self._settings["headfont"].get_descent()+6
394+ if "init" in kwargs:
395+ self.list = _List(width=self.image.get_width())
396+ self.scroll = sgc.ScrollBox((self.rect.w,self.rect.h-self._settings["offset"]),pos=(0,self._settings["offset"]),widget=self.list)
397+ self.scroll._parent = self
398+ self.list.config(**kwargs)
399+ self.scroll.config(widget=self.list,**kwargs)
400+
401+ def _draw(self,draw):
402+ if "header" in self._settings:
403+ lbl = sgc.Label(pos=(0,0),col=(10,10,10),
404+ text=self._settings["header"],
405+ font=self._settings["headfont"])
406+ self._images["image"].blit(lbl.image,(3,1))
407+ draw.line(self._images["image"],(150,150,150),
408+ (1,self._settings["offset"]),
409+ (self.image.get_width()-2,self._settings["offset"]))
410+
411+ draw.line(self._images["image"],(150,150,150),
412+ (1,0),(self.image.get_width()-2,0))
413+ draw.line(self._images["image"],(150,150,150),
414+ (1,self.image.get_height()-1),
415+ (self.image.get_width()-2,self.image.get_height()-1))
416+ draw.line(self._images["image"],(150,150,150),
417+ (0,1),(0,self.image.get_height()-2))
418+ draw.line(self._images["image"],(150,150,150),
419+ (self.image.get_width()-1,1),
420+ (self.image.get_width()-1,self.image.get_height()-2))
421+
422+ def _event(self, event):
423+ self.scroll._event(event)
424+
425+ def update(self, time):
426+ self.scroll.update(time)
427+ self.image.fill((255,255,255))
428+ self.image.blit(self.scroll.image,(0,self._settings["offset"]))
429+ self.image.blit(self._images["image"],(0,0))
430+
431+ def _focus_enter(self, focus):
432+ self.scroll._focus_enter(focus)
433+
434+ def _focus_exit(self):
435+ self.scroll._focus_exit()
436+
437+ @property
438+ def selected_text(self):
439+ return [x for x in self.list.selected_text]
440+
441+ @property
442+ def selected_pos(self):
443+ return [x for x in self.list.selected]
444+
445+
446+class _MultiList(_List):
447+
448+ _can_focus = True
449+ _settings_default = {"col": (118, 45, 215),
450+ "font": Font["widget"],
451+ "padding": 3,"offset": 0,
452+ "mult": False,"colwid":False}
453+
454+
455+ def _config(self,**kwargs):
456+ self.anchor = False
457+ if "multi_selection" in kwargs:
458+ self._settings["mult"] = kwargs["multi_selection"]
459+ if "padding" in kwargs:
460+ self._settings["padding"] = kwargs["padding"]
461+ if "init" in kwargs:
462+ self.color = (118, 45, 215)
463+ self.lbls=[]
464+ self.selected=[]
465+ if "col" in kwargs:
466+ self.color = kwargs["col"]
467+ if "font" in kwargs:
468+ self._settings["font"] = kwargs["font"]
469+ if "columnwidth" in kwargs:
470+ self._settings["colwid"] = kwargs["columnwidth"]
471+ if "content" in kwargs:
472+
473+ self.columns = []
474+ self.content = kwargs["content"]
475+ self.texth = self._settings["font"].get_ascent()+\
476+ self._settings["font"].get_descent()+\
477+ (self._settings["padding"]*2)
478+ w = []
479+ for x in range(len(kwargs["content"][0])):
480+ labels = []
481+ p=0
482+ for y in range(len(kwargs["content"])):
483+ lbl = sgc.Label(pos=(0,p),col=(10,10,10),text=kwargs["content"][y][x],
484+ font=self._settings["font"])
485+ p+=self.texth
486+ labels.append(lbl)
487+ w.append(lbl)
488+ self.lbls.append(labels)
489+ if self._settings["colwid"]:
490+ column = sgc.Container((self._settings["colwid"][x],len(kwargs["content"])*self.texth),widgets=labels)
491+ else:
492+ column = sgc.Container(widgets=labels)
493+ self.columns.append(column)
494+
495+ self.contain = sgc.HBox(border=self._settings["padding"],widgets=self.columns)
496+ self.rect.w = self.contain.rect.w
497+ self.rect.h = self.contain.rect.h
498+ if not hasattr(self, "image"):
499+ self._create_base_images((self.contain.image.get_width()
500+ ,self.contain.image.get_height()))
501+
502+ @property
503+ def selected_text(self):
504+ return [self.content[x-1] for x in self.selected]
505+
506+ @property
507+ def selected_pos(self):
508+ return [x-1 for x in self.selected]
509+
510+class MultiListBox(ListBox):
511+
512+ _can_focus = True
513+ _default_size = (100,100)
514+ _settings_default = {"headfont": Font["widget"],
515+ "offset": 0,"colwid": 100,"header":None}
516+
517+
518+ def _config(self,**kwargs):
519+ if "content" in kwargs:
520+ self.content = kwargs["content"]
521+ if "columnwidth" in kwargs:
522+ self.colpos=[0]
523+ self._settings["colwid"] = [c for c in kwargs["columnwidth"]]
524+ for x in range(len(kwargs["columnwidth"])):
525+ self.colpos.append((self.colpos[x]+self._settings["colwid"][x]))
526+ if "header" in kwargs:
527+ self._settings["header"] = kwargs["header"]
528+ self._settings["offset"] = self._settings["headfont"].get_ascent()+\
529+ self._settings["headfont"].get_descent()+6
530+
531+
532+ if "init" in kwargs:
533+ strings = pygame.cursors.sizer_x_strings
534+ cursor = pygame.cursors.compile(strings)
535+ size = (len(strings[0]), len(strings))
536+ hotspot = (size[0]/2, size[1]/2)
537+ self._cursor = (size, hotspot) + cursor
538+ self._cursor_set = False
539+
540+ self.move = False
541+ self.mouse = False
542+ self.resize = False
543+ self.list = _MultiList()
544+ self.scroll = sgc.ScrollBox((self.rect.w,self.rect.h-self._settings["offset"]),pos=(0,self._settings["offset"]),widget=self.list)
545+ self.scroll._parent = self
546+ if self._settings["colwid"] != 100:
547+ kwargs["columnwidth"] = self._settings["colwid"]
548+ if "content" not in kwargs:
549+ kwargs["content"]=self.content
550+ self.list.config(**kwargs)
551+ if "init" in kwargs:
552+ self.scroll.config(widget=self.list,**kwargs)
553+
554+ def _draw(self,draw):
555+
556+ if self._settings["header"]:
557+ self.header = sgc.Simple((self.colpos[-1]+10,self._settings["offset"]))
558+ for p, header in enumerate(self._settings["header"]):
559+ lbl = sgc.Label((self._settings["colwid"][p],self._settings["offset"]),pos=(0,0),
560+ text=header,
561+ col=(10,10,10),
562+
563+ font=self._settings["headfont"])
564+ draw.rect(self.header.image,(255,255,255),((self.colpos[p],0),(self.colpos[p]+self._settings["colwid"][p],self._settings["offset"])),0)
565+ self.header.image.blit(lbl.image,(self.colpos[p]+6*p+3,1))
566+ draw.line(self.header.image,(150,150,150),
567+ (self.colpos[p]+6*(p),0),
568+ (self.colpos[p]+6*(p),self._settings["offset"]))
569+
570+
571+ draw.line(self._images["image"],(150,150,150),
572+ (1,0),(self.image.get_width()-2,0))
573+ draw.line(self._images["image"],(150,150,150),
574+ (1,self.image.get_height()-1),
575+ (self.image.get_width()-2,self.image.get_height()-1))
576+ draw.line(self._images["image"],(150,150,150),
577+ (0,1),(0,self.image.get_height()-2))
578+ draw.line(self._images["image"],(150,150,150),
579+ (self.image.get_width()-1,1),
580+ (self.image.get_width()-1,self.image.get_height()-2))
581+ self.image.fill((255,0,0))
582+
583+ def _event(self, event):
584+ if (event.type == MOUSEBUTTONDOWN and event.button == 1
585+ and (self.collidehead(event.pos)is not False)):
586+ self.move = self.collidehead(event.pos)
587+ self.mouse = event.pos[0]
588+ elif event.type == MOUSEBUTTONUP:
589+ if self.resize is not False and self.mouse is not False:
590+ self.scroll = sgc.ScrollBox((self.rect.w,self.rect.h-self._settings["offset"]),pos=(0,self._settings["offset"]),widget=self.list)
591+ self.scroll._parent = self
592+ self.mouse = False
593+ self.resize = False
594+ elif event.type == MOUSEMOTION:
595+ if self.collidehead(event.pos) is False and self._cursor_set==True:
596+ self._remove_cursor()
597+ self._cursor_set = False
598+ elif self.collidehead(event.pos) is not False and self._cursor_set==False:
599+ self._set_cursor(*self._cursor)
600+ self._cursor_set = True
601+ if self.resize is not False and self.mouse is not False:
602+ dif = event.pos[0] - self.mouse
603+ self.mouse = event.pos[0]
604+ self._settings["colwid"][self.move]+=dif
605+ if self._settings["colwid"][self.move] < 0:
606+ self._settings["colwid"][self.move] = 0
607+ self.config(columnwidth=self._settings["colwid"], content=self.content)
608+ self.list._create_base_images((self.list.rect.w, self.list.rect.h))
609+ elif self.mouse is not False:
610+ if abs(event.pos[0] - self.mouse) > 4:
611+ self.resize = True
612+ self.scroll._event(event)
613+
614+ def collidehead(self,pos):
615+ for p, x in enumerate(self.colpos[1:],1):
616+ if (pos[0]-self.pos_abs[0]>=self.scroll._settings["widget"].pos[0]+x+6*p-2 and
617+ pos[0]-self.pos_abs[0]<=self.scroll._settings["widget"].pos[0]+x+6*p+2 and
618+ pos[1] < self.pos_abs[1]+self._settings["offset"] and
619+ pos[1] > self.pos_abs[1]):
620+ return p-1
621+ return False
622+
623+ def update(self, time):
624+ self.scroll.update(time)
625+ self.image.fill((255,255,255))
626+ self.image.blit(self.scroll.image,(0,self._settings["offset"]))
627+ if self._settings["header"]:
628+ self.image.blit(self.header.image,(self.scroll._settings["widget"].pos[0],0)) #MAYBE A HACK, PROBABLY
629+ self.image.blit(self._images["image"],(0,0))
630+
631+ def _focus_enter(self, focus):
632+ self.scroll._focus_enter(focus)
633+
634+ def _focus_exit(self):
635+ self.scroll._focus_exit()
636+
637+ @property
638+ def selected_text(self):
639+ return [x for x in self.list.selected_text]
640+
641+ @property
642+ def selected_pos(self):
643+ return [x for x in self.list.selected]
644+
645+
646+
647+
648+
649+
650+
651+
652+
653+
654+
655+
656
657=== modified file 'sgc/widgets/menu.py'
658--- sgc/widgets/menu.py 2012-07-18 11:56:10 +0000
659+++ sgc/widgets/menu.py 2012-07-21 12:53:18 +0000
660@@ -120,18 +120,24 @@
661 widgets.append(div)
662 # Widget
663 elif item[0].startswith("w:"):
664- args = item[1]
665- name = args.pop("name", None)
666- try:
667- # Try to load existing widget
668- widget = eval(item[0][2:])
669- except NameError:
670- # Try to import custom widget
671- parts = item[0][2:].rpartition(".")
672- mod = __import__(parts[0])
673- widget = getattr(mod, parts[2])
674- widget = widget(**args)
675- if name: self._dict[name] = widget
676+ args = self._get_args(item[1:])
677+ name = args.pop("name")
678+ f = args.pop("func") if ("func" in args) else None
679+ if item[0].endswith("input_box"):
680+ widget = input_box.InputBox(**args)
681+ elif item[0].endswith("button"):
682+ if "surf" in args:
683+ args["surf"] = eval(args["surf"])
684+ widget = button.Button(**args)
685+ elif item[0].endswith("radio"):
686+ if "surf" in args:
687+ args["surf"] = eval(args["surf"])
688+ widget = radio_button.Radio(**args)
689+ elif item[0].endswith("label"):
690+ widget = label.Label(**args)
691+ self._dict[name] = widget
692+ if f: widget.on_click = self._funcs[f]
693+ widget.name = name
694 widgets.append(widget)
695 # Function
696 elif item[0].startswith("f:"):
697@@ -176,6 +182,7 @@
698 def update(self, time):
699 menu = self._menus[self._curr_menu]
700 menu.update(time)
701+ self.image.fill(0) # Hack for OpenGL
702 if self._old_menu is not None:
703 self.image.blit(self._menus[self._old_menu].image, (0,0))
704 menu.image.set_alpha(menu._fade)
705
706=== modified file 'sgc/widgets/opengl.py'
707--- sgc/widgets/opengl.py 2011-09-22 09:41:10 +0000
708+++ sgc/widgets/opengl.py 2012-07-21 12:53:18 +0000
709@@ -1,9 +1,9 @@
710 #!/usr/bin/env python
711
712-# Copyright (C) 2011 Sam Bull
713+# Copyright (C) 2011-2012 Sam Bull
714
715 """
716-Base widget, all widgets inherit from this.
717+OpenGL functions.
718
719 """
720
721@@ -11,10 +11,11 @@
722 from OpenGL.GL import *
723 import FTGL
724
725-from ..surface import SurfaceBase
726-
727-
728-class OpenGLImage(SurfaceBase):
729+from _locals import *
730+from matrix import Matrix
731+
732+
733+class OpenGLImage():
734 """
735 Class used to emulate the interface of Surface for OpenGL drawing.
736
737@@ -28,39 +29,49 @@
738 self._lock = False
739 self.display_list = []
740 self._children = []
741- if parent:
742- self._parent = parent # Parent surface used for _abs
743- else:
744- self._parent = self._default_screen
745+ self.matrix = Matrix()
746+ self._parent = parent # Parent surface used for _abs
747
748- self._rect = Rect((0,0), (0,0))
749+ self.rect = Rect((0,0), (0,0))
750 if isinstance(surf, (tuple,list)):
751- self._rect.size = surf
752+ self.rect.size = surf
753 elif isinstance(surf, OpenGLFont):
754- self._rect.size = (surf.size)
755+ self.rect.size = (surf.size)
756 self.display_list.extend(surf.display_list)
757 elif isinstance(surf, OpenGLImage):
758- self._rect = surf._rect
759+ self.matrix = surf.matrix.copy()
760+ self.rect = Rect(surf.rect)
761 self._a = surf._a
762- self.display_list = surf.display_list
763- self._children = surf._children
764+ self.display_list = surf.display_list[:]
765+ for child in surf._children:
766+ self.blit(child.copy())
767
768- def blit(self, surf, pos=None):
769+ def blit(self, surf, pos=None, area=None):
770 assert isinstance(surf, OpenGLImage)
771 if surf not in self._children:
772 if pos is not None: surf.pos = pos
773+ surf.rect.topleft = surf.pos
774 surf._parent = self
775 self._children.append(surf)
776
777 def draw(self):
778 glLoadIdentity()
779- if self.rect.w <= self._parent.rect.w and \
780- self.rect.h <= self._parent.rect.h:
781+ if self._parent:
782+ r = self._parent.rect
783+ else:
784+ r = Rect(0,0,10000,10000)
785+ if self.rect.w <= r.w and self.rect.h <= r.h:
786 # Mask the area, so nothing is drawn outside surface area.
787- bottom = self._default_screen.h - self.rect_abs.bottom
788+ bottom = 480 - self.rect_abs.bottom # Screen height...
789 glScissor(self.rect_abs.x, bottom,
790 self.rect.w+1, self.rect.h+1)
791 glTranslatef(self.pos_abs[0], self.pos_abs[1], 0)
792+ if not isinstance(self.matrix, (list, tuple)):
793+ glMultMatrixf(self.matrix.to_opengl())
794+ else:
795+ for m in self.matrix:
796+ glMultMatrixf(m.to_opengl())
797+
798 for dl,col in self.display_list:
799 if col is not None: glColor(col[0], col[1], col[2], self.a)
800 glCallList(dl)
801@@ -73,7 +84,7 @@
802 # Clear the surface
803 self.display_list = []
804 self._children = []
805- rect = Rect((0,0), self.size)
806+ rect = Rect((0,0), self.rect.size)
807 if col != 0:
808 col = [c/255. for c in col]
809 dl = glGenLists(1)
810@@ -86,7 +97,13 @@
811 return OpenGLImage(self)
812
813 def get_size(self):
814- return self.size
815+ return self.rect.size
816+
817+ def get_height(self):
818+ return self.rect.h
819+
820+ def get_width(self):
821+ return self.rect.w
822
823 def set_alpha(self, alpha):
824 self._a = alpha/255.
825@@ -127,7 +144,7 @@
826 self._lock = False
827
828 def replace(self, surf, **kwargs):
829- self._rect.size = surf.size
830+ self.rect.size = surf.size
831 self.display_list = surf.display_list[:]
832 self._children = surf._children[:]
833
834@@ -136,7 +153,33 @@
835 if self._a is not None:
836 return self._a
837 else:
838- return self._parent.a
839+ if self._parent:
840+ return self._parent.a
841+ else:
842+ return 1
843+
844+ @property
845+ def rect_abs(self):
846+ if self._parent is None:
847+ return self.rect
848+ else:
849+ p_abs = self._parent.pos_abs
850+ p = (self.rect.x + p_abs[0], self.rect.y + p_abs[1])
851+ return Rect(p, self.rect.size)
852+
853+ @property
854+ def pos(self):
855+ return self.rect.topleft
856+ @pos.setter
857+ def pos(self, value):
858+ self.rect.topleft = value
859+ @property
860+ def pos_abs(self):
861+ if self._parent is None:
862+ return self.rect.topleft
863+ else:
864+ p_abs = self._parent.pos_abs
865+ return (self.rect.x + p_abs[0], self.rect.y + p_abs[1])
866
867 # --- Dummy methods. Ignore. ---
868
869@@ -152,17 +195,27 @@
870 to an OpenGLImage object in the same manner as pygame.Font.
871
872 """
873- def __init__(self, font, size):
874+ def __init__(self, font, size=16):
875+ self.rect = Rect(0,0,0,0)
876 self._children = []
877- self.font = FTGL.TextureFont(font)
878- self.font.FaceSize(16)
879- self.y_offset = self.font.line_height * .75
880+ self.matrix = Matrix()
881+ self.display_list = []
882+ if isinstance(font, OpenGLFont):
883+ self.font = font.font
884+ self.y_offset = font.y_offset
885+ self.size = font.size
886+ else:
887+ self.font = FTGL.TextureFont(font) # BufferFont
888+ self.font.FaceSize(size)
889+ self.y_offset = self.font.line_height * .75
890
891 def render(self, text, antialias, color, background=None):
892+ temp = OpenGLImage((self.font.Advance(text.encode()), self.font.line_height))
893 text = text.encode()
894 col = [c/255. for c in color]
895 dl = glGenLists(1)
896 self.size = (self.font.Advance(text), self.font.line_height)
897+ self.rect = Rect((0,0), self.size)
898 glNewList(dl, GL_COMPILE)
899 glPushMatrix()
900 # Flip text right way up
901@@ -173,16 +226,33 @@
902 self.font.Render(text)
903 glPopMatrix()
904 glEndList()
905- self.display_list = [(dl, col)]
906- return self
907+ temp.display_list = [(dl, col)]
908+ return temp
909+
910+ def get_linesize(self):
911+ """TODO"""
912+ return self.rect.h
913+
914+ def get_ascent(self):
915+ """TODO"""
916+ return self.rect.h-4
917+
918+ def get_descent(self):
919+ """TODO"""
920+ return -4
921+
922+ def metrics(self, text):
923+ """TODO"""
924+ return [(0,0,0,0,10) for c in text]
925
926 class Draw():
927 """
928 Class to emulate the pygame.draw module.
929- Functions should work in the same manner.
930+ Functions should work in the same manner, except where otherwise stated.
931
932 """
933 def rect(self, surf, col, rect, width=0):
934+ rect = Rect(rect)
935 col = [c/255. for c in col]
936 dl = glGenLists(1)
937 glNewList(dl, GL_COMPILE)
938@@ -220,6 +290,8 @@
939 for v in pointlist:
940 glVertex(v)
941 glEnd()
942+ else:
943+ raise NotImplementedError
944 glEndList()
945 surf.display_list.append((dl, col))
946
947@@ -235,10 +307,18 @@
948 glVertex(pos)
949 glEnd()
950 glDisable(GL_POINT_SMOOTH)
951- glPointSize()
952+ #glPointSize()
953+ else:
954+ raise NotImplementedError
955 glEndList()
956 surf.display_list.append((dl, col))
957
958+ def ellipse(self, surf, col, rect, width=0):
959+ raise NotImplementedError
960+
961+ def arc(self, surf, col, rect, start_angle, stop_angle, width=1):
962+ raise NotImplementedError
963+
964 def line(self, surf, col, start_pos, end_pos, width=1):
965 col = [c/255. for c in col]
966 dl = glGenLists(1)
967@@ -251,5 +331,14 @@
968 glEndList()
969 surf.display_list.append((dl, col))
970
971+ def lines(self, surf, col, closed, pointlist, width=1):
972+ raise NotImplementedError
973+
974+ def aaline(self, surf, col, startpos, endpos, blend=1):
975+ raise NotImplementedError
976+
977+ def aalines(self, surf, col, closed, pointlist, blend=1):
978+ raise NotImplementedError
979+
980 # Export Draw functions
981 draw = Draw()
982
983=== modified file 'sgc/widgets/radio_button.py'
984--- sgc/widgets/radio_button.py 2012-06-19 20:41:57 +0000
985+++ sgc/widgets/radio_button.py 2012-07-21 12:53:18 +0000
986@@ -73,8 +73,8 @@
987 draw.circle(self._images["image"], (255,255,255), pos, r)
988 draw.circle(self._images["over"], self._settings["col"], pos, r)
989 # Border circles
990- draw.circle(self._images["image"], (0,0,1), pos, r, 1)
991- draw.circle(self._images["over"], (0,0,1), pos, r, 1)
992+ draw.circle(self._images["image"], (0,0,1), pos, r)
993+ draw.circle(self._images["over"], (0,0,1), pos, r)
994
995 def _draw_active(self, draw, image):
996 # Central dot for 'active' state

Subscribers

People subscribed via source and target branches