2 # Purpose: Classes for parameter introduction
3 # Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
13 'wxSIMPLE_BORDER', 'wxSUNKEN_BORDER', 'wxDOUBLE_BORDER',
14 'wxRAISED_BORDER', 'wxSTATIC_BORDER', 'wxNO_BORDER',
15 'wxCLIP_CHILDREN', 'wxTRANSPARENT_WINDOW', 'wxWANTS_CHARS',
16 'wxNO_FULL_REPAINT_ON_RESIZE', 'wxFULL_REPAINT_ON_RESIZE'
20 'wxWS_EX_VALIDATE_RECURSIVELY',
21 'wxWS_EX_BLOCK_EVENTS',
23 'wxFRAME_EX_CONTEXTHELP',
24 'wxWS_EX_PROCESS_IDLE',
25 'wxWS_EX_PROCESS_UI_UPDATES'
28 # Global var initialized in Panel.__init__ for button size in screen pixels
30 # Button size in dialog units
33 # Class that can properly disable children
34 class PPanel(wx
.Panel
):
35 def __init__(self
, parent
, name
):
36 wx
.Panel
.__init
__(self
, parent
, -1, name
=name
)
37 self
.modified
= self
.freeze
= False
38 def Enable(self
, value
):
40 # Something strange is going on with enable so we make sure...
41 for w
in self
.GetChildren():
43 #wx.Panel.Enable(self, value)
44 def SetModified(self
, state
=True):
46 if state
: g
.panel
.SetModified(True)
47 # Common method to set modified state
48 def OnChange(self
, evt
):
49 if self
.freeze
: return
53 class ParamBinaryOr(PPanel
):
54 def __init__(self
, parent
, name
):
55 PPanel
.__init
__(self
, parent
, name
)
56 self
.ID_TEXT_CTRL
= wx
.NewId()
57 self
.ID_BUTTON_CHOICES
= wx
.NewId()
59 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wx
.Size(200,-1))
60 sizer
.Add(self
.text
, 0, wx
.RIGHT | wx
.ALIGN_CENTER_VERTICAL
, 5)
61 self
.button
= wx
.Button(self
, self
.ID_BUTTON_CHOICES
, 'Edit...', size
=buttonSize
)
62 sizer
.Add(self
.button
, 0, wx
.ALIGN_CENTER_VERTICAL
)
64 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_CHOICES
, self
.OnButtonChoices
)
65 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
67 return self
.text
.GetValue()
68 def SetValue(self
, value
):
70 self
.text
.SetValue(value
)
72 def OnButtonChoices(self
, evt
):
73 dlg
= g
.frame
.res
.LoadDialog(self
, 'DIALOG_CHOICES')
74 if self
.GetName() == 'flag': dlg
.SetTitle('Sizer item flags')
75 elif self
.GetName() == 'style': dlg
.SetTitle('Window styles')
76 elif self
.GetName() == 'exstyle': dlg
.SetTitle('Extended window styles')
77 listBox
= xrc
.XRCCTRL(dlg
, 'CHECKLIST')
78 listBox
.InsertItems(self
.values
, 0)
79 value
= map(string
.strip
, self
.text
.GetValue().split('|'))
80 if value
== ['']: value
= []
84 listBox
.Check(self
.values
.index(i
))
87 if self
.equal
.has_key(i
):
88 listBox
.Check(self
.values
.index(self
.equal
[i
]))
90 print 'WARNING: unknown flag: %s: ignored.' % i
92 if dlg
.ShowModal() == wx
.ID_OK
:
94 for i
in range(listBox
.GetCount()):
95 if listBox
.IsChecked(i
):
96 value
.append(self
.values
[i
])
99 self
.SetValue('|'.join(value
))
103 class ParamFlag(ParamBinaryOr
):
104 values
= ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL',
105 'wxEXPAND', 'wxGROW', 'wxSHAPED', 'wxSTRETCH_NOT',
106 'wxALIGN_CENTRE', 'wxALIGN_LEFT', 'wxALIGN_RIGHT',
107 'wxALIGN_TOP', 'wxALIGN_BOTTOM',
108 'wxALIGN_CENTRE_VERTICAL', 'wxALIGN_CENTRE_HORIZONTAL',
109 'wxADJUST_MINSIZE', 'wxFIXED_MINSIZE'
111 equal
= {'wxALIGN_CENTER': 'wxALIGN_CENTRE',
112 'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL',
113 'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL',
114 'wxUP': 'wxTOP', 'wxDOWN': 'wxBOTTOM', 'wxNORTH': 'wxTOP',
115 'wxSOUTH': 'wxBOTTOM', 'wxWEST': 'wxLEFT', 'wxEAST': 'wxRIGHT'}
116 def __init__(self
, parent
, name
):
117 ParamBinaryOr
.__init
__(self
, parent
, name
)
119 class ParamNonGenericStyle(ParamBinaryOr
):
120 def __init__(self
, parent
, name
):
121 self
.values
= g
.currentXXX
.winStyles
122 ParamBinaryOr
.__init
__(self
, parent
, name
)
124 class ParamStyle(ParamBinaryOr
):
125 equal
= {'wxALIGN_CENTER': 'wxALIGN_CENTRE'}
126 def __init__(self
, parent
, name
):
127 ParamBinaryOr
.__init
__(self
, parent
, name
)
128 self
.valuesSpecific
= g
.currentXXX
.winStyles
129 if self
.valuesSpecific
: # override if using specific styles
131 self
.valuesGeneric
= [s
for s
in genericStyles
132 if s
not in self
.valuesSpecific
]
133 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_CHOICES
, self
.OnButtonChoicesBoth
)
135 self
.values
= genericStyles
136 def OnButtonChoicesBoth(self
, evt
):
137 dlg
= g
.frame
.res
.LoadDialog(self
, 'DIALOG_STYLES')
138 listBoxSpecific
= xrc
.XRCCTRL(dlg
, 'CHECKLIST_SPECIFIC')
139 listBoxSpecific
.InsertItems(self
.valuesSpecific
, 0)
140 listBoxGeneric
= xrc
.XRCCTRL(dlg
, 'CHECKLIST_GENERIC')
141 listBoxGeneric
.InsertItems(self
.valuesGeneric
, 0)
142 value
= map(string
.strip
, self
.text
.GetValue().split('|'))
143 if value
== ['']: value
= []
144 # Set specific styles
145 value2
= [] # collect generic and ignored here
148 listBoxSpecific
.Check(self
.valuesSpecific
.index(i
))
151 if self
.equal
.has_key(i
):
152 listBoxSpecific
.Check(self
.valuesSpecific
.index(self
.equal
[i
]))
156 # Set generic styles, collect non-standart values
159 listBoxGeneric
.Check(self
.valuesGeneric
.index(i
))
162 if self
.equal
.has_key(i
):
163 listBoxGeneric
.Check(self
.valuesGeneric
.index(self
.equal
[i
]))
165 print 'WARNING: unknown flag: %s: ignored.' % i
167 if dlg
.ShowModal() == wx
.ID_OK
:
168 value
= [self
.valuesSpecific
[i
]
169 for i
in range(listBoxSpecific
.GetCount())
170 if listBoxSpecific
.IsChecked(i
)] + \
171 [self
.valuesGeneric
[i
]
172 for i
in range(listBoxGeneric
.GetCount())
173 if listBoxGeneric
.IsChecked(i
)] + ignored
174 self
.SetValue('|'.join(value
))
178 class ParamExStyle(ParamBinaryOr
):
179 def __init__(self
, parent
, name
):
181 self
.values
= g
.currentXXX
.exStyles
+ genericExStyles
184 ParamBinaryOr
.__init
__(self
, parent
, name
)
186 class ParamColour(PPanel
):
187 def __init__(self
, parent
, name
):
188 PPanel
.__init
__(self
, parent
, name
)
189 self
.ID_TEXT_CTRL
= wx
.NewId()
190 self
.ID_BUTTON
= wx
.NewId()
191 sizer
= wx
.BoxSizer()
192 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(80,-1))
193 sizer
.Add(self
.text
, 0, wx
.ALIGN_CENTER_VERTICAL | wx
.TOP | wx
.BOTTOM
, 2)
194 self
.button
= wx
.Panel(self
, self
.ID_BUTTON
, wx
.DefaultPosition
, wx
.Size(20, 20))
195 sizer
.Add(self
.button
, 0, wx
.ALIGN_CENTER_VERTICAL | wx
.LEFT
, 5)
197 self
.textModified
= False
198 wx
.EVT_PAINT(self
.button
, self
.OnPaintButton
)
199 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
200 wx
.EVT_LEFT_DOWN(self
.button
, self
.OnLeftDown
)
202 return self
.text
.GetValue()
203 def SetValue(self
, value
):
205 if not value
: value
= '#FFFFFF'
206 self
.text
.SetValue(str(value
)) # update text ctrl
208 colour
= wx
.Colour(int(value
[1:3], 16), int(value
[3:5], 16), int(value
[5:7], 16))
209 self
.button
.SetBackgroundColour(colour
)
210 except: # ignore errors
212 self
.button
.Refresh()
214 def OnPaintButton(self
, evt
):
215 dc
= wx
.PaintDC(self
.button
)
216 dc
.SetBrush(wx
.TRANSPARENT_BRUSH
)
217 if self
.IsEnabled(): dc
.SetPen(wx
.BLACK_PEN
)
218 else: dc
.SetPen(wx
.GREY_PEN
)
219 size
= self
.button
.GetSize()
220 dc
.DrawRectangle(0, 0, size
.width
, size
.height
)
221 def OnLeftDown(self
, evt
):
222 data
= wx
.ColourData()
223 data
.SetColour(self
.GetValue())
224 dlg
= wx
.ColourDialog(self
, data
)
225 if dlg
.ShowModal() == wx
.ID_OK
:
226 self
.SetValue('#%02X%02X%02X' % dlg
.GetColourData().GetColour().Get())
230 ################################################################################
232 # Mapping from wx constants to XML strings
233 fontFamiliesWx2Xml
= {wx
.DEFAULT
: 'default', wx
.DECORATIVE
: 'decorative',
234 wx
.ROMAN
: 'roman', wx
.SCRIPT
: 'script', wx
.SWISS
: 'swiss',
236 fontStylesWx2Xml
= {wx.NORMAL: 'normal', wx.SLANT: 'slant', wx.ITALIC: 'italic'}
237 fontWeightsWx2Xml
= {wx.NORMAL: 'normal', wx.LIGHT: 'light', wx.BOLD: 'bold'}
240 for k
,v
in m
.items(): rm
[v
] = k
242 fontFamiliesXml2wx
= ReverseMap(fontFamiliesWx2Xml
)
243 fontStylesXml2wx
= ReverseMap(fontStylesWx2Xml
)
244 fontWeightsXml2wx
= ReverseMap(fontWeightsWx2Xml
)
246 class ParamFont(PPanel
):
247 def __init__(self
, parent
, name
):
248 PPanel
.__init
__(self
, parent
, name
)
249 self
.ID_TEXT_CTRL
= wx
.NewId()
250 self
.ID_BUTTON_SELECT
= wx
.NewId()
251 sizer
= wx
.BoxSizer()
252 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(200,-1))
253 sizer
.Add(self
.text
, 0, wx
.RIGHT | wx
.ALIGN_CENTER_VERTICAL
, 5)
254 self
.button
= wx
.Button(self
, self
.ID_BUTTON_SELECT
, 'Select...', size
=buttonSize
)
255 sizer
.Add(self
.button
, 0, wx
.ALIGN_CENTER_VERTICAL
)
257 self
.textModified
= False
258 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_SELECT
, self
.OnButtonSelect
)
259 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
260 def OnChange(self
, evt
):
261 PPanel
.OnChange(self
, evt
)
262 self
.textModified
= True
263 def _defaultValue(self
):
264 return [`g
._sysFont
.GetPointSize()`
, 'default', 'normal', 'normal', '0', '', '']
266 if self
.textModified
: # text has newer value
268 return eval(self
.text
.GetValue())
270 wx
.LogError('Syntax error in parameter value: ' + self
.GetName())
271 return self
._defaultValue
()
273 def SetValue(self
, value
):
274 self
.freeze
= True # disable other handlers
275 if not value
: value
= self
._defaultValue
()
277 self
.text
.SetValue(str(value
)) # update text ctrl
279 def OnButtonSelect(self
, evt
):
280 if self
.textModified
: # text has newer value
282 self
.value
= eval(self
.text
.GetValue())
284 wx
.LogError('Syntax error in parameter value: ' + self
.GetName())
285 self
.value
= self
._defaultValue
()
288 size
= g
._sysFont
.GetPointSize()
290 style
= weight
= wx
.NORMAL
293 enc
= wx
.FONTENCODING_DEFAULT
294 # Fall back to default if exceptions
297 try: size
= int(self
.value
[0])
298 except ValueError: error
= True; wx
.LogError('Invalid size specification')
299 try: family
= fontFamiliesXml2wx
[self
.value
[1]]
300 except KeyError: error
= True; wx
.LogError('Invalid family specification')
301 try: style
= fontStylesXml2wx
[self
.value
[2]]
302 except KeyError: error
= True; wx
.LogError('Invalid style specification')
303 try: weight
= fontWeightsXml2wx
[self
.value
[3]]
304 except KeyError: error
= True; wx
.LogError('Invalid weight specification')
305 try: underlined
= bool(self
.value
[4])
306 except ValueError: error
= True; wx
.LogError('Invalid underlined flag specification')
310 mapper
= wx
.FontMapper()
311 if not self
.value
[6]: enc
= mapper
.CharsetToEncoding(self
.value
[6])
313 if error
: wx
.LogError('Invalid font specification')
314 if enc
== wx
.FONTENCODING_DEFAULT
: enc
= wx
.FONTENCODING_SYSTEM
315 font
= wx
.Font(size
, family
, style
, weight
, underlined
, face
, enc
)
317 data
.SetInitialFont(font
)
318 dlg
= wx
.FontDialog(self
, data
)
319 if dlg
.ShowModal() == wx
.ID_OK
:
320 font
= dlg
.GetFontData().GetChosenFont()
321 if font
.GetEncoding() == wx
.FONTENCODING_SYSTEM
:
324 encName
= wx
.FontMapper
.GetEncodingName(font
.GetEncoding()).encode()
325 value
= [str(font
.GetPointSize()),
326 fontFamiliesWx2Xml
.get(font
.GetFamily(), "default"),
327 fontStylesWx2Xml
.get(font
.GetStyle(), "normal"),
328 fontWeightsWx2Xml
.get(font
.GetWeight(), "normal"),
329 str(int(font
.GetUnderlined())),
330 font
.GetFaceName().encode(),
335 self
.textModified
= False
338 ################################################################################
340 class ParamInt(PPanel
):
341 def __init__(self
, parent
, name
):
342 PPanel
.__init
__(self
, parent
, name
)
343 self
.ID_SPIN_CTRL
= wx
.NewId()
344 sizer
= wx
.BoxSizer()
345 self
.spin
= wx
.SpinCtrl(self
, self
.ID_SPIN_CTRL
, size
=(60,-1))
346 self
.spin
.SetRange(-2147483648, 2147483647) # min/max integers
349 wx
.EVT_SPINCTRL(self
, self
.ID_SPIN_CTRL
, self
.OnChange
)
351 return str(self
.spin
.GetValue())
352 def SetValue(self
, value
):
354 if not value
: value
= 0
355 self
.spin
.SetValue(int(value
))
358 # Non-negative number
359 class ParamIntNN(PPanel
):
360 def __init__(self
, parent
, name
):
361 PPanel
.__init
__(self
, parent
, name
)
362 self
.ID_SPIN_CTRL
= wx
.NewId()
363 sizer
= wx
.BoxSizer()
364 self
.spin
= wx
.SpinCtrl(self
, self
.ID_SPIN_CTRL
, size
=(60,-1))
365 self
.spin
.SetRange(0, 10000) # min/max integers
368 wx
.EVT_SPINCTRL(self
, self
.ID_SPIN_CTRL
, self
.OnChange
)
370 return str(self
.spin
.GetValue())
371 def SetValue(self
, value
):
373 if not value
: value
= 0
374 self
.spin
.SetValue(int(value
))
377 # Same as int but allows dialog units (XXXd)
378 class ParamUnit(PPanel
):
379 def __init__(self
, parent
, name
):
380 PPanel
.__init
__(self
, parent
, name
)
381 self
.ID_TEXT_CTRL
= wx
.NewId()
382 self
.ID_SPIN_BUTTON
= wx
.NewId()
383 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
384 self
.spin
= wx
.SpinButton(self
, self
.ID_SPIN_BUTTON
, style
= wx
.SP_VERTICAL
, size
=(-1,0))
385 textW
= 60 - self
.spin
.GetSize()[0]
386 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(textW
,-1))
387 self
.spin
.SetRange(-10000, 10000)
388 sizer
.Add(self
.text
, 0, wx
.EXPAND
)
389 sizer
.Add(self
.spin
, 0, wx
.EXPAND
)
391 self
.spin
.Bind(wx
.EVT_SPIN_UP
, self
.OnSpinUp
)
392 self
.spin
.Bind(wx
.EVT_SPIN_DOWN
, self
.OnSpinDown
)
394 return self
.text
.GetValue()
395 def SetValue(self
, value
):
396 if not value
: value
= '0'
397 self
.text
.SetValue(value
)
401 # Check if we are working with dialog units
402 value
= self
.text
.GetValue()
404 if value
[-1].upper() == 'D':
408 intValue
= int(value
) + x
409 self
.spin
.SetValue(intValue
)
410 if x
: # 0 can be passed to update spin value only
411 self
.text
.SetValue(str(intValue
) + units
)
414 # !!! Strange, if I use wx.LogWarning, event is re-generated
415 print 'ERROR: incorrect unit format'
417 def OnSpinUp(self
, evt
):
420 def OnSpinDown(self
, evt
):
421 if self
.freeze
: return
425 class ParamMultilineText(PPanel
):
426 def __init__(self
, parent
, name
, textWidth
=-1):
427 PPanel
.__init
__(self
, parent
, name
)
428 self
.ID_TEXT_CTRL
= wx
.NewId()
429 self
.ID_BUTTON_EDIT
= wx
.NewId()
430 sizer
= wx
.BoxSizer()
431 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wx
.Size(200,-1))
432 sizer
.Add(self
.text
, 0, wx
.RIGHT | wx
.ALIGN_CENTER_VERTICAL
, 5)
433 self
.button
= wx
.Button(self
, self
.ID_BUTTON_EDIT
, 'Edit...', size
=buttonSize
)
434 sizer
.Add(self
.button
, 0, wx
.ALIGN_CENTER_VERTICAL
)
435 self
.SetSizerAndFit(sizer
)
436 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_EDIT
, self
.OnButtonEdit
)
437 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
439 return self
.text
.GetValue()
440 def SetValue(self
, value
):
441 self
.freeze
= True # disable other handlers
442 self
.text
.SetValue(value
)
443 self
.freeze
= False # disable other handlers
444 def OnButtonEdit(self
, evt
):
445 dlg
= g
.frame
.res
.LoadDialog(self
, 'DIALOG_TEXT')
446 textCtrl
= xrc
.XRCCTRL(dlg
, 'TEXT')
447 textCtrl
.SetValue(self
.text
.GetValue())
448 if dlg
.ShowModal() == wx
.ID_OK
:
449 self
.text
.SetValue(textCtrl
.GetValue())
453 class ParamText(PPanel
):
454 def __init__(self
, parent
, name
, textWidth
=-1, style
=0):
455 PPanel
.__init
__(self
, parent
, name
)
456 self
.ID_TEXT_CTRL
= wx
.NewId()
457 # We use sizer even here to have the same size of text control
458 sizer
= wx
.BoxSizer()
459 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wx
.Size(textWidth
,-1), style
=style
)
460 if textWidth
== -1: option
= 1
462 sizer
.Add(self
.text
, option
, wx
.ALIGN_CENTER_VERTICAL | wx
.TOP | wx
.BOTTOM
, 2)
464 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
466 return self
.text
.GetValue()
467 def SetValue(self
, value
):
468 self
.freeze
= True # disable other handlers
469 self
.text
.SetValue(value
)
470 self
.freeze
= False # disable other handlers
472 class ParamAccel(ParamText
):
473 def __init__(self
, parent
, name
):
474 ParamText
.__init
__(self
, parent
, name
, 100)
476 class ParamPosSize(ParamText
):
477 def __init__(self
, parent
, name
):
478 ParamText
.__init
__(self
, parent
, name
, 80)
480 class ParamLabel(ParamText
):
481 def __init__(self
, parent
, name
):
482 ParamText
.__init
__(self
, parent
, name
, 200)
484 class ParamEncoding(ParamText
):
485 def __init__(self
, parent
, name
):
486 ParamText
.__init
__(self
, parent
, name
, 100)
488 class ParamComment(ParamText
):
489 def __init__(self
, parent
, name
):
490 ParamText
.__init
__(self
, parent
, name
, 330 + buttonSize
[0],
491 style
=wx
.TE_PROCESS_ENTER
)
493 class ContentDialog(wx
.Dialog
):
494 def __init__(self
, parent
, value
):
497 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_CONTENT')
499 self
.list = xrc
.XRCCTRL(self
, 'LIST')
503 self
.SetAutoLayout(True)
504 self
.GetSizer().Fit(self
)
506 self
.ID_BUTTON_APPEND
= xrc
.XRCID('BUTTON_APPEND')
507 self
.ID_BUTTON_REMOVE
= xrc
.XRCID('BUTTON_REMOVE')
508 self
.ID_BUTTON_UP
= xrc
.XRCID('BUTTON_UP')
509 self
.ID_BUTTON_DOWN
= xrc
.XRCID('BUTTON_DOWN')
510 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_UP
, self
.OnButtonUp
)
511 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_DOWN
, self
.OnButtonDown
)
512 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_APPEND
, self
.OnButtonAppend
)
513 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
514 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_UP
, self
.OnUpdateUI
)
515 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_DOWN
, self
.OnUpdateUI
)
516 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
517 def OnButtonUp(self
, evt
):
518 i
= self
.list.GetSelection()
519 str = self
.list.GetString(i
)
521 self
.list.InsertItems([str], i
-1)
522 self
.list.SetSelection(i
-1)
523 def OnButtonDown(self
, evt
):
524 i
= self
.list.GetSelection()
525 str = self
.list.GetString(i
)
527 self
.list.InsertItems([str], i
+1)
528 self
.list.SetSelection(i
+1)
529 def OnButtonAppend(self
, evt
):
530 str = wx
.GetTextFromUser('Enter new item:', 'Append', '', self
)
531 self
.list.Append(str)
532 def OnButtonRemove(self
, evt
):
533 self
.list.Delete(self
.list.GetSelection())
534 def OnUpdateUI(self
, evt
):
535 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
536 evt
.Enable(self
.list.GetSelection() != -1)
537 elif evt
.GetId() == self
.ID_BUTTON_UP
:
538 evt
.Enable(self
.list.GetSelection() > 0)
539 elif evt
.GetId() == self
.ID_BUTTON_DOWN
:
540 evt
.Enable(self
.list.GetSelection() != -1 and \
541 self
.list.GetSelection() < self
.list.GetCount() - 1)
543 class ContentCheckListDialog(wx
.Dialog
):
544 def __init__(self
, parent
, value
):
546 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_CONTENT_CHECKLIST')
548 self
.list = xrc
.XRCCTRL(self
, 'CHECK_LIST')
553 self
.list.Check(i
, ch
)
555 self
.SetAutoLayout(True)
556 self
.GetSizer().Fit(self
)
558 self
.ID_BUTTON_APPEND
= xrc
.XRCID('BUTTON_APPEND')
559 self
.ID_BUTTON_REMOVE
= xrc
.XRCID('BUTTON_REMOVE')
560 self
.ID_BUTTON_UP
= xrc
.XRCID('BUTTON_UP')
561 self
.ID_BUTTON_DOWN
= xrc
.XRCID('BUTTON_DOWN')
562 wx
.EVT_CHECKLISTBOX(self
, self
.list.GetId(), self
.OnCheck
)
563 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_UP
, self
.OnButtonUp
)
564 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_DOWN
, self
.OnButtonDown
)
565 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_APPEND
, self
.OnButtonAppend
)
566 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
567 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_UP
, self
.OnUpdateUI
)
568 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_DOWN
, self
.OnUpdateUI
)
569 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
570 def OnCheck(self
, evt
):
571 # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking
572 self
.list.Deselect(evt
.GetSelection())
573 def OnButtonUp(self
, evt
):
574 i
= self
.list.GetSelection()
575 str, ch
= self
.list.GetString(i
), self
.list.IsChecked(i
)
577 self
.list.InsertItems([str], i
-1)
578 self
.list.Check(i
-1, ch
)
579 self
.list.SetSelection(i
-1)
580 def OnButtonDown(self
, evt
):
581 i
= self
.list.GetSelection()
582 str, ch
= self
.list.GetString(i
), self
.list.IsChecked(i
)
584 self
.list.InsertItems([str], i
+1)
585 self
.list.Check(i
+1, ch
)
586 self
.list.SetSelection(i
+1)
587 def OnButtonAppend(self
, evt
):
588 str = wx
.GetTextFromUser('Enter new item:', 'Append', '', self
)
589 self
.list.Append(str)
590 def OnButtonRemove(self
, evt
):
591 self
.list.Delete(self
.list.GetSelection())
592 def OnUpdateUI(self
, evt
):
593 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
594 evt
.Enable(self
.list.GetSelection() != -1)
595 elif evt
.GetId() == self
.ID_BUTTON_UP
:
596 evt
.Enable(self
.list.GetSelection() > 0)
597 elif evt
.GetId() == self
.ID_BUTTON_DOWN
:
598 evt
.Enable(self
.list.GetSelection() != -1 and \
599 self
.list.GetSelection() < self
.list.GetCount() - 1)
601 class ParamContent(PPanel
):
602 def __init__(self
, parent
, name
):
603 PPanel
.__init
__(self
, parent
, name
)
604 self
.ID_TEXT_CTRL
= wx
.NewId()
605 self
.ID_BUTTON_EDIT
= wx
.NewId()
606 sizer
= wx
.BoxSizer()
607 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wx
.Size(200,-1))
608 sizer
.Add(self
.text
, 0, wx
.RIGHT | wx
.ALIGN_CENTER_VERTICAL
, 5)
609 self
.button
= wx
.Button(self
, self
.ID_BUTTON_EDIT
, 'Edit...', size
=buttonSize
)
610 sizer
.Add(self
.button
, 0, wx
.ALIGN_CENTER_VERTICAL
)
612 self
.textModified
= False
613 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_EDIT
, self
.OnButtonEdit
)
614 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
615 def OnChange(self
, evt
):
616 PPanel
.OnChange(self
, evt
)
617 self
.textModified
= True
619 if self
.textModified
: # text has newer value
621 return self
.text
.GetValue().split('|')
625 def SetValue(self
, value
):
627 if not value
: value
= []
629 repr_
= '|'.join(map(str, value
))
630 self
.text
.SetValue(repr_
) # update text ctrl
632 def OnButtonEdit(self
, evt
):
633 if self
.textModified
: # text has newer value
634 self
.value
= self
.GetValue()
635 dlg
= ContentDialog(self
, self
.value
)
636 if dlg
.ShowModal() == wx
.ID_OK
:
638 for i
in range(dlg
.list.GetCount()):
639 value
.append(dlg
.list.GetString(i
))
642 self
.textModified
= False
644 def SetModified(self
, state
=True):
645 PPanel
.SetModified(self
, state
)
646 self
.textModified
= False
649 class ParamContentCheckList(ParamContent
):
650 def __init__(self
, parent
, name
):
651 ParamContent
.__init
__(self
, parent
, name
)
652 def OnButtonEdit(self
, evt
):
653 if self
.textModified
: # text has newer value
654 self
.value
= self
.GetValue()
655 dlg
= ContentCheckListDialog(self
, self
.value
)
656 if dlg
.ShowModal() == wx
.ID_OK
:
658 for i
in range(dlg
.list.GetCount()):
659 value
.append((dlg
.list.GetString(i
), int(dlg
.list.IsChecked(i
))))
662 self
.textModified
= False
664 def SetValue(self
, value
):
666 if not value
: value
= []
668 repr_
= '|'.join(map(str,value
))
669 self
.text
.SetValue(repr_
) # update text ctrl
672 class IntListDialog(wx
.Dialog
):
673 def __init__(self
, parent
, value
):
675 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_INTLIST')
677 self
.list = xrc
.XRCCTRL(self
, 'LIST')
681 if type(v
) != IntType
:
682 wx
.LogError('Invalid item type')
684 self
.list.Append(str(v
))
685 self
.SetAutoLayout(True)
686 self
.GetSizer().Fit(self
)
688 self
.spinCtrl
= xrc
.XRCCTRL(self
, 'SPIN')
689 wx
.EVT_BUTTON(self
, xrc
.XRCID('BUTTON_ADD'), self
.OnButtonAdd
)
690 self
.ID_BUTTON_REMOVE
= xrc
.XRCID('BUTTON_REMOVE')
691 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
692 wx
.EVT_BUTTON(self
, xrc
.XRCID('BUTTON_CLEAR'), self
.OnButtonClear
)
693 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
694 def OnButtonAdd(self
, evt
):
695 # Check that it's unique
697 v
= self
.spinCtrl
.GetValue()
698 s
= str(v
) # to be sure
699 i
= self
.list.FindString(s
)
700 if i
== -1: # ignore non-unique
701 # Find place to insert
703 for i
in range(self
.list.GetCount()):
704 if int(self
.list.GetString(i
)) > v
:
707 if found
: self
.list.InsertItems([s
], i
)
708 else: self
.list.Append(s
)
710 wx
.LogError('List item is not an int!')
711 def OnButtonRemove(self
, evt
):
712 self
.list.Delete(self
.list.GetSelection())
713 def OnButtonClear(self
, evt
):
715 def OnUpdateUI(self
, evt
):
716 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
717 evt
.Enable(self
.list.GetSelection() != -1)
720 class ParamIntList(ParamContent
):
721 def __init__(self
, parent
, name
):
722 ParamContent
.__init
__(self
, parent
, name
)
723 def OnButtonEdit(self
, evt
):
724 if self
.textModified
: # text has newer value
726 self
.value
= map(int, self
.text
.GetValue().split('|'))
729 dlg
= IntListDialog(self
, self
.value
)
730 if dlg
.ShowModal() == wx
.ID_OK
:
732 for i
in range(dlg
.list.GetCount()):
733 value
.append(int(dlg
.list.GetString(i
)))
736 self
.textModified
= False
740 class RadioBox(PPanel
):
741 def __init__(self
, parent
, id, choices
,
742 pos
=wx
.DefaultPosition
, name
='radiobox'):
743 PPanel
.__init
__(self
, parent
, name
)
744 self
.choices
= choices
745 topSizer
= wx
.BoxSizer()
747 button
= wx
.RadioButton(self
, -1, i
, size
=(-1,buttonSize
[1]), name
=i
)
748 topSizer
.Add(button
, 0, wx
.RIGHT
, 5)
749 wx
.EVT_RADIOBUTTON(self
, button
.GetId(), self
.OnRadioChoice
)
750 self
.SetSizer(topSizer
)
751 def SetStringSelection(self
, value
):
753 for i
in self
.choices
:
754 self
.FindWindowByName(i
).SetValue(i
== value
)
757 def OnRadioChoice(self
, evt
):
758 if self
.freeze
: return
759 if evt
.GetSelection():
760 self
.value
= evt
.GetEventObject().GetName()
762 def GetStringSelection(self
):
765 class ParamBool(RadioBox
):
766 values
= {'yes': '1', 'no': '0'}
767 seulav
= {'1': 'yes', '0': 'no'}
768 def __init__(self
, parent
, name
):
769 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
771 return self
.values
[self
.GetStringSelection()]
772 def SetValue(self
, value
):
773 if not value
: value
= '1'
774 self
.SetStringSelection(self
.seulav
[value
])
776 class ParamOrient(RadioBox
):
777 values
= {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
778 seulav
= {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'}
779 def __init__(self
, parent
, name
):
780 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
782 return self
.values
[self
.GetStringSelection()]
783 def SetValue(self
, value
):
784 if not value
: value
= 'wxHORIZONTAL'
785 self
.SetStringSelection(self
.seulav
[value
])
787 class ParamOrientation(RadioBox
):
788 values
= {'horizontal': 'horizontal', 'vertical': 'vertical'}
789 seulav
= {'horizontal': 'horizontal', 'vertical': 'vertical'}
790 def __init__(self
, parent
, name
):
791 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
793 return self
.values
[self
.GetStringSelection()]
794 def SetValue(self
, value
):
795 if not value
: value
= 'vertical'
796 self
.SetStringSelection(self
.seulav
[value
])
798 class ParamFile(PPanel
):
799 def __init__(self
, parent
, name
):
800 PPanel
.__init
__(self
, parent
, name
)
801 self
.ID_TEXT_CTRL
= wx
.NewId()
802 self
.ID_BUTTON_BROWSE
= wx
.NewId()
803 sizer
= wx
.BoxSizer()
804 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wx
.Size(200,-1))
805 sizer
.Add(self
.text
, 0, wx
.RIGHT | wx
.ALIGN_CENTER_VERTICAL
, 5)
806 self
.button
= wx
.Button(self
, self
.ID_BUTTON_BROWSE
, 'Browse...',size
=buttonSize
)
807 sizer
.Add(self
.button
, 0, wx
.ALIGN_CENTER_VERTICAL
)
809 self
.textModified
= False
810 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_BROWSE
, self
.OnButtonBrowse
)
811 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
812 def OnChange(self
, evt
):
813 PPanel
.OnChange(self
, evt
)
814 self
.textModified
= True
816 if self
.textModified
: # text has newer value
817 return self
.text
.GetValue()
819 def SetValue(self
, value
):
822 self
.text
.SetValue(value
) # update text ctrl
824 def OnButtonBrowse(self
, evt
):
825 if self
.textModified
: # text has newer value
826 self
.value
= self
.text
.GetValue()
827 dlg
= wx
.FileDialog(self
,
828 defaultDir
= os
.path
.abspath(os
.path
.dirname(self
.value
)),
829 defaultFile
= os
.path
.basename(self
.value
))
830 if dlg
.ShowModal() == wx
.ID_OK
:
831 # Get common part of selected path and current
833 curpath
= os
.path
.abspath(g
.frame
.dataFile
)
835 curpath
= os
.path
.join(os
.getcwd(), '')
836 common
= os
.path
.commonprefix([curpath
, dlg
.GetPath()])
837 self
.SetValue(dlg
.GetPath()[len(common
):])
839 self
.textModified
= False
842 class ParamBitmap(PPanel
):
843 def __init__(self
, parent
, name
):
845 g
.frame
.res
.LoadOnPanel(pre
, parent
, 'PANEL_BITMAP')
847 self
.modified
= self
.freeze
= False
848 self
.radio_std
= xrc
.XRCCTRL(self
, 'RADIO_STD')
849 self
.radio_file
= xrc
.XRCCTRL(self
, 'RADIO_FILE')
850 self
.combo
= xrc
.XRCCTRL(self
, 'COMBO_STD')
851 self
.text
= xrc
.XRCCTRL(self
, 'TEXT_FILE')
852 self
.button
= xrc
.XRCCTRL(self
, 'BUTTON_BROWSE')
853 self
.textModified
= False
854 self
.SetAutoLayout(True)
855 self
.GetSizer().SetMinSize((260, -1))
856 self
.GetSizer().Fit(self
)
857 wx
.EVT_RADIOBUTTON(self
, xrc
.XRCID('RADIO_STD'), self
.OnRadioStd
)
858 wx
.EVT_RADIOBUTTON(self
, xrc
.XRCID('RADIO_FILE'), self
.OnRadioFile
)
859 wx
.EVT_BUTTON(self
, xrc
.XRCID('BUTTON_BROWSE'), self
.OnButtonBrowse
)
860 wx
.EVT_COMBOBOX(self
, xrc
.XRCID('COMBO_STD'), self
.OnCombo
)
861 wx
.EVT_TEXT(self
, xrc
.XRCID('COMBO_STD'), self
.OnChange
)
862 wx
.EVT_TEXT(self
, xrc
.XRCID('TEXT_FILE'), self
.OnChange
)
863 def OnRadioStd(self
, evt
):
865 self
.SetValue(['wxART_MISSING_IMAGE',''])
866 def OnRadioFile(self
, evt
):
868 self
.SetValue(['',''])
869 def updateRadios(self
):
871 self
.radio_std
.SetValue(True)
872 self
.radio_file
.SetValue(False)
873 self
.text
.Enable(False)
874 self
.button
.Enable(False)
875 self
.combo
.Enable(True)
877 self
.radio_std
.SetValue(False)
878 self
.radio_file
.SetValue(True)
879 self
.text
.Enable(True)
880 self
.button
.Enable(True)
881 self
.combo
.Enable(False)
882 def OnChange(self
, evt
):
883 PPanel
.OnChange(self
, evt
)
884 self
.textModified
= True
885 def OnCombo(self
, evt
):
886 PPanel
.OnChange(self
, evt
)
887 self
.value
[0] = self
.combo
.GetValue()
889 if self
.textModified
: # text has newer value
890 return [self
.combo
.GetValue(), self
.text
.GetValue()]
892 def SetValue(self
, value
):
895 self
.value
= ['', '']
898 self
.combo
.SetValue(self
.value
[0])
899 self
.text
.SetValue(self
.value
[1]) # update text ctrl
902 def OnButtonBrowse(self
, evt
):
903 if self
.textModified
: # text has newer value
904 self
.value
[1] = self
.text
.GetValue()
905 dlg
= wx
.FileDialog(self
,
906 defaultDir
= os
.path
.abspath(os
.path
.dirname(self
.value
[1])),
907 defaultFile
= os
.path
.basename(self
.value
[1]))
908 if dlg
.ShowModal() == wx
.ID_OK
:
909 # Get common part of selected path and current
911 curpath
= os
.path
.abspath(g
.frame
.dataFile
)
913 curpath
= os
.path
.join(os
.getcwd(), '')
914 common
= os
.path
.commonprefix([curpath
, dlg
.GetPath()])
915 self
.SetValue(['', dlg
.GetPath()[len(common
):]])
917 self
.textModified
= False
922 'style': ParamStyle
, 'exstyle': ParamExStyle
,
923 'pos': ParamPosSize
, 'size': ParamPosSize
,
924 'cellpos': ParamPosSize
, 'cellspan': ParamPosSize
,
925 'border': ParamUnit
, 'cols': ParamIntNN
, 'rows': ParamIntNN
,
926 'vgap': ParamUnit
, 'hgap': ParamUnit
,
927 'checkable': ParamBool
, 'checked': ParamBool
, 'radio': ParamBool
,
929 'label': ParamMultilineText
, 'title': ParamText
, 'value': ParamText
,
930 'content': ParamContent
, 'selection': ParamIntNN
,
931 'min': ParamInt
, 'max': ParamInt
,
932 'fg': ParamColour
, 'bg': ParamColour
, 'font': ParamFont
,
933 'enabled': ParamBool
, 'focused': ParamBool
, 'hidden': ParamBool
,
934 'tooltip': ParamText
, 'bitmap': ParamBitmap
, 'icon': ParamBitmap
,
935 'encoding': ParamEncoding
, 'borders': ParamUnit
,
936 'comment': ParamComment