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