Mercurial > fife-parpg
comparison engine/extensions/pychan/dialogs.py @ 205:54bfd1015b35
* PyChan event handling rework (part I)
** Unified listeners
** ...hopefully more robust attach/detach code.
* Added compat, layout and also the new autopsition feature.
* Documentation
* Minor style fixes in core.
author | phoku@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Sat, 14 Mar 2009 12:13:29 +0000 |
parents | |
children | 51cc05d862f2 |
comparison
equal
deleted
inserted
replaced
204:5816ab527da8 | 205:54bfd1015b35 |
---|---|
1 # coding: utf-8 | |
2 | |
3 from pychan import loadXML | |
4 import pychan.tools | |
5 import widgets | |
6 from internal import get_manager, screen_width, screen_height | |
7 from StringIO import StringIO | |
8 | |
9 OK,YES,NO,CANCEL = True,True,False,None | |
10 | |
11 def print_event(**kwargs): | |
12 print kwargs | |
13 | |
14 class XMLDialog(object): | |
15 def __init__(self, xml, ok_field = None, cancel_field = None,initial_data={},data={}): | |
16 self.gui = loadXML(xml) | |
17 self.ok_field = ok_field | |
18 self.cancel_field = cancel_field | |
19 self.initial_data= initial_data | |
20 self.data= data | |
21 self.max_size=None | |
22 self.min_size=None | |
23 self.gui.capture(print_event,"mouseEntered") | |
24 | |
25 def execute(self): | |
26 self.gui.distributeInitialData(self.initial_data) | |
27 self.gui.distributeData(self.data) | |
28 | |
29 screen_w, screen_h = screen_width(), screen_height() | |
30 if self.max_size is None: | |
31 self.max_size = screen_w/2, screen_h/3 | |
32 if self.min_size is None: | |
33 self.min_size = screen_w/2, screen_h/4 | |
34 self.gui.max_size = self.max_size | |
35 self.gui.min_size = self.min_size | |
36 | |
37 resultMap = {} | |
38 if self.gui.findChild(name="okButton"): | |
39 resultMap["okButton"] = OK | |
40 | |
41 if self.gui.findChild(name="cancelButton"): | |
42 resultMap["cancelButton"] = CANCEL | |
43 | |
44 if self.gui.findChild(name="yesButton"): | |
45 resultMap["noButton"] = NO | |
46 | |
47 if self.gui.findChild(name="yesButton"): | |
48 resultMap["yesButton"] = YES | |
49 | |
50 ok = self.gui.execute(resultMap) | |
51 if ok: | |
52 return self.getOkResult() | |
53 return self.getCancelResult() | |
54 | |
55 def getOkResult(self): | |
56 if self.ok_field: | |
57 return self.gui.collectData(self.ok_field) | |
58 return True | |
59 | |
60 def getCancelResult(self): | |
61 if self.cancel_field: | |
62 return self.gui.collectData(self.cancel_field) | |
63 return False | |
64 | |
65 MESSAGE_BOX_XML = """\ | |
66 <Window name="window" title="Message"> | |
67 <ScrollArea> | |
68 <Label wrap_text="1" text="$MESSAGE" name="message" vexpanding="1"/> | |
69 </ScrollArea> | |
70 <HBox> | |
71 <Spacer/><Button min_width="50" name="okButton" text="OK"/> | |
72 </HBox> | |
73 </Window> | |
74 """ | |
75 | |
76 YESNO_BOX_XML = """\ | |
77 <Window name="window" title="Question"> | |
78 <ScrollArea> | |
79 <Label wrap_text="1" text="$MESSAGE" name="message" vexpanding="1"/> | |
80 </ScrollArea> | |
81 <HBox> | |
82 <Spacer/> | |
83 <Button min_width="50" name="yesButton" text="Yes"/> | |
84 <Button min_width="50" name="noButton" text="No"/> | |
85 </HBox> | |
86 </Window> | |
87 """ | |
88 | |
89 YESNOCANCEL_BOX_XML = """\ | |
90 <Window name="window" title="Question"> | |
91 <ScrollArea> | |
92 <Label wrap_text="1" text="$MESSAGE" name="message" vexpanding="1"/> | |
93 </ScrollArea> | |
94 <HBox> | |
95 <Spacer/> | |
96 <Button min_width="50" name="yesButton" text="Yes"/> | |
97 <Button min_width="50" name="noButton" text="No"/> | |
98 <Button min_width="50" name="cancelButton" text="Cancel"/> | |
99 </HBox> | |
100 </Window> | |
101 """ | |
102 | |
103 SELECT_BOX_XML = """\ | |
104 <Window name="window" title="Select"> | |
105 <Label wrap_text="1" text="$MESSAGE" name="message"/> | |
106 <ScrollArea> | |
107 <ListBox name="selection"> | |
108 </ListBox> | |
109 </ScrollArea> | |
110 <HBox> | |
111 <Spacer/> | |
112 <Button min_width="50" name="okButton" text="Select"/> | |
113 <Button min_width="50" name="cancelButton" text="Cancel"/> | |
114 </HBox> | |
115 </Window> | |
116 """ | |
117 | |
118 EXCEPTION_CATCHER_XML="""\ | |
119 <Window name="window" title="An exception occurred - what now?"> | |
120 <VBox hexpanding="1"> | |
121 <Label wrap_text="1" max_width="400" text="$MESSAGE" name="message"/> | |
122 <ScrollArea> | |
123 <Label text="$MESSAGE" name="traceback"/> | |
124 </ScrollArea> | |
125 </VBox> | |
126 <HBox> | |
127 <Spacer/> | |
128 <Button name="yesButton" text="Retry"/> | |
129 <Button name="noButton" text="Ignore"/> | |
130 <Button name="cancelButton" text="Reraise"/> | |
131 </HBox> | |
132 </Window> | |
133 """ | |
134 | |
135 def _make_text(message): | |
136 if callable(message): | |
137 message = message() | |
138 if hasattr(message,"read"): | |
139 message = message.read() | |
140 return message | |
141 | |
142 def message(message="",caption="Message"): | |
143 text = _make_text(message) | |
144 dialog = XMLDialog(StringIO(MESSAGE_BOX_XML), | |
145 initial_data={'message':text,'window':caption}) | |
146 dialog.gui.findChild(name="message").max_width = screen_width()/2 - 50 | |
147 dialog.execute() | |
148 | |
149 def yesNo(message="",caption="Message"): | |
150 text = _make_text(message) | |
151 dialog = XMLDialog(StringIO(YESNO_BOX_XML), | |
152 initial_data={'message':text,'window':caption}) | |
153 dialog.gui.findChild(name="message").max_width = screen_width()/2 - 50 | |
154 return dialog.execute() | |
155 | |
156 def yesNoCancel(message="",caption="Message"): | |
157 text = _make_text(message) | |
158 dialog = XMLDialog(StringIO(YESNOCANCEL_BOX_XML), | |
159 initial_data={'message':text,'window':caption}) | |
160 dialog.gui.findChild(name="message").max_width = screen_width()/2 - 50 | |
161 return dialog.execute() | |
162 | |
163 def select(message="",options=[],caption="Message"): | |
164 text = _make_text(message) | |
165 dialog = XMLDialog(StringIO(SELECT_BOX_XML), | |
166 initial_data={'message':text,'window':caption}) | |
167 dialog.size = screen_width()/3, 2*screen_height()/3 | |
168 | |
169 dialog.gui.findChild(name="message").max_width = screen_width()/2 - 50 | |
170 listbox = dialog.gui.findChild(name="selection") | |
171 listbox.items = options | |
172 if dialog.execute(): | |
173 return listbox.selected_item | |
174 return None | |
175 | |
176 def trace(f): | |
177 import sys, traceback | |
178 def new_f(*args,**kwargs): | |
179 try: | |
180 return pychan.tools.applyOnlySuitable(f,*args,**kwargs) | |
181 | |
182 except Exception, e: | |
183 dialog = XMLDialog(StringIO(EXCEPTION_CATCHER_XML), | |
184 initial_data={'message':str(e)} | |
185 ) | |
186 tb = traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback) | |
187 dialog.gui.findChild(name="traceback").text = "".join(tb) | |
188 dialog.min_size = screen_width()/2,3*screen_height()/4 | |
189 dialog.max_size = screen_width()/2,3*screen_height()/4 | |
190 result = dialog.execute() | |
191 if result == YES: | |
192 return new_f(*args,**kwargs) | |
193 elif result == NO: | |
194 return | |
195 raise | |
196 return new_f | |
197 |