]>
Commit | Line | Data |
---|---|---|
1 | # Name: params.py | |
2 | # Purpose: Classes for parameter introduction | |
3 | # Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be> | |
4 | # Created: 22.08.2001 | |
5 | ||
6 | from wxPython.wx import * | |
7 | from wxPython.xrc import * | |
8 | import string | |
9 | ||
10 | # Object which is currently processed | |
11 | currentXXX = None | |
12 | def SetCurrentXXX(xxx): | |
13 | global currentXXX | |
14 | currentXXX = xxx | |
15 | ||
16 | # Register objects in the view | |
17 | registered = {} | |
18 | def Register(param, obj): | |
19 | registered[param] = obj | |
20 | def GetRegistered(param): | |
21 | return registered[param] | |
22 | def ClearRegister(): | |
23 | registered.clear() | |
24 | ||
25 | genericStyles = ['wxSIMPLE_BORDER', 'wxSUNKEN_BORDER', 'wxRAISED_BORDER', | |
26 | 'wxTAB_TRAVERSAL', 'wxWANTS_CHARS', 'wxVSCROLL', 'wxHSCROLL'] | |
27 | ||
28 | class ParamBinaryOr(wxPanel): | |
29 | ID_TEXT_CTRL = wxNewId() | |
30 | ID_BUTTON_CHOICES = wxNewId() | |
31 | def __init__(self, parent, id, value, size, name, param): | |
32 | wxPanel.__init__(self, parent, id, name=name) | |
33 | self.SetBackgroundColour(panel.GetBackgroundColour()) | |
34 | Register(param, self) | |
35 | sizer = wxBoxSizer() | |
36 | self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, value, size=wxSize(200,-1)) | |
37 | sizer.Add(self.text, 0, wxRIGHT, 10) | |
38 | self.button = wxButton(self, self.ID_BUTTON_CHOICES, 'Edit...') | |
39 | sizer.Add(self.button) | |
40 | self.SetAutoLayout(true) | |
41 | self.SetSizer(sizer) | |
42 | sizer.Fit(self) | |
43 | EVT_BUTTON(self, self.ID_BUTTON_CHOICES, self.OnButtonChoices) | |
44 | EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
45 | def OnChange(self, evt): | |
46 | panel.SetModified(true) | |
47 | evt.Skip() | |
48 | def GetValue(self): | |
49 | return self.text.GetValue() | |
50 | def SetValue(self, value): | |
51 | self.text.SetValue(value) | |
52 | def OnButtonChoices(self, evt): | |
53 | dlg = wxDialog(self, -1, 'Choices', size=wxSize(250,300)) | |
54 | topSizer = wxBoxSizer(wxVERTICAL) | |
55 | listBox = wxCheckListBox(dlg, -1, choices=self.values) | |
56 | value = map(string.strip, string.split(self.text.GetValue(), '|')) | |
57 | if value == ['']: value = [] | |
58 | ignored = [] | |
59 | for i in value: | |
60 | try: | |
61 | listBox.Check(self.values.index(i)) | |
62 | except ValueError: | |
63 | # Try to find equal | |
64 | if self.equal.has_key(i): | |
65 | listBox.Check(self.values.index(self.equal[i])) | |
66 | else: | |
67 | print 'Unknown flag: %s: ignored.' % i | |
68 | ignored.append(i) | |
69 | topSizer.Add(listBox, 1, wxEXPAND) | |
70 | sizer = wxBoxSizer() | |
71 | buttonOk = wxButton(dlg, wxID_OK, 'OK') | |
72 | buttonOk.SetDefault() | |
73 | sizer.Add(buttonOk, 0, wxRIGHT, 10) | |
74 | sizer.Add(0, 0, 1) | |
75 | sizer.Add(wxButton(dlg, wxID_CANCEL, 'Cancel')) | |
76 | topSizer.Add(sizer, 0, wxALL | wxEXPAND, 10) | |
77 | dlg.SetAutoLayout(true) | |
78 | dlg.SetSizer(topSizer) | |
79 | dlg.Center() | |
80 | if dlg.ShowModal() != wxID_OK: return | |
81 | value = [] | |
82 | for i in range(listBox.Number()): | |
83 | if listBox.IsChecked(i): | |
84 | value.append(self.values[i]) | |
85 | # Add ignored flags | |
86 | value.extend(ignored) | |
87 | self.SetValue(reduce(lambda a,b: a+'|'+b, value)) | |
88 | panel.SetModified(true) | |
89 | ||
90 | class ParamFlag(ParamBinaryOr): | |
91 | values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL', | |
92 | 'wxEXPAND', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT', | |
93 | 'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL', | |
94 | 'wxALIGN_CENTRE_HORIZONTAL'] | |
95 | equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE', | |
96 | 'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL', | |
97 | 'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL'} | |
98 | def __init__(self, parent, id, value, size, name, param): | |
99 | ParamBinaryOr.__init__(self, parent, id, value, size, name, param) | |
100 | ||
101 | class ParamStyle(ParamBinaryOr): | |
102 | equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE'} | |
103 | def __init__(self, parent, id, value, size, name, param): | |
104 | self.values = currentXXX.styles + genericStyles | |
105 | ParamBinaryOr.__init__(self, parent, id, value, size, name, param) | |
106 | ||
107 | class ParamInt(wxPanel): | |
108 | ID_SPIN_CTRL = wxNewId() | |
109 | def __init__(self, parent, id, value, size, name, param): | |
110 | wxPanel.__init__(self, parent, id, name=name) | |
111 | sizer = wxBoxSizer() | |
112 | self.spin = wxSpinCtrl(self, self.ID_SPIN_CTRL, value, size=wxSize(50,-1)) | |
113 | self.SetBackgroundColour(panel.GetBackgroundColour()) | |
114 | sizer.Add(self.spin) | |
115 | self.SetAutoLayout(true) | |
116 | self.SetSizer(sizer) | |
117 | sizer.Fit(self) | |
118 | Register(param, self) | |
119 | EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange) | |
120 | def GetValue(self): | |
121 | return str(self.spin.GetValue()) | |
122 | def SetValue(self, value): | |
123 | if not value: value = 0 | |
124 | self.spin.SetValue(int(value)) | |
125 | def OnChange(self, evt): | |
126 | panel.SetModified(true) | |
127 | evt.Skip() | |
128 | ||
129 | class ParamText(wxTextCtrl): | |
130 | def __init__(self, parent, id, value, size, name, param): | |
131 | wxTextCtrl.__init__(self, parent, id, value, size=wxSize(200,-1), name=name) | |
132 | Register(param, self) | |
133 | EVT_TEXT(self, id, self.OnChange) | |
134 | def OnChange(self, evt): | |
135 | panel.SetModified(true) | |
136 | evt.Skip() | |
137 | ||
138 | class ParamAccel(wxTextCtrl): | |
139 | def __init__(self, parent, id, value, size, name, param): | |
140 | wxTextCtrl.__init__(self, parent, id, value, size=wxSize(50,-1), name=name) | |
141 | Register(param, self) | |
142 | EVT_TEXT(self, id, self.OnChange) | |
143 | def OnChange(self, evt): | |
144 | panel.SetModified(true) | |
145 | evt.Skip() | |
146 | ||
147 | class ParamPosSize(wxTextCtrl): | |
148 | def __init__(self, parent, id, value, size, name, param): | |
149 | wxTextCtrl.__init__(self, parent, id, value, size=wxSize(80,-1), name=name) | |
150 | Register(param, self) | |
151 | EVT_TEXT(self, id, self.OnChange) | |
152 | def OnChange(self, evt): | |
153 | panel.SetModified(true) | |
154 | evt.Skip() | |
155 | ||
156 | class ContentDialog(wxDialog): | |
157 | def __init__(self, parent, value): | |
158 | # Use another constructor | |
159 | w = frame.res.LoadDialog(parent, 'ID_DIALOG_CONTENT') | |
160 | self.this = w.this | |
161 | w.thisown = 0 | |
162 | self.thisown = 1 | |
163 | #frame.res.LoadOnDialog(self, parent, 'ID_DIALOG_CONTENT') | |
164 | self.Center() | |
165 | self.list = self.FindWindowByName('ID_LIST') | |
166 | # Set list items | |
167 | for v in value: | |
168 | self.list.Append(v) | |
169 | # !!! Bug in XRC or wxWin listbox select random items | |
170 | self.FindWindowByName('wxID_OK').SetFocus() | |
171 | # Callbacks | |
172 | self.ID_BUTTON_APPEND = XMLID('ID_BUTTON_APPEND') | |
173 | self.ID_BUTTON_REMOVE = XMLID('ID_BUTTON_REMOVE') | |
174 | self.ID_BUTTON_UP = XMLID('ID_BUTTON_UP') | |
175 | self.ID_BUTTON_DOWN = XMLID('ID_BUTTON_DOWN') | |
176 | EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp) | |
177 | EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown) | |
178 | EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend) | |
179 | EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove) | |
180 | EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI) | |
181 | EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI) | |
182 | EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI) | |
183 | def OnButtonUp(self, evt): | |
184 | i = self.list.GetSelection() | |
185 | str = self.list.GetString(i) | |
186 | self.list.Delete(i) | |
187 | self.list.InsertItems([str], i-1) | |
188 | self.list.SetSelection(i-1) | |
189 | def OnButtonDown(self, evt): | |
190 | i = self.list.GetSelection() | |
191 | str = self.list.GetString(i) | |
192 | self.list.Delete(i) | |
193 | self.list.InsertItems([str], i+1) | |
194 | self.list.SetSelection(i+1) | |
195 | def OnButtonAppend(self, evt): | |
196 | str = wxGetTextFromUser('Enter new item:', 'Append', '', self) | |
197 | self.list.Append(str) | |
198 | def OnButtonRemove(self, evt): | |
199 | self.list.Delete(self.list.GetSelection()) | |
200 | def OnUpdateUI(self, evt): | |
201 | if evt.GetId() == self.ID_BUTTON_REMOVE: | |
202 | evt.Enable(self.list.GetSelection() != -1) | |
203 | elif evt.GetId() == self.ID_BUTTON_UP: | |
204 | evt.Enable(self.list.GetSelection() > 0) | |
205 | elif evt.GetId() == self.ID_BUTTON_DOWN: | |
206 | evt.Enable(self.list.GetSelection() < self.list.Number() - 1) | |
207 | ||
208 | class ParamContent(wxPanel): | |
209 | ID_TEXT_CTRL = wxNewId() | |
210 | ID_BUTTON_EDIT = wxNewId() | |
211 | def __init__(self, parent, id, value, size, name, param): | |
212 | wxPanel.__init__(self, parent, id, name=name) | |
213 | self.SetBackgroundColour(panel.GetBackgroundColour()) | |
214 | Register(param, self) | |
215 | sizer = wxBoxSizer() | |
216 | self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, str(value), size=wxSize(200,-1)) | |
217 | sizer.Add(self.text, 0, wxRIGHT, 10) | |
218 | self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...') | |
219 | sizer.Add(self.button) | |
220 | self.SetAutoLayout(true) | |
221 | self.SetSizer(sizer) | |
222 | sizer.Fit(self) | |
223 | self.textModified = false | |
224 | EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit) | |
225 | EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
226 | def OnChange(self, evt): | |
227 | panel.SetModified(true) | |
228 | self.textModified = true | |
229 | evt.Skip() | |
230 | def GetValue(self): | |
231 | if self.textModified: # text has newer value | |
232 | return eval(self.text.GetValue()) | |
233 | return self.value | |
234 | def SetValue(self, value): | |
235 | self.value = value | |
236 | self.text.SetValue(str(value)) # update text ctrl | |
237 | def OnButtonEdit(self, evt): | |
238 | if self.textModified: # text has newer value | |
239 | self.value = eval(self.text.GetValue()) | |
240 | dlg = ContentDialog(self, self.value) | |
241 | if dlg.ShowModal() != wxID_OK: return | |
242 | value = [] | |
243 | for i in range(dlg.list.Number()): | |
244 | value.append(dlg.list.GetString(i)) | |
245 | # Add ignored flags | |
246 | self.SetValue(value) | |
247 | panel.SetModified(true) | |
248 | self.textModified = false | |
249 | ||
250 | # Boxless radiobox | |
251 | class RadioBox(wxPanel): | |
252 | ID_RADIO_CHOICE = wxNewId() # economize on IDs, use names | |
253 | def __init__(self, parent, id, choices, | |
254 | pos=wxDefaultPosition, size=wxDefaultSize, name='radiobox'): | |
255 | wxPanel.__init__(self, parent, id, pos, size, name=name) | |
256 | self.SetBackgroundColour(panel.GetBackgroundColour()) | |
257 | self.choices = choices | |
258 | topSizer = wxBoxSizer() | |
259 | for i in choices: | |
260 | topSizer.Add(wxRadioButton(self, self.ID_RADIO_CHOICE, i, name=i)) | |
261 | self.SetAutoLayout(true) | |
262 | self.SetSizer(topSizer) | |
263 | topSizer.Fit(self) | |
264 | EVT_RADIOBUTTON(self, self.ID_RADIO_CHOICE, self.OnRadioChoice) | |
265 | def SetStringSelection(self, value): | |
266 | self.value = None | |
267 | for i in self.choices: | |
268 | w = self.FindWindowByName(i) | |
269 | w.SetValue(i == value) | |
270 | self.value = value | |
271 | def OnRadioChoice(self, evt): | |
272 | if not self.value: # procedure call | |
273 | evt.Skip() | |
274 | return | |
275 | self.FindWindowByName(self.value).SetValue(false) | |
276 | self.value = evt.GetEventObject().GetName() | |
277 | panel.SetModified(true) | |
278 | def GetStringSelection(self): | |
279 | return self.value | |
280 | ||
281 | class ParamBool(RadioBox): | |
282 | values = {'yes': '1', 'no': '0'} | |
283 | seulav = {'1': 'yes', '0': 'no'} | |
284 | def __init__(self, parent, id, value, size, name, param): | |
285 | RadioBox.__init__(self, parent, id, choices = self.values.keys(), name=name) | |
286 | Register(param, self) | |
287 | self.SetValue(value) | |
288 | def GetValue(self): | |
289 | return self.values[self.GetStringSelection()] | |
290 | def SetValue(self, value): | |
291 | if not value: value = '1' | |
292 | self.SetStringSelection(self.seulav[value]) | |
293 | ||
294 | class ParamOrient(RadioBox): | |
295 | values = {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'} | |
296 | seulav = {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'} | |
297 | def __init__(self, parent, id, value, size, name, param): | |
298 | RadioBox.__init__(self, parent, id, choices = self.values.keys(), name=name) | |
299 | Register(param, self) | |
300 | self.SetValue(value) | |
301 | def GetValue(self): | |
302 | return self.values[self.GetStringSelection()] | |
303 | def SetValue(self, value): | |
304 | if not value: value = 'wxHORIZONTAL' | |
305 | self.SetStringSelection(self.seulav[value]) | |
306 | ||
307 | paramDict = { | |
308 | 'flag': ParamFlag, | |
309 | 'style': ParamStyle, | |
310 | 'pos': ParamPosSize, 'size': ParamPosSize, | |
311 | 'border': ParamInt, 'cols': ParamInt, 'rows': ParamInt, | |
312 | 'vgap': ParamInt, 'hgap': ParamInt, | |
313 | 'checkable': ParamBool, 'accel': ParamAccel, | |
314 | 'label': ParamText, 'title': ParamText, 'value': ParamText, | |
315 | 'content': ParamContent, 'selection': ParamInt, | |
316 | 'min': ParamInt, 'max': ParamInt, | |
317 | } |