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