]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/tools/XRCed/params.py
Use unbuffered output
[wxWidgets.git] / wxPython / wx / tools / XRCed / params.py
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 # RCS-ID: $Id$
6
7 import string
8 import os.path
9 from globals import *
10 from types import *
11 from wxPython.xrc import *
12
13 genericStyles = ['wxSIMPLE_BORDER', 'wxDOUBLE_BORDER',
14 'wxSUNKEN_BORDER', 'wxRAISED_BORDER',
15 'wxSTATIC_BORDER', 'wxNO_BORDER',
16 'wxTRANSPARENT_WINDOW', 'wxWANTS_CHARS',
17 'wxNO_FULL_REPAINT_ON_RESIZE']
18
19 buttonSize = (35,-1) # in dialog units, transformed to pixels in panel ctor
20
21 # Class that can properly disable children
22 class PPanel(wxPanel):
23 def __init__(self, parent, name):
24 wxPanel.__init__(self, parent, -1, name=name)
25 self.modified = self.freeze = False
26 def Enable(self, value):
27 # Something strange is going on with enable so we make sure...
28 for w in self.GetChildren():
29 w.Enable(value)
30 wxPanel.Enable(self, value)
31 def SetModified(self):
32 self.modified = True
33 g.panel.SetModified(True)
34 # Common method to set modified state
35 def OnChange(self, evt):
36 if self.freeze: return
37 self.SetModified()
38 evt.Skip()
39
40 class ParamBinaryOr(PPanel):
41 def __init__(self, parent, name):
42 PPanel.__init__(self, parent, name)
43 self.ID_TEXT_CTRL = wxNewId()
44 self.ID_BUTTON_CHOICES = wxNewId()
45 self.SetBackgroundColour(g.panel.GetBackgroundColour())
46 sizer = wxBoxSizer()
47 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
48 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
49 self.button = wxButton(self, self.ID_BUTTON_CHOICES, 'Edit...', size=buttonSize)
50 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
51 self.SetAutoLayout(True)
52 self.SetSizer(sizer)
53 sizer.Fit(self)
54 EVT_BUTTON(self, self.ID_BUTTON_CHOICES, self.OnButtonChoices)
55 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
56 def GetValue(self):
57 return self.text.GetValue()
58 def SetValue(self, value):
59 self.freeze = True
60 self.text.SetValue(value)
61 self.freeze = False
62 def OnButtonChoices(self, evt):
63 dlg = g.frame.res.LoadDialog(self, 'DIALOG_CHOICES')
64 listBox = XRCCTRL(dlg, 'CHECK_LIST')
65 listBox.InsertItems(self.values, 0)
66 value = map(string.strip, self.text.GetValue().split('|'))
67 if value == ['']: value = []
68 ignored = []
69 for i in value:
70 try:
71 listBox.Check(self.values.index(i))
72 except ValueError:
73 # Try to find equal
74 if self.equal.has_key(i):
75 listBox.Check(self.values.index(self.equal[i]))
76 else:
77 print 'WARNING: unknown flag: %s: ignored.' % i
78 ignored.append(i)
79 if dlg.ShowModal() == wxID_OK:
80 value = []
81 for i in range(listBox.GetCount()):
82 if listBox.IsChecked(i):
83 value.append(self.values[i])
84 # Add ignored flags
85 value.extend(ignored)
86 if value:
87 self.SetValue(reduce(lambda a,b: a+'|'+b, value))
88 else:
89 self.SetValue('')
90 self.SetModified()
91 dlg.Destroy()
92
93 class ParamFlag(ParamBinaryOr):
94 values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL',
95 'wxEXPAND', 'wxGROW', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT',
96 'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL',
97 'wxALIGN_CENTRE_HORIZONTAL']
98 equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE',
99 'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL',
100 'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL'}
101 def __init__(self, parent, name):
102 ParamBinaryOr.__init__(self, parent, name)
103
104 class ParamStyle(ParamBinaryOr):
105 equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE'}
106 def __init__(self, parent, name):
107 self.values = g.currentXXX.winStyles + genericStyles
108 ParamBinaryOr.__init__(self, parent, name)
109
110 class ParamNonGenericStyle(ParamBinaryOr):
111 def __init__(self, parent, name):
112 self.values = g.currentXXX.winStyles
113 ParamBinaryOr.__init__(self, parent, name)
114
115 class ParamExStyle(ParamBinaryOr):
116 def __init__(self, parent, name):
117 if g.currentXXX:
118 self.values = g.currentXXX.exStyles # constant at the moment
119 else:
120 self.values = []
121 ParamBinaryOr.__init__(self, parent, name)
122
123 class ParamColour(PPanel):
124 def __init__(self, parent, name):
125 PPanel.__init__(self, parent, name)
126 self.ID_TEXT_CTRL = wxNewId()
127 self.ID_BUTTON = wxNewId()
128 self.SetBackgroundColour(g.panel.GetBackgroundColour())
129 sizer = wxBoxSizer()
130 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=(65,-1))
131 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
132 self.button = wxPanel(self, self.ID_BUTTON, wxDefaultPosition, wxSize(20, 1))
133 sizer.Add(self.button, 0, wxGROW | wxALIGN_CENTER_VERTICAL)
134 self.SetAutoLayout(True)
135 self.SetSizer(sizer)
136 sizer.Fit(self)
137 self.textModified = False
138 EVT_PAINT(self.button, self.OnPaintButton)
139 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
140 EVT_LEFT_DOWN(self.button, self.OnLeftDown)
141 def GetValue(self):
142 return self.text.GetValue()
143 def SetValue(self, value):
144 self.freeze = True
145 if not value: value = '#FFFFFF'
146 self.text.SetValue(str(value)) # update text ctrl
147 colour = wxColour(int(value[1:3], 16), int(value[3:5], 16), int(value[5:7], 16))
148 self.button.SetBackgroundColour(colour)
149 self.button.Refresh()
150 self.freeze = False
151 def OnPaintButton(self, evt):
152 dc = wxPaintDC(self.button)
153 dc.SetBrush(wxTRANSPARENT_BRUSH)
154 if self.IsEnabled(): dc.SetPen(wxBLACK_PEN)
155 else: dc.SetPen(wxGREY_PEN)
156 size = self.button.GetSize()
157 dc.DrawRectangle((0, 0), size)
158 def OnLeftDown(self, evt):
159 data = wxColourData()
160 data.SetColour(self.GetValue())
161 dlg = wxColourDialog(self, data)
162 if dlg.ShowModal() == wxID_OK:
163 self.SetValue('#%02X%02X%02X' % dlg.GetColourData().GetColour().Get())
164 self.SetModified()
165 dlg.Destroy()
166
167 ################################################################################
168
169 # Mapping from wx constants ro XML strings
170 fontFamiliesWx2Xml = {wxDEFAULT: 'default', wxDECORATIVE: 'decorative',
171 wxROMAN: 'roman', wxSCRIPT: 'script', wxSWISS: 'swiss',
172 wxMODERN: 'modern'}
173 fontStylesWx2Xml = {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'}
174 fontWeightsWx2Xml = {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'}
175 def ReverseMap(m):
176 rm = {}
177 for k,v in m.items(): rm[v] = k
178 return rm
179 fontFamiliesXml2wx = ReverseMap(fontFamiliesWx2Xml)
180 fontStylesXml2wx = ReverseMap(fontStylesWx2Xml)
181 fontWeightsXml2wx = ReverseMap(fontWeightsWx2Xml)
182
183 class ParamFont(PPanel):
184 def __init__(self, parent, name):
185 PPanel.__init__(self, parent, name)
186 self.ID_TEXT_CTRL = wxNewId()
187 self.ID_BUTTON_SELECT = wxNewId()
188 self.SetBackgroundColour(g.panel.GetBackgroundColour())
189 sizer = wxBoxSizer()
190 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=(200,-1))
191 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
192 self.button = wxButton(self, self.ID_BUTTON_SELECT, 'Select...', size=buttonSize)
193 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
194 self.SetAutoLayout(True)
195 self.SetSizer(sizer)
196 sizer.Fit(self)
197 self.textModified = False
198 EVT_BUTTON(self, self.ID_BUTTON_SELECT, self.OnButtonSelect)
199 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
200 def OnChange(self, evt):
201 PPanel.OnChange(self, evt)
202 self.textModified = True
203 def _defaultValue(self):
204 return ['12', 'default', 'normal', 'normal', '0', '', '']
205 def GetValue(self):
206 if self.textModified: # text has newer value
207 try:
208 return eval(self.text.GetValue())
209 except SyntaxError:
210 wxLogError('Syntax error in parameter value: ' + self.GetName())
211 return self._defaultValue()
212 return self.value
213 def SetValue(self, value):
214 self.freeze = True # disable other handlers
215 if not value: value = self._defaultValue()
216 self.value = value
217 self.text.SetValue(str(value)) # update text ctrl
218 self.freeze = False
219 def OnButtonSelect(self, evt):
220 if self.textModified: # text has newer value
221 try:
222 self.value = eval(self.text.GetValue())
223 except SyntaxError:
224 wxLogError('Syntax error in parameter value: ' + self.GetName())
225 self.value = self._defaultValue()
226 # Make initial font
227 # Default values
228 size = 12
229 family = wxDEFAULT
230 style = weight = wxNORMAL
231 underlined = 0
232 face = ''
233 enc = wxFONTENCODING_DEFAULT
234 # Fall back to default if exceptions
235 error = False
236 try:
237 try: size = int(self.value[0])
238 except ValueError: error = True
239 try: family = fontFamiliesXml2wx[self.value[1]]
240 except KeyError: error = True
241 try: style = fontStylesXml2wx[self.value[2]]
242 except KeyError: error = True
243 try: weight = fontWeightsXml2wx[self.value[3]]
244 except KeyError: error = True
245 try: underlined = int(self.value[4])
246 except ValueError: error = True
247 face = self.value[5]
248 mapper = wxFontMapper()
249 if not self.value[6]: enc = mapper.CharsetToEncoding(self.value[6])
250 except IndexError:
251 error = True
252 if error: wxLogError('Invalid font specification')
253 if enc == wxFONTENCODING_DEFAULT: enc = wxFONTENCODING_SYSTEM
254 font = wxFont(size, family, style, weight, underlined, face, enc)
255 data = wxFontData()
256 data.SetInitialFont(font)
257 dlg = wxFontDialog(self, data)
258 if dlg.ShowModal() == wxID_OK:
259 font = dlg.GetFontData().GetChosenFont()
260 value = [str(font.GetPointSize()),
261 fontFamiliesWx2Xml.get(font.GetFamily(), "default"),
262 fontStylesWx2Xml.get(font.GetStyle(), "normal"),
263 fontWeightsWx2Xml.get(font.GetWeight(), "normal"),
264 str(font.GetUnderlined()),
265 font.GetFaceName().encode(),
266 wxFontMapper_GetEncodingName(font.GetEncoding()).encode()
267 ]
268 # Add ignored flags
269 self.SetValue(value)
270 self.SetModified()
271 self.textModified = False
272 dlg.Destroy()
273
274 ################################################################################
275
276 class ParamInt(PPanel):
277 def __init__(self, parent, name):
278 PPanel.__init__(self, parent, name)
279 self.ID_SPIN_CTRL = wxNewId()
280 sizer = wxBoxSizer()
281 self.spin = wxSpinCtrl(self, self.ID_SPIN_CTRL, size=(50,-1))
282 self.SetBackgroundColour(g.panel.GetBackgroundColour())
283 sizer.Add(self.spin)
284 self.SetAutoLayout(True)
285 self.SetSizer(sizer)
286 sizer.Fit(self)
287 EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange)
288 def GetValue(self):
289 return str(self.spin.GetValue())
290 def SetValue(self, value):
291 self.freeze = True
292 if not value: value = 0
293 self.spin.SetValue(int(value))
294 self.freeze = False
295
296 # Same as int but allows dialog units (XXXd)
297 class ParamUnit(PPanel):
298 def __init__(self, parent, name):
299 PPanel.__init__(self, parent, name)
300 self.ID_TEXT_CTRL = wxNewId()
301 self.ID_SPIN_BUTTON = wxNewId()
302 sizer = wxBoxSizer()
303 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=(35,-1))
304 self.spin = wxSpinButton(self, self.ID_SPIN_BUTTON, style = wxSP_VERTICAL, size=(-1,1))
305 self.spin.SetRange(-10000, 10000)
306 self.SetBackgroundColour(g.panel.GetBackgroundColour())
307 sizer.Add(self.text, 0, wxEXPAND | wxRIGHT, 2)
308 sizer.Add(self.spin, 0, wxEXPAND)
309 self.SetAutoLayout(True)
310 self.SetSizer(sizer)
311 sizer.Fit(self)
312 EVT_SPIN_UP(self, self.ID_SPIN_BUTTON, self.OnSpinUp)
313 EVT_SPIN_DOWN(self, self.ID_SPIN_BUTTON, self.OnSpinDown)
314 def GetValue(self):
315 return self.text.GetValue()
316 def SetValue(self, value):
317 self.freeze = True
318 if not value: value = '0'
319 self.text.SetValue(value)
320 self.freeze = False
321 def Change(self, x):
322 # Check if we are working with dialog units
323 value = self.text.GetValue()
324 units = ''
325 if value[-1].upper() == 'D':
326 units = value[-1]
327 value = value[:-1]
328 try:
329 intValue = int(value) + x
330 self.spin.SetValue(intValue)
331 self.text.SetValue(str(intValue) + units)
332 self.SetModified()
333 except:
334 # !!! Strange, if I use wxLogWarning, event is re-generated
335 print 'incorrect unit format'
336 def OnSpinUp(self, evt):
337 self.Change(1)
338 def OnSpinDown(self, evt):
339 self.Change(-1)
340
341 class ParamMultilineText(PPanel):
342 def __init__(self, parent, name, textWidth=-1):
343 PPanel.__init__(self, parent, name)
344 self.ID_TEXT_CTRL = wxNewId()
345 self.ID_BUTTON_EDIT = wxNewId()
346 self.SetBackgroundColour(g.panel.GetBackgroundColour())
347 sizer = wxBoxSizer()
348 self.SetBackgroundColour(g.panel.GetBackgroundColour())
349 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
350 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
351 self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize)
352 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
353 self.SetAutoLayout(True)
354 self.SetSizer(sizer)
355 sizer.Fit(self)
356 EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit)
357 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
358 def GetValue(self):
359 return self.text.GetValue()
360 def SetValue(self, value):
361 self.freeze = True # disable other handlers
362 self.text.SetValue(value)
363 self.freeze = False # disable other handlers
364 def OnButtonEdit(self, evt):
365 dlg = g.frame.res.LoadDialog(self, 'DIALOG_TEXT')
366 textCtrl = XRCCTRL(dlg, 'TEXT')
367 textCtrl.SetValue(self.text.GetValue())
368 if dlg.ShowModal() == wxID_OK:
369 self.text.SetValue(textCtrl.GetValue())
370 self.SetModified()
371 dlg.Destroy()
372
373 class ParamText(PPanel):
374 def __init__(self, parent, name, textWidth=-1):
375 PPanel.__init__(self, parent, name)
376 self.ID_TEXT_CTRL = wxNewId()
377 # We use sizer even here to have the same size of text control
378 sizer = wxBoxSizer()
379 self.SetBackgroundColour(g.panel.GetBackgroundColour())
380 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(textWidth,-1))
381 if textWidth == -1: option = 1
382 else: option = 0
383 sizer.Add(self.text, option, wxALIGN_CENTER_VERTICAL)
384 self.SetAutoLayout(True)
385 self.SetSizer(sizer)
386 sizer.Fit(self)
387 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
388 def GetValue(self):
389 return self.text.GetValue()
390 def SetValue(self, value):
391 self.freeze = True # disable other handlers
392 self.text.SetValue(value)
393 self.freeze = False # disable other handlers
394
395 class ParamAccel(ParamText):
396 def __init__(self, parent, name):
397 ParamText.__init__(self, parent, name, 100)
398
399 class ParamPosSize(ParamText):
400 def __init__(self, parent, name):
401 ParamText.__init__(self, parent, name, 80)
402
403 class ParamLabel(ParamText):
404 def __init__(self, parent, name):
405 ParamText.__init__(self, parent, name, 200)
406
407 class ParamEncoding(ParamText):
408 def __init__(self, parent, name):
409 ParamText.__init__(self, parent, name, 100)
410
411 class ContentDialog(wxDialog):
412 def __init__(self, parent, value):
413 # Load from resource
414 pre = wxPreDialog()
415 g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_CONTENT')
416 self.this = pre.this
417 self._setOORInfo(self)
418 self.list = XRCCTRL(self, 'LIST')
419 # Set list items
420 for v in value:
421 self.list.Append(v)
422 self.SetAutoLayout(True)
423 self.GetSizer().Fit(self)
424 # Callbacks
425 self.ID_BUTTON_APPEND = XRCID('BUTTON_APPEND')
426 self.ID_BUTTON_REMOVE = XRCID('BUTTON_REMOVE')
427 self.ID_BUTTON_UP = XRCID('BUTTON_UP')
428 self.ID_BUTTON_DOWN = XRCID('BUTTON_DOWN')
429 EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp)
430 EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown)
431 EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend)
432 EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
433 EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI)
434 EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI)
435 EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
436 def OnButtonUp(self, evt):
437 i = self.list.GetSelection()
438 str = self.list.GetString(i)
439 self.list.Delete(i)
440 self.list.InsertItems([str], i-1)
441 self.list.SetSelection(i-1)
442 def OnButtonDown(self, evt):
443 i = self.list.GetSelection()
444 str = self.list.GetString(i)
445 self.list.Delete(i)
446 self.list.InsertItems([str], i+1)
447 self.list.SetSelection(i+1)
448 def OnButtonAppend(self, evt):
449 str = wxGetTextFromUser('Enter new item:', 'Append', '', self)
450 self.list.Append(str)
451 def OnButtonRemove(self, evt):
452 self.list.Delete(self.list.GetSelection())
453 def OnUpdateUI(self, evt):
454 if evt.GetId() == self.ID_BUTTON_REMOVE:
455 evt.Enable(self.list.GetSelection() != -1)
456 elif evt.GetId() == self.ID_BUTTON_UP:
457 evt.Enable(self.list.GetSelection() > 0)
458 elif evt.GetId() == self.ID_BUTTON_DOWN:
459 evt.Enable(self.list.GetSelection() != -1 and \
460 self.list.GetSelection() < self.list.GetCount() - 1)
461
462 class ContentCheckListDialog(wxDialog):
463 def __init__(self, parent, value):
464 pre = wxPreDialog()
465 g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_CONTENT_CHECK_LIST')
466 self.this = pre.this
467 self._setOORInfo(self)
468 self.list = XRCCTRL(self, 'CHECK_LIST')
469 # Set list items
470 i = 0
471 for v,ch in value:
472 self.list.Append(v)
473 self.list.Check(i, ch)
474 i += 1
475 self.SetAutoLayout(True)
476 self.GetSizer().Fit(self)
477 # Callbacks
478 self.ID_BUTTON_APPEND = XRCID('BUTTON_APPEND')
479 self.ID_BUTTON_REMOVE = XRCID('BUTTON_REMOVE')
480 self.ID_BUTTON_UP = XRCID('BUTTON_UP')
481 self.ID_BUTTON_DOWN = XRCID('BUTTON_DOWN')
482 EVT_CHECKLISTBOX(self, self.list.GetId(), self.OnCheck)
483 EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp)
484 EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown)
485 EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend)
486 EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
487 EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI)
488 EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI)
489 EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
490 def OnCheck(self, evt):
491 # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking
492 self.list.Deselect(evt.GetSelection())
493 def OnButtonUp(self, evt):
494 i = self.list.GetSelection()
495 str, ch = self.list.GetString(i), self.list.IsChecked(i)
496 self.list.Delete(i)
497 self.list.InsertItems([str], i-1)
498 self.list.Check(i-1, ch)
499 self.list.SetSelection(i-1)
500 def OnButtonDown(self, evt):
501 i = self.list.GetSelection()
502 str, ch = self.list.GetString(i), self.list.IsChecked(i)
503 self.list.Delete(i)
504 self.list.InsertItems([str], i+1)
505 self.list.Check(i+1, ch)
506 self.list.SetSelection(i+1)
507 def OnButtonAppend(self, evt):
508 str = wxGetTextFromUser('Enter new item:', 'Append', '', self)
509 self.list.Append(str)
510 def OnButtonRemove(self, evt):
511 self.list.Delete(self.list.GetSelection())
512 def OnUpdateUI(self, evt):
513 if evt.GetId() == self.ID_BUTTON_REMOVE:
514 evt.Enable(self.list.GetSelection() != -1)
515 elif evt.GetId() == self.ID_BUTTON_UP:
516 evt.Enable(self.list.GetSelection() > 0)
517 elif evt.GetId() == self.ID_BUTTON_DOWN:
518 evt.Enable(self.list.GetSelection() != -1 and \
519 self.list.GetSelection() < self.list.GetCount() - 1)
520
521 class ParamContent(PPanel):
522 def __init__(self, parent, name):
523 PPanel.__init__(self, parent, name)
524 self.ID_TEXT_CTRL = wxNewId()
525 self.ID_BUTTON_EDIT = wxNewId()
526 self.SetBackgroundColour(g.panel.GetBackgroundColour())
527 sizer = wxBoxSizer()
528 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
529 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
530 self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize)
531 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
532 self.SetAutoLayout(True)
533 self.SetSizer(sizer)
534 sizer.Fit(self)
535 self.textModified = False
536 EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit)
537 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
538 def OnChange(self, evt):
539 PPanel.OnChange(self, evt)
540 self.textModified = True
541 def GetValue(self):
542 if self.textModified: # text has newer value
543 try:
544 return eval(self.text.GetValue())
545 except SyntaxError:
546 wxLogError('Syntax error in parameter value: ' + self.GetName())
547 return []
548 return self.value
549 def SetValue(self, value):
550 self.freeze = True
551 if not value: value = []
552 self.value = value
553 self.text.SetValue(str(value)) # update text ctrl
554 self.freeze = False
555 def OnButtonEdit(self, evt):
556 if self.textModified: # text has newer value
557 try:
558 self.value = eval(self.text.GetValue())
559 except SyntaxError:
560 wxLogError('Syntax error in parameter value: ' + self.GetName())
561 self.value = []
562 dlg = ContentDialog(self, self.value)
563 if dlg.ShowModal() == wxID_OK:
564 value = []
565 for i in range(dlg.list.GetCount()):
566 value.append(dlg.list.GetString(i))
567 # Add ignored flags
568 self.SetValue(value)
569 self.SetModified()
570 self.textModified = False
571 dlg.Destroy()
572
573 # CheckList content
574 class ParamContentCheckList(ParamContent):
575 def __init__(self, parent, name):
576 ParamContent.__init__(self, parent, name)
577 def OnButtonEdit(self, evt):
578 if self.textModified: # text has newer value
579 try:
580 self.value = eval(self.text.GetValue())
581 except SyntaxError:
582 wxLogError('Syntax error in parameter value: ' + self.GetName())
583 self.value = []
584 dlg = ContentCheckListDialog(self, self.value)
585 if dlg.ShowModal() == wxID_OK:
586 value = []
587 for i in range(dlg.list.GetCount()):
588 value.append((dlg.list.GetString(i), dlg.list.IsChecked(i)))
589 # Add ignored flags
590 self.SetValue(value)
591 self.SetModified()
592 self.textModified = False
593 dlg.Destroy()
594
595 class IntListDialog(wxDialog):
596 def __init__(self, parent, value):
597 pre = wxPreDialog()
598 g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_INTLIST')
599 self.this = pre.this
600 self._setOORInfo(self)
601 self.list = XRCCTRL(self, 'LIST')
602 # Set list items
603 value.sort()
604 for v in value:
605 if type(v) != IntType:
606 wxLogError('Invalid item type')
607 else:
608 self.list.Append(str(v))
609 self.SetAutoLayout(True)
610 self.GetSizer().Fit(self)
611 # Callbacks
612 self.ID_BUTTON_ADD = XRCID('BUTTON_ADD')
613 self.ID_BUTTON_REMOVE = XRCID('BUTTON_REMOVE')
614 EVT_BUTTON(self, self.ID_BUTTON_ADD, self.OnButtonAppend)
615 EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
616 EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
617 def OnButtonAppend(self, evt):
618 s = wxGetTextFromUser('Enter new number:', 'Add', '', self)
619 if not s: return
620 # Check that it's unique
621 try:
622 v = int(s)
623 s = str(v) # to be sure
624 i = self.list.FindString(s)
625 if i == -1: # ignore non-unique
626 # Find place to insert
627 found = False
628 for i in range(self.list.GetCount()):
629 if int(self.list.GetString(i)) > v:
630 found = True
631 break
632 if found: self.list.InsertItems([s], i)
633 else: self.list.Append(s)
634 except ValueError:
635 wxLogError('List item is not an int!')
636 def OnButtonRemove(self, evt):
637 self.list.Delete(self.list.GetSelection())
638 def OnUpdateUI(self, evt):
639 if evt.GetId() == self.ID_BUTTON_REMOVE:
640 evt.Enable(self.list.GetSelection() != -1)
641
642 # For growable list
643 class ParamIntList(ParamContent):
644 def __init__(self, parent, name):
645 ParamContent.__init__(self, parent, name)
646 def OnButtonEdit(self, evt):
647 if self.textModified: # text has newer value
648 try:
649 self.value = eval(self.text.GetValue())
650 except SyntaxError:
651 wxLogError('Syntax error in parameter value: ' + self.GetName())
652 self.value = []
653 dlg = IntListDialog(self, self.value)
654 if dlg.ShowModal() == wxID_OK:
655 value = []
656 for i in range(dlg.list.GetCount()):
657 value.append(int(dlg.list.GetString(i)))
658 # Add ignored flags
659 self.SetValue(value)
660 self.SetModified()
661 self.textModified = False
662 dlg.Destroy()
663
664 # Boxless radiobox
665 class RadioBox(PPanel):
666 def __init__(self, parent, id, choices,
667 pos=wxDefaultPosition, name='radiobox'):
668 PPanel.__init__(self, parent, name)
669 self.SetBackgroundColour(g.panel.GetBackgroundColour())
670 self.choices = choices
671 topSizer = wxBoxSizer()
672 for i in choices:
673 button = wxRadioButton(self, -1, i, size=(-1,buttonSize[1]), name=i)
674 topSizer.Add(button, 0, wxRIGHT, 5)
675 EVT_RADIOBUTTON(self, button.GetId(), self.OnRadioChoice)
676 self.SetAutoLayout(True)
677 self.SetSizer(topSizer)
678 topSizer.Fit(self)
679 def SetStringSelection(self, value):
680 self.freeze = True
681 for i in self.choices:
682 self.FindWindowByName(i).SetValue(i == value)
683 self.value = value
684 self.freeze = False
685 def OnRadioChoice(self, evt):
686 if self.freeze: return
687 if evt.GetSelection():
688 self.value = evt.GetEventObject().GetName()
689 self.SetModified()
690 def GetStringSelection(self):
691 return self.value
692
693 class ParamBool(RadioBox):
694 values = {'yes': '1', 'no': '0'}
695 seulav = {'1': 'yes', '0': 'no'}
696 def __init__(self, parent, name):
697 RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name)
698 def GetValue(self):
699 return self.values[self.GetStringSelection()]
700 def SetValue(self, value):
701 if not value: value = '1'
702 self.SetStringSelection(self.seulav[value])
703
704 class ParamOrient(RadioBox):
705 values = {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
706 seulav = {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'}
707 def __init__(self, parent, name):
708 RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name)
709 def GetValue(self):
710 return self.values[self.GetStringSelection()]
711 def SetValue(self, value):
712 if not value: value = 'wxHORIZONTAL'
713 self.SetStringSelection(self.seulav[value])
714
715 class ParamFile(PPanel):
716 def __init__(self, parent, name):
717 PPanel.__init__(self, parent, name)
718 self.ID_TEXT_CTRL = wxNewId()
719 self.ID_BUTTON_BROWSE = wxNewId()
720 self.SetBackgroundColour(g.panel.GetBackgroundColour())
721 sizer = wxBoxSizer()
722 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
723 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
724 self.button = wxButton(self, self.ID_BUTTON_BROWSE, 'Browse...',size=buttonSize)
725 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
726 self.SetAutoLayout(True)
727 self.SetSizer(sizer)
728 sizer.Fit(self)
729 self.textModified = False
730 EVT_BUTTON(self, self.ID_BUTTON_BROWSE, self.OnButtonBrowse)
731 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
732 def OnChange(self, evt):
733 PPanel.OnChange(self, evt)
734 self.textModified = True
735 def GetValue(self):
736 if self.textModified: # text has newer value
737 return self.text.GetValue()
738 return self.value
739 def SetValue(self, value):
740 self.freeze = True
741 self.value = value
742 self.text.SetValue(value) # update text ctrl
743 self.freeze = False
744 def OnButtonBrowse(self, evt):
745 if self.textModified: # text has newer value
746 self.value = self.text.GetValue()
747 dlg = wxFileDialog(self,
748 defaultDir = os.path.abspath(os.path.dirname(self.value)),
749 defaultFile = os.path.basename(self.value))
750 if dlg.ShowModal() == wxID_OK:
751 # Get common part of selected path and current
752 if g.frame.dataFile:
753 curpath = os.path.abspath(g.frame.dataFile)
754 else:
755 curpath = os.path.join(os.getcwd(), '')
756 common = os.path.commonprefix([curpath, dlg.GetPath()])
757 self.SetValue(dlg.GetPath()[len(common):])
758 self.SetModified()
759 self.textModified = False
760 dlg.Destroy()
761
762 class ParamBitmap(PPanel):
763 def __init__(self, parent, name):
764 pre = wxPrePanel()
765 g.frame.res.LoadOnPanel(pre, parent, 'PANEL_BITMAP')
766 self.this = pre.this
767 self._setOORInfo(self)
768 self.modified = self.freeze = False
769 self.SetBackgroundColour(g.panel.GetBackgroundColour())
770 self.radio_std = XRCCTRL(self, 'RADIO_STD')
771 self.radio_file = XRCCTRL(self, 'RADIO_FILE')
772 self.combo = XRCCTRL(self, 'COMBO_STD')
773 self.text = XRCCTRL(self, 'TEXT_FILE')
774 self.button = XRCCTRL(self, 'BUTTON_BROWSE')
775 self.textModified = False
776 self.SetAutoLayout(True)
777 self.GetSizer().SetMinSize((260, -1))
778 self.GetSizer().Fit(self)
779 EVT_RADIOBUTTON(self, XRCID('RADIO_STD'), self.OnRadioStd)
780 EVT_RADIOBUTTON(self, XRCID('RADIO_FILE'), self.OnRadioFile)
781 EVT_BUTTON(self, XRCID('BUTTON_BROWSE'), self.OnButtonBrowse)
782 EVT_COMBOBOX(self, XRCID('COMBO_STD'), self.OnCombo)
783 EVT_TEXT(self, XRCID('COMBO_STD'), self.OnChange)
784 EVT_TEXT(self, XRCID('TEXT_FILE'), self.OnChange)
785 def OnRadioStd(self, evt):
786 self.SetModified()
787 self.SetValue(['wxART_MISSING_IMAGE',''])
788 def OnRadioFile(self, evt):
789 self.SetModified()
790 self.SetValue(['',''])
791 def updateRadios(self):
792 if self.value[0]:
793 self.radio_std.SetValue(True)
794 self.radio_file.SetValue(False)
795 self.text.Enable(False)
796 self.button.Enable(False)
797 self.combo.Enable(True)
798 else:
799 self.radio_std.SetValue(False)
800 self.radio_file.SetValue(True)
801 self.text.Enable(True)
802 self.button.Enable(True)
803 self.combo.Enable(False)
804 def OnChange(self, evt):
805 PPanel.OnChange(self, evt)
806 self.textModified = True
807 def OnCombo(self, evt):
808 PPanel.OnChange(self, evt)
809 self.value[0] = self.combo.GetValue()
810 def GetValue(self):
811 if self.textModified: # text has newer value
812 return [self.combo.GetValue(), self.text.GetValue()]
813 return self.value
814 def SetValue(self, value):
815 self.freeze = True
816 if not value:
817 self.value = ['', '']
818 else:
819 self.value = value
820 self.combo.SetValue(self.value[0])
821 self.text.SetValue(self.value[1]) # update text ctrl
822 self.updateRadios()
823 self.freeze = False
824 def OnButtonBrowse(self, evt):
825 if self.textModified: # text has newer value
826 self.value[1] = self.text.GetValue()
827 dlg = wxFileDialog(self,
828 defaultDir = os.path.abspath(os.path.dirname(self.value[1])),
829 defaultFile = os.path.basename(self.value[1]))
830 if dlg.ShowModal() == wxID_OK:
831 # Get common part of selected path and current
832 if g.frame.dataFile:
833 curpath = os.path.abspath(g.frame.dataFile)
834 else:
835 curpath = os.path.join(os.getcwd(), '')
836 common = os.path.commonprefix([curpath, dlg.GetPath()])
837 self.SetValue(['', dlg.GetPath()[len(common):]])
838 self.SetModified()
839 self.textModified = False
840 dlg.Destroy()
841
842 paramDict = {
843 'flag': ParamFlag,
844 'style': ParamStyle, 'exstyle': ParamExStyle,
845 'pos': ParamPosSize, 'size': ParamPosSize,
846 'border': ParamUnit, 'cols': ParamInt, 'rows': ParamInt,
847 'vgap': ParamUnit, 'hgap': ParamUnit,
848 'checkable': ParamBool, 'checked': ParamBool, 'radio': ParamBool,
849 'accel': ParamAccel,
850 'label': ParamMultilineText, 'title': ParamText, 'value': ParamText,
851 'content': ParamContent, 'selection': ParamInt,
852 'min': ParamInt, 'max': ParamInt,
853 'fg': ParamColour, 'bg': ParamColour, 'font': ParamFont,
854 'enabled': ParamBool, 'focused': ParamBool, 'hidden': ParamBool,
855 'tooltip': ParamText, 'bitmap': ParamBitmap, 'icon': ParamBitmap,
856 'encoding': ParamEncoding
857 }