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
):
39 # Something strange is going on with enable so we make sure...
40 for w
in self
.GetChildren():
42 #wx.Panel.Enable(self, value)
43 def SetModified(self
, state
=True):
45 if state
: g
.panel
.SetModified(True)
46 # Common method to set modified state
47 def OnChange(self
, evt
):
48 if self
.freeze
: return
52 class ParamBinaryOr(PPanel
):
53 def __init__(self
, parent
, name
):
54 PPanel
.__init
__(self
, parent
, name
)
55 self
.ID_TEXT_CTRL
= wx
.NewId()
56 self
.ID_BUTTON_CHOICES
= wx
.NewId()
58 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wx
.Size(200,-1))
59 sizer
.Add(self
.text
, 0, wx
.RIGHT | wx
.ALIGN_CENTER_VERTICAL
, 5)
60 self
.button
= wx
.Button(self
, self
.ID_BUTTON_CHOICES
, 'Edit...', size
=buttonSize
)
61 sizer
.Add(self
.button
, 0, wx
.ALIGN_CENTER_VERTICAL
)
63 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_CHOICES
, self
.OnButtonChoices
)
64 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
66 return self
.text
.GetValue()
67 def SetValue(self
, value
):
69 self
.text
.SetValue(value
)
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
= xrc
.XRCCTRL(dlg
, 'CHECKLIST')
77 listBox
.InsertItems(self
.values
, 0)
78 value
= map(string
.strip
, self
.text
.GetValue().split('|'))
79 if value
== ['']: value
= []
83 listBox
.Check(self
.values
.index(i
))
86 if self
.equal
.has_key(i
):
87 listBox
.Check(self
.values
.index(self
.equal
[i
]))
89 print 'WARNING: unknown flag: %s: ignored.' % i
91 if dlg
.ShowModal() == wx
.ID_OK
:
93 for i
in range(listBox
.GetCount()):
94 if listBox
.IsChecked(i
):
95 value
.append(self
.values
[i
])
98 self
.SetValue('|'.join(value
))
102 class ParamFlag(ParamBinaryOr
):
103 values
= ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL',
104 'wxEXPAND', 'wxGROW', 'wxSHAPED', 'wxSTRETCH_NOT',
105 'wxALIGN_CENTRE', 'wxALIGN_LEFT', 'wxALIGN_RIGHT',
106 'wxALIGN_TOP', 'wxALIGN_BOTTOM',
107 'wxALIGN_CENTRE_VERTICAL', 'wxALIGN_CENTRE_HORIZONTAL',
108 'wxADJUST_MINSIZE', 'wxFIXED_MINSIZE'
110 equal
= {'wxALIGN_CENTER': 'wxALIGN_CENTRE',
111 'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL',
112 'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL',
113 'wxUP': 'wxTOP', 'wxDOWN': 'wxBOTTOM', 'wxNORTH': 'wxTOP',
114 'wxSOUTH': 'wxBOTTOM', 'wxWEST': 'wxLEFT', 'wxEAST': 'wxRIGHT'}
115 def __init__(self
, parent
, name
):
116 ParamBinaryOr
.__init
__(self
, parent
, name
)
118 class ParamNonGenericStyle(ParamBinaryOr
):
119 def __init__(self
, parent
, name
):
120 self
.values
= g
.currentXXX
.winStyles
121 ParamBinaryOr
.__init
__(self
, parent
, name
)
123 class ParamStyle(ParamBinaryOr
):
124 equal
= {'wxALIGN_CENTER': 'wxALIGN_CENTRE'}
125 def __init__(self
, parent
, name
):
126 ParamBinaryOr
.__init
__(self
, parent
, name
)
127 self
.valuesSpecific
= g
.currentXXX
.winStyles
128 if self
.valuesSpecific
: # override if using specific styles
130 self
.valuesGeneric
= [s
for s
in genericStyles
131 if s
not in self
.valuesSpecific
]
132 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_CHOICES
, self
.OnButtonChoicesBoth
)
134 self
.values
= genericStyles
135 def OnButtonChoicesBoth(self
, evt
):
136 dlg
= g
.frame
.res
.LoadDialog(self
, 'DIALOG_STYLES')
137 listBoxSpecific
= xrc
.XRCCTRL(dlg
, 'CHECKLIST_SPECIFIC')
138 listBoxSpecific
.InsertItems(self
.valuesSpecific
, 0)
139 listBoxGeneric
= xrc
.XRCCTRL(dlg
, 'CHECKLIST_GENERIC')
140 listBoxGeneric
.InsertItems(self
.valuesGeneric
, 0)
141 value
= map(string
.strip
, self
.text
.GetValue().split('|'))
142 if value
== ['']: value
= []
143 # Set specific styles
144 value2
= [] # collect generic and ignored here
147 listBoxSpecific
.Check(self
.valuesSpecific
.index(i
))
150 if self
.equal
.has_key(i
):
151 listBoxSpecific
.Check(self
.valuesSpecific
.index(self
.equal
[i
]))
155 # Set generic styles, collect non-standart values
158 listBoxGeneric
.Check(self
.valuesGeneric
.index(i
))
161 if self
.equal
.has_key(i
):
162 listBoxGeneric
.Check(self
.valuesGeneric
.index(self
.equal
[i
]))
164 print 'WARNING: unknown flag: %s: ignored.' % i
166 if dlg
.ShowModal() == wx
.ID_OK
:
167 value
= [self
.valuesSpecific
[i
]
168 for i
in range(listBoxSpecific
.GetCount())
169 if listBoxSpecific
.IsChecked(i
)] + \
170 [self
.valuesGeneric
[i
]
171 for i
in range(listBoxGeneric
.GetCount())
172 if listBoxGeneric
.IsChecked(i
)] + ignored
173 self
.SetValue('|'.join(value
))
177 class ParamExStyle(ParamBinaryOr
):
178 def __init__(self
, parent
, name
):
180 self
.values
= g
.currentXXX
.exStyles
+ genericExStyles
183 ParamBinaryOr
.__init
__(self
, parent
, name
)
185 class ParamColour(PPanel
):
186 def __init__(self
, parent
, name
):
187 PPanel
.__init
__(self
, parent
, name
)
188 self
.ID_TEXT_CTRL
= wx
.NewId()
189 self
.ID_BUTTON
= wx
.NewId()
190 sizer
= wx
.BoxSizer()
191 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(80,-1))
192 sizer
.Add(self
.text
, 0, wx
.ALIGN_CENTER_VERTICAL | wx
.TOP | wx
.BOTTOM
, 2)
193 self
.button
= wx
.Panel(self
, self
.ID_BUTTON
, wx
.DefaultPosition
, wx
.Size(20, 20))
194 sizer
.Add(self
.button
, 0, wx
.ALIGN_CENTER_VERTICAL | wx
.LEFT
, 5)
196 self
.textModified
= False
197 wx
.EVT_PAINT(self
.button
, self
.OnPaintButton
)
198 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
199 wx
.EVT_LEFT_DOWN(self
.button
, self
.OnLeftDown
)
201 return self
.text
.GetValue()
202 def SetValue(self
, value
):
204 if not value
: value
= '#FFFFFF'
205 self
.text
.SetValue(str(value
)) # update text ctrl
207 colour
= wx
.Colour(int(value
[1:3], 16), int(value
[3:5], 16), int(value
[5:7], 16))
208 self
.button
.SetBackgroundColour(colour
)
209 except: # ignore errors
211 self
.button
.Refresh()
213 def OnPaintButton(self
, evt
):
214 dc
= wx
.PaintDC(self
.button
)
215 dc
.SetBrush(wx
.TRANSPARENT_BRUSH
)
216 if self
.IsEnabled(): dc
.SetPen(wx
.BLACK_PEN
)
217 else: dc
.SetPen(wx
.GREY_PEN
)
218 size
= self
.button
.GetSize()
219 dc
.DrawRectangle(0, 0, size
.width
, size
.height
)
220 def OnLeftDown(self
, evt
):
221 data
= wx
.ColourData()
222 data
.SetColour(self
.GetValue())
223 dlg
= wx
.ColourDialog(self
, data
)
224 if dlg
.ShowModal() == wx
.ID_OK
:
225 self
.SetValue('#%02X%02X%02X' % dlg
.GetColourData().GetColour().Get())
229 ################################################################################
231 # Mapping from wx constants to XML strings
232 fontFamiliesWx2Xml
= {wx
.DEFAULT
: 'default', wx
.DECORATIVE
: 'decorative',
233 wx
.ROMAN
: 'roman', wx
.SCRIPT
: 'script', wx
.SWISS
: 'swiss',
235 fontStylesWx2Xml
= {wx.NORMAL: 'normal', wx.SLANT: 'slant', wx.ITALIC: 'italic'}
236 fontWeightsWx2Xml
= {wx.NORMAL: 'normal', wx.LIGHT: 'light', wx.BOLD: 'bold'}
239 for k
,v
in m
.items(): rm
[v
] = k
241 fontFamiliesXml2wx
= ReverseMap(fontFamiliesWx2Xml
)
242 fontStylesXml2wx
= ReverseMap(fontStylesWx2Xml
)
243 fontWeightsXml2wx
= ReverseMap(fontWeightsWx2Xml
)
245 class ParamFont(PPanel
):
246 def __init__(self
, parent
, name
):
247 PPanel
.__init
__(self
, parent
, name
)
248 self
.ID_TEXT_CTRL
= wx
.NewId()
249 self
.ID_BUTTON_SELECT
= wx
.NewId()
250 sizer
= wx
.BoxSizer()
251 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(200,-1))
252 sizer
.Add(self
.text
, 0, wx
.RIGHT | wx
.ALIGN_CENTER_VERTICAL
, 5)
253 self
.button
= wx
.Button(self
, self
.ID_BUTTON_SELECT
, 'Select...', size
=buttonSize
)
254 sizer
.Add(self
.button
, 0, wx
.ALIGN_CENTER_VERTICAL
)
256 self
.textModified
= False
257 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_SELECT
, self
.OnButtonSelect
)
258 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
259 def OnChange(self
, evt
):
260 PPanel
.OnChange(self
, evt
)
261 self
.textModified
= True
262 def _defaultValue(self
):
263 return [`g
._sysFont
.GetPointSize()`
, 'default', 'normal', 'normal', '0', '', '']
265 if self
.textModified
: # text has newer value
267 return eval(self
.text
.GetValue())
269 wx
.LogError('Syntax error in parameter value: ' + self
.GetName())
270 return self
._defaultValue
()
272 def SetValue(self
, value
):
273 self
.freeze
= True # disable other handlers
274 if not value
: value
= self
._defaultValue
()
276 self
.text
.SetValue(str(value
)) # update text ctrl
278 def OnButtonSelect(self
, evt
):
279 if self
.textModified
: # text has newer value
281 self
.value
= eval(self
.text
.GetValue())
283 wx
.LogError('Syntax error in parameter value: ' + self
.GetName())
284 self
.value
= self
._defaultValue
()
287 size
= g
._sysFont
.GetPointSize()
289 style
= weight
= wx
.NORMAL
292 enc
= wx
.FONTENCODING_DEFAULT
293 # Fall back to default if exceptions
296 try: size
= int(self
.value
[0])
297 except ValueError: error
= True; wx
.LogError('Invalid size specification')
298 try: family
= fontFamiliesXml2wx
[self
.value
[1]]
299 except KeyError: error
= True; wx
.LogError('Invalid family specification')
300 try: style
= fontStylesXml2wx
[self
.value
[2]]
301 except KeyError: error
= True; wx
.LogError('Invalid style specification')
302 try: weight
= fontWeightsXml2wx
[self
.value
[3]]
303 except KeyError: error
= True; wx
.LogError('Invalid weight specification')
304 try: underlined
= bool(self
.value
[4])
305 except ValueError: error
= True; wx
.LogError('Invalid underlined flag specification')
309 mapper
= wx
.FontMapper()
310 if not self
.value
[6]: enc
= mapper
.CharsetToEncoding(self
.value
[6])
312 if error
: wx
.LogError('Invalid font specification')
313 if enc
== wx
.FONTENCODING_DEFAULT
: enc
= wx
.FONTENCODING_SYSTEM
314 font
= wx
.Font(size
, family
, style
, weight
, underlined
, face
, enc
)
316 data
.SetInitialFont(font
)
317 dlg
= wx
.FontDialog(self
, data
)
318 if dlg
.ShowModal() == wx
.ID_OK
:
319 font
= dlg
.GetFontData().GetChosenFont()
320 if font
.GetEncoding() == wx
.FONTENCODING_SYSTEM
:
323 encName
= wx
.FontMapper
.GetEncodingName(font
.GetEncoding()).encode()
324 value
= [str(font
.GetPointSize()),
325 fontFamiliesWx2Xml
.get(font
.GetFamily(), "default"),
326 fontStylesWx2Xml
.get(font
.GetStyle(), "normal"),
327 fontWeightsWx2Xml
.get(font
.GetWeight(), "normal"),
328 str(int(font
.GetUnderlined())),
329 font
.GetFaceName().encode(),
334 self
.textModified
= False
337 ################################################################################
339 class ParamInt(PPanel
):
340 def __init__(self
, parent
, name
):
341 PPanel
.__init
__(self
, parent
, name
)
342 self
.ID_SPIN_CTRL
= wx
.NewId()
343 sizer
= wx
.BoxSizer()
344 self
.spin
= wx
.SpinCtrl(self
, self
.ID_SPIN_CTRL
, size
=(60,-1))
345 self
.spin
.SetRange(-2147483648, 2147483647) # min/max integers
348 wx
.EVT_SPINCTRL(self
, self
.ID_SPIN_CTRL
, self
.OnChange
)
350 return str(self
.spin
.GetValue())
351 def SetValue(self
, value
):
353 if not value
: value
= 0
354 self
.spin
.SetValue(int(value
))
357 # Non-negative number
358 class ParamIntNN(PPanel
):
359 def __init__(self
, parent
, name
):
360 PPanel
.__init
__(self
, parent
, name
)
361 self
.ID_SPIN_CTRL
= wx
.NewId()
362 sizer
= wx
.BoxSizer()
363 self
.spin
= wx
.SpinCtrl(self
, self
.ID_SPIN_CTRL
, size
=(60,-1))
364 self
.spin
.SetRange(0, 10000) # min/max integers
367 wx
.EVT_SPINCTRL(self
, self
.ID_SPIN_CTRL
, self
.OnChange
)
369 return str(self
.spin
.GetValue())
370 def SetValue(self
, value
):
372 if not value
: value
= 0
373 self
.spin
.SetValue(int(value
))
376 # Same as int but allows dialog units (XXXd)
377 class ParamUnit(PPanel
):
378 def __init__(self
, parent
, name
):
379 PPanel
.__init
__(self
, parent
, name
)
380 self
.ID_TEXT_CTRL
= wx
.NewId()
381 self
.ID_SPIN_BUTTON
= wx
.NewId()
382 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
383 self
.spin
= wx
.SpinButton(self
, self
.ID_SPIN_BUTTON
, style
= wx
.SP_VERTICAL
, size
=(-1,0))
384 textW
= 60 - self
.spin
.GetSize()[0]
385 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(textW
,-1))
386 self
.spin
.SetRange(-10000, 10000)
387 sizer
.Add(self
.text
, 0, wx
.EXPAND
)
388 sizer
.Add(self
.spin
, 0, wx
.EXPAND
)
390 self
.spin
.Bind(wx
.EVT_SPIN_UP
, self
.OnSpinUp
)
391 self
.spin
.Bind(wx
.EVT_SPIN_DOWN
, self
.OnSpinDown
)
393 return self
.text
.GetValue()
394 def SetValue(self
, value
):
395 if not value
: value
= '0'
396 self
.text
.SetValue(value
)
400 # Check if we are working with dialog units
401 value
= self
.text
.GetValue()
403 if value
[-1].upper() == 'D':
407 intValue
= int(value
) + x
408 self
.spin
.SetValue(intValue
)
409 if x
: # 0 can be passed to update spin value only
410 self
.text
.SetValue(str(intValue
) + units
)
413 # !!! Strange, if I use wx.LogWarning, event is re-generated
414 print 'ERROR: incorrect unit format'
416 def OnSpinUp(self
, evt
):
419 def OnSpinDown(self
, evt
):
420 if self
.freeze
: return
424 class ParamMultilineText(PPanel
):
425 def __init__(self
, parent
, name
, textWidth
=-1):
426 PPanel
.__init
__(self
, parent
, name
)
427 self
.ID_TEXT_CTRL
= wx
.NewId()
428 self
.ID_BUTTON_EDIT
= wx
.NewId()
429 sizer
= wx
.BoxSizer()
430 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wx
.Size(200,-1))
431 sizer
.Add(self
.text
, 0, wx
.RIGHT | wx
.ALIGN_CENTER_VERTICAL
, 5)
432 self
.button
= wx
.Button(self
, self
.ID_BUTTON_EDIT
, 'Edit...', size
=buttonSize
)
433 sizer
.Add(self
.button
, 0, wx
.ALIGN_CENTER_VERTICAL
)
434 self
.SetSizerAndFit(sizer
)
435 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_EDIT
, self
.OnButtonEdit
)
436 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
438 return self
.text
.GetValue()
439 def SetValue(self
, value
):
440 self
.freeze
= True # disable other handlers
441 self
.text
.SetValue(value
)
442 self
.freeze
= False # disable other handlers
443 def OnButtonEdit(self
, evt
):
444 dlg
= g
.frame
.res
.LoadDialog(self
, 'DIALOG_TEXT')
445 textCtrl
= xrc
.XRCCTRL(dlg
, 'TEXT')
446 textCtrl
.SetValue(self
.text
.GetValue())
447 if dlg
.ShowModal() == wx
.ID_OK
:
448 self
.text
.SetValue(textCtrl
.GetValue())
452 class ParamText(PPanel
):
453 def __init__(self
, parent
, name
, textWidth
=-1, style
=0):
454 PPanel
.__init
__(self
, parent
, name
)
455 self
.ID_TEXT_CTRL
= wx
.NewId()
456 # We use sizer even here to have the same size of text control
457 sizer
= wx
.BoxSizer()
458 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wx
.Size(textWidth
,-1), style
=style
)
459 if textWidth
== -1: option
= 1
461 sizer
.Add(self
.text
, option
, wx
.ALIGN_CENTER_VERTICAL | wx
.TOP | wx
.BOTTOM
, 2)
463 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
465 return self
.text
.GetValue()
466 def SetValue(self
, value
):
467 self
.freeze
= True # disable other handlers
468 self
.text
.SetValue(value
)
469 self
.freeze
= False # disable other handlers
471 class ParamAccel(ParamText
):
472 def __init__(self
, parent
, name
):
473 ParamText
.__init
__(self
, parent
, name
, 100)
475 class ParamPosSize(ParamText
):
476 def __init__(self
, parent
, name
):
477 ParamText
.__init
__(self
, parent
, name
, 80)
479 class ParamLabel(ParamText
):
480 def __init__(self
, parent
, name
):
481 ParamText
.__init
__(self
, parent
, name
, 200)
483 class ParamEncoding(ParamText
):
484 def __init__(self
, parent
, name
):
485 ParamText
.__init
__(self
, parent
, name
, 100)
487 class ParamComment(ParamText
):
488 def __init__(self
, parent
, name
):
489 ParamText
.__init
__(self
, parent
, name
, 330 + buttonSize
[0],
490 style
=wx
.TE_PROCESS_ENTER
)
492 class ContentDialog(wx
.Dialog
):
493 def __init__(self
, parent
, value
):
496 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_CONTENT')
498 self
.list = xrc
.XRCCTRL(self
, 'LIST')
502 self
.SetAutoLayout(True)
503 self
.GetSizer().Fit(self
)
505 self
.ID_BUTTON_APPEND
= xrc
.XRCID('BUTTON_APPEND')
506 self
.ID_BUTTON_REMOVE
= xrc
.XRCID('BUTTON_REMOVE')
507 self
.ID_BUTTON_UP
= xrc
.XRCID('BUTTON_UP')
508 self
.ID_BUTTON_DOWN
= xrc
.XRCID('BUTTON_DOWN')
509 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_UP
, self
.OnButtonUp
)
510 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_DOWN
, self
.OnButtonDown
)
511 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_APPEND
, self
.OnButtonAppend
)
512 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
513 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_UP
, self
.OnUpdateUI
)
514 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_DOWN
, self
.OnUpdateUI
)
515 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
516 def OnButtonUp(self
, evt
):
517 i
= self
.list.GetSelection()
518 str = self
.list.GetString(i
)
520 self
.list.InsertItems([str], i
-1)
521 self
.list.SetSelection(i
-1)
522 def OnButtonDown(self
, evt
):
523 i
= self
.list.GetSelection()
524 str = self
.list.GetString(i
)
526 self
.list.InsertItems([str], i
+1)
527 self
.list.SetSelection(i
+1)
528 def OnButtonAppend(self
, evt
):
529 str = wx
.GetTextFromUser('Enter new item:', 'Append', '', self
)
530 self
.list.Append(str)
531 def OnButtonRemove(self
, evt
):
532 self
.list.Delete(self
.list.GetSelection())
533 def OnUpdateUI(self
, evt
):
534 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
535 evt
.Enable(self
.list.GetSelection() != -1)
536 elif evt
.GetId() == self
.ID_BUTTON_UP
:
537 evt
.Enable(self
.list.GetSelection() > 0)
538 elif evt
.GetId() == self
.ID_BUTTON_DOWN
:
539 evt
.Enable(self
.list.GetSelection() != -1 and \
540 self
.list.GetSelection() < self
.list.GetCount() - 1)
542 class ContentCheckListDialog(wx
.Dialog
):
543 def __init__(self
, parent
, value
):
545 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_CONTENT_CHECKLIST')
547 self
.list = xrc
.XRCCTRL(self
, 'CHECK_LIST')
552 self
.list.Check(i
, ch
)
554 self
.SetAutoLayout(True)
555 self
.GetSizer().Fit(self
)
557 self
.ID_BUTTON_APPEND
= xrc
.XRCID('BUTTON_APPEND')
558 self
.ID_BUTTON_REMOVE
= xrc
.XRCID('BUTTON_REMOVE')
559 self
.ID_BUTTON_UP
= xrc
.XRCID('BUTTON_UP')
560 self
.ID_BUTTON_DOWN
= xrc
.XRCID('BUTTON_DOWN')
561 wx
.EVT_CHECKLISTBOX(self
, self
.list.GetId(), self
.OnCheck
)
562 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_UP
, self
.OnButtonUp
)
563 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_DOWN
, self
.OnButtonDown
)
564 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_APPEND
, self
.OnButtonAppend
)
565 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
566 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_UP
, self
.OnUpdateUI
)
567 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_DOWN
, self
.OnUpdateUI
)
568 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
569 def OnCheck(self
, evt
):
570 # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking
571 self
.list.Deselect(evt
.GetSelection())
572 def OnButtonUp(self
, evt
):
573 i
= self
.list.GetSelection()
574 str, ch
= self
.list.GetString(i
), self
.list.IsChecked(i
)
576 self
.list.InsertItems([str], i
-1)
577 self
.list.Check(i
-1, ch
)
578 self
.list.SetSelection(i
-1)
579 def OnButtonDown(self
, evt
):
580 i
= self
.list.GetSelection()
581 str, ch
= self
.list.GetString(i
), self
.list.IsChecked(i
)
583 self
.list.InsertItems([str], i
+1)
584 self
.list.Check(i
+1, ch
)
585 self
.list.SetSelection(i
+1)
586 def OnButtonAppend(self
, evt
):
587 str = wx
.GetTextFromUser('Enter new item:', 'Append', '', self
)
588 self
.list.Append(str)
589 def OnButtonRemove(self
, evt
):
590 self
.list.Delete(self
.list.GetSelection())
591 def OnUpdateUI(self
, evt
):
592 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
593 evt
.Enable(self
.list.GetSelection() != -1)
594 elif evt
.GetId() == self
.ID_BUTTON_UP
:
595 evt
.Enable(self
.list.GetSelection() > 0)
596 elif evt
.GetId() == self
.ID_BUTTON_DOWN
:
597 evt
.Enable(self
.list.GetSelection() != -1 and \
598 self
.list.GetSelection() < self
.list.GetCount() - 1)
600 class ParamContent(PPanel
):
601 def __init__(self
, parent
, name
):
602 PPanel
.__init
__(self
, parent
, name
)
603 self
.ID_TEXT_CTRL
= wx
.NewId()
604 self
.ID_BUTTON_EDIT
= wx
.NewId()
605 sizer
= wx
.BoxSizer()
606 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wx
.Size(200,-1))
607 sizer
.Add(self
.text
, 0, wx
.RIGHT | wx
.ALIGN_CENTER_VERTICAL
, 5)
608 self
.button
= wx
.Button(self
, self
.ID_BUTTON_EDIT
, 'Edit...', size
=buttonSize
)
609 sizer
.Add(self
.button
, 0, wx
.ALIGN_CENTER_VERTICAL
)
611 self
.textModified
= False
612 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_EDIT
, self
.OnButtonEdit
)
613 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
614 def OnChange(self
, evt
):
615 PPanel
.OnChange(self
, evt
)
616 self
.textModified
= True
618 if self
.textModified
: # text has newer value
620 return self
.text
.GetValue().split('|')
624 def SetValue(self
, value
):
626 if not value
: value
= []
628 repr_
= '|'.join(map(str, value
))
629 self
.text
.SetValue(repr_
) # update text ctrl
631 def OnButtonEdit(self
, evt
):
632 if self
.textModified
: # text has newer value
633 self
.value
= self
.GetValue()
634 dlg
= ContentDialog(self
, self
.value
)
635 if dlg
.ShowModal() == wx
.ID_OK
:
637 for i
in range(dlg
.list.GetCount()):
638 value
.append(dlg
.list.GetString(i
))
641 self
.textModified
= False
643 def SetModified(self
, state
=True):
644 PPanel
.SetModified(self
, state
)
645 self
.textModified
= False
648 class ParamContentCheckList(ParamContent
):
649 def __init__(self
, parent
, name
):
650 ParamContent
.__init
__(self
, parent
, name
)
651 def OnButtonEdit(self
, evt
):
652 if self
.textModified
: # text has newer value
653 self
.value
= self
.GetValue()
654 dlg
= ContentCheckListDialog(self
, self
.value
)
655 if dlg
.ShowModal() == wx
.ID_OK
:
657 for i
in range(dlg
.list.GetCount()):
658 value
.append((dlg
.list.GetString(i
), int(dlg
.list.IsChecked(i
))))
661 self
.textModified
= False
663 def SetValue(self
, value
):
665 if not value
: value
= []
667 repr_
= '|'.join(map(str,value
))
668 self
.text
.SetValue(repr_
) # update text ctrl
671 class IntListDialog(wx
.Dialog
):
672 def __init__(self
, parent
, value
):
674 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_INTLIST')
676 self
.list = xrc
.XRCCTRL(self
, 'LIST')
680 if type(v
) != IntType
:
681 wx
.LogError('Invalid item type')
683 self
.list.Append(str(v
))
684 self
.SetAutoLayout(True)
685 self
.GetSizer().Fit(self
)
687 self
.spinCtrl
= xrc
.XRCCTRL(self
, 'SPIN')
688 wx
.EVT_BUTTON(self
, xrc
.XRCID('BUTTON_ADD'), self
.OnButtonAdd
)
689 self
.ID_BUTTON_REMOVE
= xrc
.XRCID('BUTTON_REMOVE')
690 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
691 wx
.EVT_BUTTON(self
, xrc
.XRCID('BUTTON_CLEAR'), self
.OnButtonClear
)
692 wx
.EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
693 def OnButtonAdd(self
, evt
):
694 # Check that it's unique
696 v
= self
.spinCtrl
.GetValue()
697 s
= str(v
) # to be sure
698 i
= self
.list.FindString(s
)
699 if i
== -1: # ignore non-unique
700 # Find place to insert
702 for i
in range(self
.list.GetCount()):
703 if int(self
.list.GetString(i
)) > v
:
706 if found
: self
.list.InsertItems([s
], i
)
707 else: self
.list.Append(s
)
709 wx
.LogError('List item is not an int!')
710 def OnButtonRemove(self
, evt
):
711 self
.list.Delete(self
.list.GetSelection())
712 def OnButtonClear(self
, evt
):
714 def OnUpdateUI(self
, evt
):
715 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
716 evt
.Enable(self
.list.GetSelection() != -1)
719 class ParamIntList(ParamContent
):
720 def __init__(self
, parent
, name
):
721 ParamContent
.__init
__(self
, parent
, name
)
722 def OnButtonEdit(self
, evt
):
723 if self
.textModified
: # text has newer value
725 self
.value
= map(int, self
.text
.GetValue().split('|'))
728 dlg
= IntListDialog(self
, self
.value
)
729 if dlg
.ShowModal() == wx
.ID_OK
:
731 for i
in range(dlg
.list.GetCount()):
732 value
.append(int(dlg
.list.GetString(i
)))
735 self
.textModified
= False
739 class RadioBox(PPanel
):
740 def __init__(self
, parent
, id, choices
,
741 pos
=wx
.DefaultPosition
, name
='radiobox'):
742 PPanel
.__init
__(self
, parent
, name
)
743 self
.choices
= choices
744 topSizer
= wx
.BoxSizer()
746 button
= wx
.RadioButton(self
, -1, i
, size
=(-1,buttonSize
[1]), name
=i
)
747 topSizer
.Add(button
, 0, wx
.RIGHT
, 5)
748 wx
.EVT_RADIOBUTTON(self
, button
.GetId(), self
.OnRadioChoice
)
749 self
.SetSizer(topSizer
)
750 def SetStringSelection(self
, value
):
752 for i
in self
.choices
:
753 self
.FindWindowByName(i
).SetValue(i
== value
)
756 def OnRadioChoice(self
, evt
):
757 if self
.freeze
: return
758 if evt
.GetSelection():
759 self
.value
= evt
.GetEventObject().GetName()
761 def GetStringSelection(self
):
764 class ParamBool(RadioBox
):
765 values
= {'yes': '1', 'no': '0'}
766 seulav
= {'1': 'yes', '0': 'no'}
767 def __init__(self
, parent
, name
):
768 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
770 return self
.values
[self
.GetStringSelection()]
771 def SetValue(self
, value
):
772 if not value
: value
= '1'
773 self
.SetStringSelection(self
.seulav
[value
])
775 class ParamOrient(RadioBox
):
776 values
= {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
777 seulav
= {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'}
778 def __init__(self
, parent
, name
):
779 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
781 return self
.values
[self
.GetStringSelection()]
782 def SetValue(self
, value
):
783 if not value
: value
= 'wxHORIZONTAL'
784 self
.SetStringSelection(self
.seulav
[value
])
786 class ParamOrientation(RadioBox
):
787 values
= {'horizontal': 'horizontal', 'vertical': 'vertical'}
788 seulav
= {'horizontal': 'horizontal', 'vertical': 'vertical'}
789 def __init__(self
, parent
, name
):
790 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
792 return self
.values
[self
.GetStringSelection()]
793 def SetValue(self
, value
):
794 if not value
: value
= 'vertical'
795 self
.SetStringSelection(self
.seulav
[value
])
797 class ParamFile(PPanel
):
798 def __init__(self
, parent
, name
):
799 PPanel
.__init
__(self
, parent
, name
)
800 self
.ID_TEXT_CTRL
= wx
.NewId()
801 self
.ID_BUTTON_BROWSE
= wx
.NewId()
802 sizer
= wx
.BoxSizer()
803 self
.text
= wx
.TextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wx
.Size(200,-1))
804 sizer
.Add(self
.text
, 0, wx
.RIGHT | wx
.ALIGN_CENTER_VERTICAL
, 5)
805 self
.button
= wx
.Button(self
, self
.ID_BUTTON_BROWSE
, 'Browse...',size
=buttonSize
)
806 sizer
.Add(self
.button
, 0, wx
.ALIGN_CENTER_VERTICAL
)
808 self
.textModified
= False
809 wx
.EVT_BUTTON(self
, self
.ID_BUTTON_BROWSE
, self
.OnButtonBrowse
)
810 wx
.EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
811 def OnChange(self
, evt
):
812 PPanel
.OnChange(self
, evt
)
813 self
.textModified
= True
815 if self
.textModified
: # text has newer value
816 return self
.text
.GetValue()
818 def SetValue(self
, value
):
821 self
.text
.SetValue(value
) # update text ctrl
823 def OnButtonBrowse(self
, evt
):
824 if self
.textModified
: # text has newer value
825 self
.value
= self
.text
.GetValue()
826 dlg
= wx
.FileDialog(self
,
827 defaultDir
= os
.path
.abspath(os
.path
.dirname(self
.value
)),
828 defaultFile
= os
.path
.basename(self
.value
))
829 if dlg
.ShowModal() == wx
.ID_OK
:
830 # Get common part of selected path and current
832 curpath
= os
.path
.abspath(g
.frame
.dataFile
)
834 curpath
= os
.path
.join(os
.getcwd(), '')
835 common
= os
.path
.commonprefix([curpath
, dlg
.GetPath()])
836 self
.SetValue(dlg
.GetPath()[len(common
):])
838 self
.textModified
= False
841 class ParamBitmap(PPanel
):
842 def __init__(self
, parent
, name
):
844 g
.frame
.res
.LoadOnPanel(pre
, parent
, 'PANEL_BITMAP')
846 self
.modified
= self
.freeze
= False
847 self
.radio_std
= xrc
.XRCCTRL(self
, 'RADIO_STD')
848 self
.radio_file
= xrc
.XRCCTRL(self
, 'RADIO_FILE')
849 self
.combo
= xrc
.XRCCTRL(self
, 'COMBO_STD')
850 self
.text
= xrc
.XRCCTRL(self
, 'TEXT_FILE')
851 self
.button
= xrc
.XRCCTRL(self
, 'BUTTON_BROWSE')
852 self
.textModified
= False
853 self
.SetAutoLayout(True)
854 self
.GetSizer().SetMinSize((260, -1))
855 self
.GetSizer().Fit(self
)
856 wx
.EVT_RADIOBUTTON(self
, xrc
.XRCID('RADIO_STD'), self
.OnRadioStd
)
857 wx
.EVT_RADIOBUTTON(self
, xrc
.XRCID('RADIO_FILE'), self
.OnRadioFile
)
858 wx
.EVT_BUTTON(self
, xrc
.XRCID('BUTTON_BROWSE'), self
.OnButtonBrowse
)
859 wx
.EVT_COMBOBOX(self
, xrc
.XRCID('COMBO_STD'), self
.OnCombo
)
860 wx
.EVT_TEXT(self
, xrc
.XRCID('COMBO_STD'), self
.OnChange
)
861 wx
.EVT_TEXT(self
, xrc
.XRCID('TEXT_FILE'), self
.OnChange
)
862 def OnRadioStd(self
, evt
):
864 self
.SetValue(['wxART_MISSING_IMAGE',''])
865 def OnRadioFile(self
, evt
):
867 self
.SetValue(['',''])
868 def updateRadios(self
):
870 self
.radio_std
.SetValue(True)
871 self
.radio_file
.SetValue(False)
872 self
.text
.Enable(False)
873 self
.button
.Enable(False)
874 self
.combo
.Enable(True)
876 self
.radio_std
.SetValue(False)
877 self
.radio_file
.SetValue(True)
878 self
.text
.Enable(True)
879 self
.button
.Enable(True)
880 self
.combo
.Enable(False)
881 def OnChange(self
, evt
):
882 PPanel
.OnChange(self
, evt
)
883 self
.textModified
= True
884 def OnCombo(self
, evt
):
885 PPanel
.OnChange(self
, evt
)
886 self
.value
[0] = self
.combo
.GetValue()
888 if self
.textModified
: # text has newer value
889 return [self
.combo
.GetValue(), self
.text
.GetValue()]
891 def SetValue(self
, value
):
894 self
.value
= ['', '']
897 self
.combo
.SetValue(self
.value
[0])
898 self
.text
.SetValue(self
.value
[1]) # update text ctrl
901 def OnButtonBrowse(self
, evt
):
902 if self
.textModified
: # text has newer value
903 self
.value
[1] = self
.text
.GetValue()
904 dlg
= wx
.FileDialog(self
,
905 defaultDir
= os
.path
.abspath(os
.path
.dirname(self
.value
[1])),
906 defaultFile
= os
.path
.basename(self
.value
[1]))
907 if dlg
.ShowModal() == wx
.ID_OK
:
908 # Get common part of selected path and current
910 curpath
= os
.path
.abspath(g
.frame
.dataFile
)
912 curpath
= os
.path
.join(os
.getcwd(), '')
913 common
= os
.path
.commonprefix([curpath
, dlg
.GetPath()])
914 self
.SetValue(['', dlg
.GetPath()[len(common
):]])
916 self
.textModified
= False
921 'style': ParamStyle
, 'exstyle': ParamExStyle
,
922 'pos': ParamPosSize
, 'size': ParamPosSize
,
923 'cellpos': ParamPosSize
, 'cellspan': ParamPosSize
,
924 'border': ParamUnit
, 'cols': ParamIntNN
, 'rows': ParamIntNN
,
925 'vgap': ParamUnit
, 'hgap': ParamUnit
,
926 'checkable': ParamBool
, 'checked': ParamBool
, 'radio': ParamBool
,
928 'label': ParamMultilineText
, 'title': ParamText
, 'value': ParamText
,
929 'content': ParamContent
, 'selection': ParamIntNN
,
930 'min': ParamInt
, 'max': ParamInt
,
931 'fg': ParamColour
, 'bg': ParamColour
, 'font': ParamFont
,
932 'enabled': ParamBool
, 'focused': ParamBool
, 'hidden': ParamBool
,
933 'tooltip': ParamText
, 'bitmap': ParamBitmap
, 'icon': ParamBitmap
,
934 'encoding': ParamEncoding
, 'borders': ParamUnit
,
935 'comment': ParamComment