]>
Commit | Line | Data |
---|---|---|
09f3d4e6 RD |
1 | # Name: params.py |
2 | # Purpose: Classes for parameter introduction | |
3 | # Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be> | |
4 | # Created: 22.08.2001 | |
a40b5e84 | 5 | # RCS-ID: $Id$ |
09f3d4e6 RD |
6 | |
7 | from wxPython.wx import * | |
8 | from wxPython.xrc import * | |
9 | import string | |
32ce09e2 | 10 | import os.path |
09f3d4e6 RD |
11 | |
12 | # Object which is currently processed | |
13 | currentXXX = None | |
14 | def SetCurrentXXX(xxx): | |
15 | global currentXXX | |
16 | currentXXX = xxx | |
17 | ||
32ce09e2 RD |
18 | genericStyles = ['wxSIMPLE_BORDER', 'wxDOUBLE_BORDER', |
19 | 'wxSUNKEN_BORDER', 'wxRAISED_BORDER', | |
20 | 'wxSTATIC_BORDER', 'wxNO_BORDER', | |
21 | 'wxTRANSPARENT_WINDOW', 'wxWANTS_CHARS', | |
22 | 'wxNO_FULL_REPAINT_ON_RESIZE'] | |
09f3d4e6 | 23 | |
a40b5e84 RD |
24 | # Class that can properly disable children |
25 | class PPanel(wxPanel): | |
f0c20d94 RD |
26 | def __init__(self, parent, name): |
27 | wxPanel.__init__(self, parent, -1, name=name) | |
32ce09e2 | 28 | self.modified = self.freeze = false |
a40b5e84 | 29 | def Enable(self, value): |
32ce09e2 | 30 | # Something strange is going on with enable so we make sure... |
a40b5e84 RD |
31 | for w in self.GetChildren(): |
32 | w.Enable(value) | |
32ce09e2 RD |
33 | wxPanel.Enable(self, value) |
34 | def SetModified(self): | |
35 | self.modified = true | |
92631ff2 | 36 | panel.SetModified(true) |
a40b5e84 RD |
37 | |
38 | class ParamBinaryOr(PPanel): | |
f0c20d94 RD |
39 | def __init__(self, parent, name): |
40 | PPanel.__init__(self, parent, name) | |
a40b5e84 RD |
41 | self.ID_TEXT_CTRL = wxNewId() |
42 | self.ID_BUTTON_CHOICES = wxNewId() | |
09f3d4e6 | 43 | self.SetBackgroundColour(panel.GetBackgroundColour()) |
09f3d4e6 | 44 | sizer = wxBoxSizer() |
32ce09e2 RD |
45 | self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1)) |
46 | sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 10) | |
09f3d4e6 | 47 | self.button = wxButton(self, self.ID_BUTTON_CHOICES, 'Edit...') |
32ce09e2 | 48 | sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL) |
09f3d4e6 RD |
49 | self.SetAutoLayout(true) |
50 | self.SetSizer(sizer) | |
51 | sizer.Fit(self) | |
52 | EVT_BUTTON(self, self.ID_BUTTON_CHOICES, self.OnButtonChoices) | |
53 | EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
54 | def OnChange(self, evt): | |
32ce09e2 RD |
55 | if self.freeze: return |
56 | self.SetModified() | |
09f3d4e6 RD |
57 | evt.Skip() |
58 | def GetValue(self): | |
59 | return self.text.GetValue() | |
60 | def SetValue(self, value): | |
32ce09e2 | 61 | self.freeze = true |
09f3d4e6 | 62 | self.text.SetValue(value) |
32ce09e2 | 63 | self.freeze = false |
09f3d4e6 | 64 | def OnButtonChoices(self, evt): |
a40b5e84 | 65 | dlg = wxDialog(self, -1, 'Choices') |
09f3d4e6 | 66 | topSizer = wxBoxSizer(wxVERTICAL) |
a40b5e84 | 67 | listBox = wxCheckListBox(dlg, -1, choices=self.values, size=(250,200)) |
09f3d4e6 RD |
68 | value = map(string.strip, string.split(self.text.GetValue(), '|')) |
69 | if value == ['']: value = [] | |
70 | ignored = [] | |
71 | for i in value: | |
72 | try: | |
73 | listBox.Check(self.values.index(i)) | |
74 | except ValueError: | |
75 | # Try to find equal | |
76 | if self.equal.has_key(i): | |
77 | listBox.Check(self.values.index(self.equal[i])) | |
78 | else: | |
32ce09e2 | 79 | print 'WARNING: unknown flag: %s: ignored.' % i |
09f3d4e6 RD |
80 | ignored.append(i) |
81 | topSizer.Add(listBox, 1, wxEXPAND) | |
82 | sizer = wxBoxSizer() | |
83 | buttonOk = wxButton(dlg, wxID_OK, 'OK') | |
84 | buttonOk.SetDefault() | |
85 | sizer.Add(buttonOk, 0, wxRIGHT, 10) | |
86 | sizer.Add(0, 0, 1) | |
87 | sizer.Add(wxButton(dlg, wxID_CANCEL, 'Cancel')) | |
88 | topSizer.Add(sizer, 0, wxALL | wxEXPAND, 10) | |
89 | dlg.SetAutoLayout(true) | |
90 | dlg.SetSizer(topSizer) | |
a40b5e84 | 91 | topSizer.Fit(dlg) |
09f3d4e6 | 92 | dlg.Center() |
92631ff2 | 93 | if dlg.ShowModal() == wxID_OK: |
32ce09e2 RD |
94 | value = [] |
95 | for i in range(listBox.Number()): | |
96 | if listBox.IsChecked(i): | |
97 | value.append(self.values[i]) | |
98 | # Add ignored flags | |
99 | value.extend(ignored) | |
f0c20d94 RD |
100 | if value: |
101 | self.SetValue(reduce(lambda a,b: a+'|'+b, value)) | |
102 | else: | |
103 | self.SetValue('') | |
32ce09e2 RD |
104 | self.SetModified() |
105 | dlg.Destroy() | |
09f3d4e6 RD |
106 | |
107 | class ParamFlag(ParamBinaryOr): | |
108 | values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL', | |
109 | 'wxEXPAND', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT', | |
110 | 'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL', | |
111 | 'wxALIGN_CENTRE_HORIZONTAL'] | |
112 | equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE', | |
113 | 'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL', | |
114 | 'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL'} | |
f0c20d94 RD |
115 | def __init__(self, parent, name): |
116 | ParamBinaryOr.__init__(self, parent, name) | |
09f3d4e6 RD |
117 | |
118 | class ParamStyle(ParamBinaryOr): | |
119 | equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE'} | |
f0c20d94 | 120 | def __init__(self, parent, name): |
a40b5e84 | 121 | self.values = currentXXX.winStyles + genericStyles |
f0c20d94 | 122 | ParamBinaryOr.__init__(self, parent, name) |
32ce09e2 RD |
123 | |
124 | class ParamNonGenericStyle(ParamBinaryOr): | |
f0c20d94 | 125 | def __init__(self, parent, name): |
32ce09e2 | 126 | self.values = currentXXX.winStyles |
f0c20d94 | 127 | ParamBinaryOr.__init__(self, parent, name) |
09f3d4e6 | 128 | |
a40b5e84 | 129 | class ParamExStyle(ParamBinaryOr): |
f0c20d94 | 130 | def __init__(self, parent, name): |
a40b5e84 RD |
131 | if currentXXX: |
132 | self.values = currentXXX.exStyles # constant at the moment | |
133 | else: | |
134 | self.values = [] | |
f0c20d94 | 135 | ParamBinaryOr.__init__(self, parent, name) |
a40b5e84 RD |
136 | |
137 | class ParamColour(PPanel): | |
f0c20d94 RD |
138 | def __init__(self, parent, name): |
139 | PPanel.__init__(self, parent, name) | |
a40b5e84 RD |
140 | self.ID_TEXT_CTRL = wxNewId() |
141 | self.ID_BUTTON = wxNewId() | |
142 | self.SetBackgroundColour(panel.GetBackgroundColour()) | |
143 | sizer = wxBoxSizer() | |
32ce09e2 RD |
144 | self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(60,-1)) |
145 | sizer.Add(self.text, 0, wxRIGHT, 10) | |
a40b5e84 RD |
146 | self.button = wxPanel(self, self.ID_BUTTON, wxDefaultPosition, wxSize(40, -1)) |
147 | sizer.Add(self.button, 0, wxGROW) | |
148 | self.SetAutoLayout(true) | |
149 | self.SetSizer(sizer) | |
150 | sizer.Fit(self) | |
151 | self.textModified = false | |
a40b5e84 RD |
152 | EVT_PAINT(self.button, self.OnPaintButton) |
153 | EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
154 | EVT_LEFT_DOWN(self.button, self.OnLeftDown) | |
155 | def GetValue(self): | |
156 | return self.value | |
157 | def SetValue(self, value): | |
32ce09e2 | 158 | self.freeze = true |
a40b5e84 RD |
159 | if not value: value = '#FFFFFF' |
160 | self.value = value | |
161 | self.text.SetValue(str(value)) # update text ctrl | |
32ce09e2 RD |
162 | colour = wxColour(int(value[1:3], 16), int(value[3:5], 16), int(value[5:7], 16)) |
163 | self.button.SetBackgroundColour(colour) | |
a40b5e84 | 164 | self.button.Refresh() |
32ce09e2 | 165 | self.freeze = false |
a40b5e84 | 166 | def OnChange(self, evt): |
32ce09e2 RD |
167 | if self.freeze: return |
168 | self.SetModified() | |
a40b5e84 RD |
169 | self.textModified = true |
170 | evt.Skip() | |
171 | def OnPaintButton(self, evt): | |
172 | dc = wxPaintDC(self.button) | |
173 | dc.SetBrush(wxTRANSPARENT_BRUSH) | |
32ce09e2 | 174 | if self.IsEnabled(): dc.SetPen(wxBLACK_PEN) |
a40b5e84 RD |
175 | else: dc.SetPen(wxGREY_PEN) |
176 | size = self.button.GetSize() | |
177 | dc.DrawRectangle(0, 0, size.x, size.y) | |
178 | def OnLeftDown(self, evt): | |
179 | dlg = wxColourDialog(self) | |
180 | if dlg.ShowModal() == wxID_OK: | |
181 | self.SetValue('#%02X%02X%02X' % dlg.GetColourData().GetColour().Get()) | |
32ce09e2 RD |
182 | self.SetModified() |
183 | self.textModified = false | |
184 | dlg.Destroy() | |
a40b5e84 RD |
185 | |
186 | ################################################################################ | |
187 | ||
188 | # Mapping from wx constants ro XML strings | |
189 | fontFamiliesWx2Xml = {wxDEFAULT: 'default', wxDECORATIVE: 'decorative', | |
190 | wxROMAN: 'roman', wxSCRIPT: 'script', wxSWISS: 'swiss', | |
191 | wxMODERN: 'modern'} | |
192 | fontStylesWx2Xml = {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'} | |
193 | fontWeightsWx2Xml = {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'} | |
194 | def ReverseMap(m): | |
195 | rm = {} | |
196 | for k,v in m.items(): rm[v] = k | |
197 | return rm | |
198 | fontFamiliesXml2wx = ReverseMap(fontFamiliesWx2Xml) | |
199 | fontStylesXml2wx = ReverseMap(fontStylesWx2Xml) | |
200 | fontWeightsXml2wx = ReverseMap(fontWeightsWx2Xml) | |
201 | ||
202 | class ParamFont(PPanel): | |
f0c20d94 RD |
203 | def __init__(self, parent, name): |
204 | PPanel.__init__(self, parent, name) | |
a40b5e84 RD |
205 | self.ID_TEXT_CTRL = wxNewId() |
206 | self.ID_BUTTON_SELECT = wxNewId() | |
207 | self.SetBackgroundColour(panel.GetBackgroundColour()) | |
208 | sizer = wxBoxSizer() | |
32ce09e2 RD |
209 | self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1)) |
210 | sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 10) | |
a40b5e84 | 211 | self.button = wxButton(self, self.ID_BUTTON_SELECT, 'Select...') |
32ce09e2 | 212 | sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL) |
a40b5e84 RD |
213 | self.SetAutoLayout(true) |
214 | self.SetSizer(sizer) | |
215 | sizer.Fit(self) | |
216 | self.textModified = false | |
217 | EVT_BUTTON(self, self.ID_BUTTON_SELECT, self.OnButtonSelect) | |
218 | EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
219 | def OnChange(self, evt): | |
32ce09e2 RD |
220 | if self.freeze: return |
221 | self.SetModified() | |
a40b5e84 RD |
222 | self.textModified = true |
223 | evt.Skip() | |
f0c20d94 RD |
224 | def _defaultValue(self): |
225 | return ['12', 'default', 'normal', 'normal', '0', '', ''] | |
a40b5e84 RD |
226 | def GetValue(self): |
227 | if self.textModified: # text has newer value | |
f0c20d94 RD |
228 | try: |
229 | return eval(self.text.GetValue()) | |
230 | except SyntaxError: | |
231 | wxLogError('Syntax error in parameter value: ' + self.GetName()) | |
232 | return self._defaultValue() | |
a40b5e84 RD |
233 | return self.value |
234 | def SetValue(self, value): | |
32ce09e2 | 235 | self.freeze = true # disable other handlers |
f0c20d94 | 236 | if not value: value = self._defaultValue() |
a40b5e84 RD |
237 | self.value = value |
238 | self.text.SetValue(str(value)) # update text ctrl | |
32ce09e2 | 239 | self.freeze = false |
a40b5e84 RD |
240 | def OnButtonSelect(self, evt): |
241 | if self.textModified: # text has newer value | |
f0c20d94 RD |
242 | try: |
243 | self.value = eval(self.text.GetValue()) | |
244 | except SyntaxError: | |
245 | wxLogError('Syntax error in parameter value: ' + self.GetName()) | |
246 | self.value = self._defaultValue() | |
a40b5e84 | 247 | # Make initial font |
f0c20d94 RD |
248 | # Default values |
249 | size = 12 | |
250 | family = wxDEFAULT | |
251 | style = weight = wxNORMAL | |
252 | underlined = 0 | |
253 | face = '' | |
a40b5e84 | 254 | enc = wxFONTENCODING_DEFAULT |
f0c20d94 RD |
255 | # Fall back to default if exceptions |
256 | error = false | |
257 | try: | |
258 | try: size = int(self.value[0]) | |
259 | except ValueError: error = true | |
260 | try: family = fontFamiliesXml2wx[self.value[1]] | |
261 | except KeyError: error = true | |
262 | try: style = fontStylesXml2wx[self.value[2]] | |
263 | except KeyError: error = true | |
264 | try: weight = fontWeightsXml2wx[self.value[3]] | |
265 | except KeyError: error = true | |
266 | try: underlined = int(self.value[4]) | |
267 | except ValueError: error = true | |
268 | face = self.value[5] | |
269 | mapper = wxFontMapper() | |
270 | if not self.value[6]: enc = mapper.CharsetToEncoding(self.value[6]) | |
271 | except IndexError: | |
272 | error = true | |
273 | if error: wxLogError('Invalid font specification') | |
a40b5e84 RD |
274 | if enc == wxFONTENCODING_DEFAULT: enc = wxFONTENCODING_SYSTEM |
275 | font = wxFont(size, family, style, weight, underlined, face, enc) | |
276 | data = wxFontData() | |
277 | data.SetInitialFont(font) | |
278 | dlg = wxFontDialog(self, data) | |
32ce09e2 RD |
279 | if dlg.ShowModal() == wxID_OK: |
280 | font = dlg.GetFontData().GetChosenFont() | |
f0c20d94 RD |
281 | value = [str(font.GetPointSize()), |
282 | fontFamiliesWx2Xml.get(font.GetFamily(), "default"), | |
283 | fontStylesWx2Xml.get(font.GetStyle(), "normal"), | |
284 | fontWeightsWx2Xml.get(font.GetWeight(), "normal"), | |
285 | str(font.GetUnderlined()), | |
286 | font.GetFaceName(), | |
287 | wxFontMapper_GetEncodingName(font.GetEncoding()) | |
288 | ] | |
32ce09e2 RD |
289 | # Add ignored flags |
290 | self.SetValue(value) | |
291 | self.SetModified() | |
292 | self.textModified = false | |
293 | dlg.Destroy() | |
a40b5e84 RD |
294 | |
295 | ################################################################################ | |
296 | ||
297 | class ParamInt(PPanel): | |
f0c20d94 RD |
298 | def __init__(self, parent, name): |
299 | PPanel.__init__(self, parent, name) | |
a40b5e84 | 300 | self.ID_SPIN_CTRL = wxNewId() |
09f3d4e6 | 301 | sizer = wxBoxSizer() |
32ce09e2 | 302 | self.spin = wxSpinCtrl(self, self.ID_SPIN_CTRL, size=wxSize(50,-1)) |
09f3d4e6 RD |
303 | self.SetBackgroundColour(panel.GetBackgroundColour()) |
304 | sizer.Add(self.spin) | |
305 | self.SetAutoLayout(true) | |
306 | self.SetSizer(sizer) | |
307 | sizer.Fit(self) | |
09f3d4e6 RD |
308 | EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange) |
309 | def GetValue(self): | |
310 | return str(self.spin.GetValue()) | |
311 | def SetValue(self, value): | |
32ce09e2 | 312 | self.freeze = true |
09f3d4e6 RD |
313 | if not value: value = 0 |
314 | self.spin.SetValue(int(value)) | |
32ce09e2 | 315 | self.freeze = false |
09f3d4e6 | 316 | def OnChange(self, evt): |
32ce09e2 RD |
317 | if self.freeze: return |
318 | self.SetModified() | |
09f3d4e6 RD |
319 | evt.Skip() |
320 | ||
32ce09e2 | 321 | class ParamText(PPanel): |
f0c20d94 RD |
322 | def __init__(self, parent, name, textWidth=200): |
323 | PPanel.__init__(self, parent, name) | |
32ce09e2 RD |
324 | self.ID_TEXT_CTRL = wxNewId() |
325 | # We use sizer even here to have the same size of text control | |
326 | sizer = wxBoxSizer() | |
327 | self.SetBackgroundColour(panel.GetBackgroundColour()) | |
328 | self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(textWidth,-1)) | |
329 | sizer.Add(self.text, 0, wxALIGN_CENTER_VERTICAL) | |
330 | self.SetAutoLayout(true) | |
331 | self.SetSizer(sizer) | |
332 | sizer.Fit(self) | |
333 | EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
334 | def GetValue(self): | |
335 | return self.text.GetValue() | |
336 | def SetValue(self, value): | |
337 | self.freeze = true # disable other handlers | |
338 | self.text.SetValue(value) | |
339 | self.freeze = false # disable other handlers | |
09f3d4e6 | 340 | def OnChange(self, evt): |
32ce09e2 RD |
341 | if self.freeze: return |
342 | self.SetModified() | |
09f3d4e6 RD |
343 | evt.Skip() |
344 | ||
32ce09e2 | 345 | class ParamAccel(ParamText): |
f0c20d94 RD |
346 | def __init__(self, parent, name): |
347 | ParamText.__init__(self, parent, name, 50) | |
09f3d4e6 | 348 | |
32ce09e2 | 349 | class ParamPosSize(ParamText): |
f0c20d94 RD |
350 | def __init__(self, parent, name): |
351 | ParamText.__init__(self, parent, name, 80) | |
09f3d4e6 | 352 | |
f0c20d94 | 353 | class ContentDialog(wxDialogPtr): |
09f3d4e6 | 354 | def __init__(self, parent, value): |
f0c20d94 | 355 | # Is this normal??? |
09f3d4e6 | 356 | w = frame.res.LoadDialog(parent, 'ID_DIALOG_CONTENT') |
f0c20d94 | 357 | wxDialogPtr.__init__(self, w.this) |
09f3d4e6 | 358 | self.thisown = 1 |
09f3d4e6 RD |
359 | self.Center() |
360 | self.list = self.FindWindowByName('ID_LIST') | |
361 | # Set list items | |
362 | for v in value: | |
363 | self.list.Append(v) | |
a40b5e84 | 364 | self.SetAutoLayout(true) |
a40b5e84 | 365 | self.GetSizer().Fit(self) |
09f3d4e6 RD |
366 | # Callbacks |
367 | self.ID_BUTTON_APPEND = XMLID('ID_BUTTON_APPEND') | |
368 | self.ID_BUTTON_REMOVE = XMLID('ID_BUTTON_REMOVE') | |
369 | self.ID_BUTTON_UP = XMLID('ID_BUTTON_UP') | |
370 | self.ID_BUTTON_DOWN = XMLID('ID_BUTTON_DOWN') | |
371 | EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp) | |
372 | EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown) | |
373 | EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend) | |
374 | EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove) | |
375 | EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI) | |
376 | EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI) | |
377 | EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI) | |
378 | def OnButtonUp(self, evt): | |
379 | i = self.list.GetSelection() | |
380 | str = self.list.GetString(i) | |
381 | self.list.Delete(i) | |
382 | self.list.InsertItems([str], i-1) | |
383 | self.list.SetSelection(i-1) | |
384 | def OnButtonDown(self, evt): | |
385 | i = self.list.GetSelection() | |
386 | str = self.list.GetString(i) | |
387 | self.list.Delete(i) | |
388 | self.list.InsertItems([str], i+1) | |
389 | self.list.SetSelection(i+1) | |
390 | def OnButtonAppend(self, evt): | |
391 | str = wxGetTextFromUser('Enter new item:', 'Append', '', self) | |
392 | self.list.Append(str) | |
393 | def OnButtonRemove(self, evt): | |
394 | self.list.Delete(self.list.GetSelection()) | |
395 | def OnUpdateUI(self, evt): | |
396 | if evt.GetId() == self.ID_BUTTON_REMOVE: | |
397 | evt.Enable(self.list.GetSelection() != -1) | |
398 | elif evt.GetId() == self.ID_BUTTON_UP: | |
399 | evt.Enable(self.list.GetSelection() > 0) | |
400 | elif evt.GetId() == self.ID_BUTTON_DOWN: | |
a40b5e84 RD |
401 | evt.Enable(self.list.GetSelection() != -1 and \ |
402 | self.list.GetSelection() < self.list.Number() - 1) | |
09f3d4e6 | 403 | |
f0c20d94 RD |
404 | class ContentCheckListDialog(wxDialogPtr): |
405 | def __init__(self, parent, value): | |
406 | # Is this normal??? | |
407 | w = frame.res.LoadDialog(parent, 'ID_DIALOG_CONTENT_CHECK_LIST') | |
408 | wxDialogPtr.__init__(self, w.this) | |
409 | self.thisown = 1 | |
410 | self.Center() | |
411 | self.list = self.FindWindowByName('ID_CHECK_LIST') | |
412 | # Set list items | |
413 | i = 0 | |
414 | for v,ch in value: | |
415 | self.list.Append(v) | |
416 | self.list.Check(i, ch) | |
417 | i += 1 | |
418 | self.SetAutoLayout(true) | |
419 | self.GetSizer().Fit(self) | |
420 | # Callbacks | |
421 | self.ID_BUTTON_APPEND = XMLID('ID_BUTTON_APPEND') | |
422 | self.ID_BUTTON_REMOVE = XMLID('ID_BUTTON_REMOVE') | |
423 | self.ID_BUTTON_UP = XMLID('ID_BUTTON_UP') | |
424 | self.ID_BUTTON_DOWN = XMLID('ID_BUTTON_DOWN') | |
425 | EVT_CHECKLISTBOX(self, self.list.GetId(), self.OnCheck) | |
426 | EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp) | |
427 | EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown) | |
428 | EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend) | |
429 | EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove) | |
430 | EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI) | |
431 | EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI) | |
432 | EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI) | |
433 | def OnCheck(self, evt): | |
434 | # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking | |
435 | self.list.Deselect(evt.GetSelection()) | |
436 | def OnButtonUp(self, evt): | |
437 | i = self.list.GetSelection() | |
438 | str, ch = self.list.GetString(i), self.list.IsChecked(i) | |
439 | self.list.Delete(i) | |
440 | self.list.InsertItems([str], i-1) | |
441 | self.list.Check(i-1, ch) | |
442 | self.list.SetSelection(i-1) | |
443 | def OnButtonDown(self, evt): | |
444 | i = self.list.GetSelection() | |
445 | str, ch = self.list.GetString(i), self.list.IsChecked(i) | |
446 | self.list.Delete(i) | |
447 | self.list.InsertItems([str], i+1) | |
448 | self.list.Check(i+1, ch) | |
449 | self.list.SetSelection(i+1) | |
450 | def OnButtonAppend(self, evt): | |
451 | str = wxGetTextFromUser('Enter new item:', 'Append', '', self) | |
452 | self.list.Append(str) | |
453 | def OnButtonRemove(self, evt): | |
454 | self.list.Delete(self.list.GetSelection()) | |
455 | def OnUpdateUI(self, evt): | |
456 | if evt.GetId() == self.ID_BUTTON_REMOVE: | |
457 | evt.Enable(self.list.GetSelection() != -1) | |
458 | elif evt.GetId() == self.ID_BUTTON_UP: | |
459 | evt.Enable(self.list.GetSelection() > 0) | |
460 | elif evt.GetId() == self.ID_BUTTON_DOWN: | |
461 | evt.Enable(self.list.GetSelection() != -1 and \ | |
462 | self.list.GetSelection() < self.list.Number() - 1) | |
463 | ||
a40b5e84 | 464 | class ParamContent(PPanel): |
f0c20d94 RD |
465 | def __init__(self, parent, name): |
466 | PPanel.__init__(self, parent, name) | |
a40b5e84 RD |
467 | self.ID_TEXT_CTRL = wxNewId() |
468 | self.ID_BUTTON_EDIT = wxNewId() | |
09f3d4e6 | 469 | self.SetBackgroundColour(panel.GetBackgroundColour()) |
09f3d4e6 | 470 | sizer = wxBoxSizer() |
32ce09e2 RD |
471 | self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1)) |
472 | sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 10) | |
09f3d4e6 | 473 | self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...') |
32ce09e2 | 474 | sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL) |
09f3d4e6 RD |
475 | self.SetAutoLayout(true) |
476 | self.SetSizer(sizer) | |
477 | sizer.Fit(self) | |
478 | self.textModified = false | |
479 | EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit) | |
480 | EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
481 | def OnChange(self, evt): | |
92631ff2 | 482 | if self.freeze: return |
32ce09e2 | 483 | self.SetModified() |
09f3d4e6 RD |
484 | self.textModified = true |
485 | evt.Skip() | |
486 | def GetValue(self): | |
487 | if self.textModified: # text has newer value | |
f0c20d94 RD |
488 | try: |
489 | return eval(self.text.GetValue()) | |
490 | except SyntaxError: | |
491 | wxLogError('Syntax error in parameter value: ' + self.GetName()) | |
492 | return [] | |
09f3d4e6 RD |
493 | return self.value |
494 | def SetValue(self, value): | |
32ce09e2 | 495 | self.freeze = true |
09f3d4e6 RD |
496 | self.value = value |
497 | self.text.SetValue(str(value)) # update text ctrl | |
32ce09e2 | 498 | self.freeze = false |
09f3d4e6 RD |
499 | def OnButtonEdit(self, evt): |
500 | if self.textModified: # text has newer value | |
f0c20d94 RD |
501 | try: |
502 | self.value = eval(self.text.GetValue()) | |
503 | except SyntaxError: | |
504 | wxLogError('Syntax error in parameter value: ' + self.GetName()) | |
505 | self.value = [] | |
09f3d4e6 | 506 | dlg = ContentDialog(self, self.value) |
32ce09e2 RD |
507 | if dlg.ShowModal() == wxID_OK: |
508 | value = [] | |
509 | for i in range(dlg.list.Number()): | |
510 | value.append(dlg.list.GetString(i)) | |
511 | # Add ignored flags | |
512 | self.SetValue(value) | |
513 | self.SetModified() | |
514 | self.textModified = false | |
515 | dlg.Destroy() | |
09f3d4e6 | 516 | |
f0c20d94 RD |
517 | # CheckList content |
518 | class ParamContentCheckList(PPanel): | |
519 | def __init__(self, parent, name): | |
520 | PPanel.__init__(self, parent, name) | |
521 | self.ID_TEXT_CTRL = wxNewId() | |
522 | self.ID_BUTTON_EDIT = wxNewId() | |
523 | self.SetBackgroundColour(panel.GetBackgroundColour()) | |
524 | sizer = wxBoxSizer() | |
525 | self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1)) | |
526 | sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 10) | |
527 | self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...') | |
528 | sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL) | |
529 | self.SetAutoLayout(true) | |
530 | self.SetSizer(sizer) | |
531 | sizer.Fit(self) | |
532 | self.textModified = false | |
533 | EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit) | |
534 | EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
535 | def OnChange(self, evt): | |
536 | if self.freeze: return | |
537 | self.SetModified() | |
538 | self.textModified = true | |
539 | evt.Skip() | |
540 | def GetValue(self): | |
541 | if self.textModified: # text has newer value | |
542 | try: | |
543 | return eval(self.text.GetValue()) | |
544 | except SyntaxError: | |
545 | wxLogError('Syntax error in parameter value: ' + self.GetName()) | |
546 | return [] | |
547 | return self.value | |
548 | def SetValue(self, value): | |
549 | self.freeze = true | |
550 | self.value = value | |
551 | self.text.SetValue(str(value)) # update text ctrl | |
552 | self.freeze = false | |
553 | def OnButtonEdit(self, evt): | |
554 | if self.textModified: # text has newer value | |
555 | try: | |
556 | self.value = eval(self.text.GetValue()) | |
557 | except SyntaxError: | |
558 | wxLogError('Syntax error in parameter value: ' + self.GetName()) | |
559 | self.value = [] | |
560 | dlg = ContentCheckListDialog(self, self.value) | |
561 | if dlg.ShowModal() == wxID_OK: | |
562 | value = [] | |
563 | for i in range(dlg.list.Number()): | |
564 | value.append((dlg.list.GetString(i), dlg.list.IsChecked(i))) | |
565 | # Add ignored flags | |
566 | self.SetValue(value) | |
567 | self.SetModified() | |
568 | self.textModified = false | |
569 | dlg.Destroy() | |
570 | ||
92631ff2 | 571 | # Boxless radiobox |
a40b5e84 | 572 | class RadioBox(PPanel): |
09f3d4e6 | 573 | def __init__(self, parent, id, choices, |
f0c20d94 RD |
574 | pos=wxDefaultPosition, name='radiobox'): |
575 | PPanel.__init__(self, parent, name) | |
09f3d4e6 RD |
576 | self.SetBackgroundColour(panel.GetBackgroundColour()) |
577 | self.choices = choices | |
578 | topSizer = wxBoxSizer() | |
579 | for i in choices: | |
32ce09e2 RD |
580 | button = wxRadioButton(self, -1, i, name=i) |
581 | topSizer.Add(button) | |
582 | EVT_RADIOBUTTON(self, button.GetId(), self.OnRadioChoice) | |
09f3d4e6 RD |
583 | self.SetAutoLayout(true) |
584 | self.SetSizer(topSizer) | |
585 | topSizer.Fit(self) | |
09f3d4e6 | 586 | def SetStringSelection(self, value): |
32ce09e2 | 587 | self.freeze = true |
09f3d4e6 | 588 | for i in self.choices: |
32ce09e2 | 589 | self.FindWindowByName(i).SetValue(i == value) |
09f3d4e6 | 590 | self.value = value |
32ce09e2 | 591 | self.freeze = false |
09f3d4e6 | 592 | def OnRadioChoice(self, evt): |
32ce09e2 RD |
593 | if self.freeze: return |
594 | if evt.GetSelection(): | |
595 | self.value = evt.GetEventObject().GetName() | |
596 | self.SetModified() | |
09f3d4e6 RD |
597 | def GetStringSelection(self): |
598 | return self.value | |
599 | ||
600 | class ParamBool(RadioBox): | |
601 | values = {'yes': '1', 'no': '0'} | |
602 | seulav = {'1': 'yes', '0': 'no'} | |
f0c20d94 RD |
603 | def __init__(self, parent, name): |
604 | RadioBox.__init__(self, parent, -1, choices = self.values.keys(), name=name) | |
09f3d4e6 RD |
605 | def GetValue(self): |
606 | return self.values[self.GetStringSelection()] | |
607 | def SetValue(self, value): | |
608 | if not value: value = '1' | |
609 | self.SetStringSelection(self.seulav[value]) | |
610 | ||
611 | class ParamOrient(RadioBox): | |
612 | values = {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'} | |
613 | seulav = {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'} | |
f0c20d94 RD |
614 | def __init__(self, parent, name): |
615 | RadioBox.__init__(self, parent, -1, choices = self.values.keys(), name=name) | |
09f3d4e6 RD |
616 | def GetValue(self): |
617 | return self.values[self.GetStringSelection()] | |
618 | def SetValue(self, value): | |
619 | if not value: value = 'wxHORIZONTAL' | |
620 | self.SetStringSelection(self.seulav[value]) | |
621 | ||
32ce09e2 | 622 | class ParamFile(PPanel): |
f0c20d94 RD |
623 | def __init__(self, parent, name): |
624 | PPanel.__init__(self, parent, name) | |
32ce09e2 RD |
625 | self.ID_TEXT_CTRL = wxNewId() |
626 | self.ID_BUTTON_BROWSE = wxNewId() | |
627 | self.SetBackgroundColour(panel.GetBackgroundColour()) | |
628 | sizer = wxBoxSizer() | |
629 | self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1)) | |
630 | sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 10) | |
631 | self.button = wxButton(self, self.ID_BUTTON_BROWSE, 'Browse...') | |
632 | sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL) | |
633 | self.SetAutoLayout(true) | |
634 | self.SetSizer(sizer) | |
635 | sizer.Fit(self) | |
636 | self.textModified = false | |
637 | EVT_BUTTON(self, self.ID_BUTTON_BROWSE, self.OnButtonBrowse) | |
638 | EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) | |
639 | def OnChange(self, evt): | |
92631ff2 | 640 | if self.freeze: return |
32ce09e2 RD |
641 | self.SetModified() |
642 | self.textModified = true | |
643 | evt.Skip() | |
644 | def GetValue(self): | |
645 | if self.textModified: # text has newer value | |
f0c20d94 | 646 | return self.text.GetValue() |
32ce09e2 RD |
647 | return self.value |
648 | def SetValue(self, value): | |
649 | self.freeze = true | |
650 | self.value = value | |
651 | self.text.SetValue(value) # update text ctrl | |
652 | self.freeze = false | |
653 | def OnButtonBrowse(self, evt): | |
654 | if self.textModified: # text has newer value | |
655 | self.value = self.text.GetValue() | |
656 | dlg = wxFileDialog(self, | |
f0c20d94 | 657 | defaultDir = os.path.dirname(self.value), |
32ce09e2 RD |
658 | defaultFile = os.path.basename(self.value)) |
659 | if dlg.ShowModal() == wxID_OK: | |
660 | # Make relative | |
f0c20d94 RD |
661 | common = os.path.commonprefix([os.path.abspath(frame.dataFile), |
662 | dlg.GetPath()]) | |
32ce09e2 RD |
663 | self.SetValue(dlg.GetPath()[len(common):]) |
664 | self.SetModified() | |
665 | self.textModified = false | |
666 | dlg.Destroy() | |
667 | ||
09f3d4e6 RD |
668 | paramDict = { |
669 | 'flag': ParamFlag, | |
a40b5e84 | 670 | 'style': ParamStyle, 'exstyle': ParamExStyle, |
09f3d4e6 RD |
671 | 'pos': ParamPosSize, 'size': ParamPosSize, |
672 | 'border': ParamInt, 'cols': ParamInt, 'rows': ParamInt, | |
673 | 'vgap': ParamInt, 'hgap': ParamInt, | |
674 | 'checkable': ParamBool, 'accel': ParamAccel, | |
675 | 'label': ParamText, 'title': ParamText, 'value': ParamText, | |
676 | 'content': ParamContent, 'selection': ParamInt, | |
677 | 'min': ParamInt, 'max': ParamInt, | |
a40b5e84 RD |
678 | 'fg': ParamColour, 'bg': ParamColour, 'font': ParamFont, |
679 | 'enabled': ParamBool, 'focused': ParamBool, 'hidden': ParamBool, | |
32ce09e2 | 680 | 'tooltip': ParamText, 'bitmap': ParamFile, 'icon': ParamFile, |
09f3d4e6 | 681 | } |
a40b5e84 | 682 |