2 # Purpose: Classes for parameter introduction
3 # Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
11 from wxPython
.xrc
import *
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'
21 'wxWS_EX_VALIDATE_RECURSIVELY',
22 'wxWS_EX_BLOCK_EVENTS',
24 'wxFRAME_EX_CONTEXTHELP',
25 'wxWS_EX_PROCESS_IDLE',
26 'wxWS_EX_PROCESS_UI_UPDATES'
29 buttonSize
= (35,-1) # in dialog units, transformed to pixels in panel ctor
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():
40 #wxPanel.Enable(self, value)
41 def SetModified(self
):
43 g
.panel
.SetModified(True)
44 # Common method to set modified state
45 def OnChange(self
, evt
):
46 if self
.freeze
: return
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()
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)
63 EVT_BUTTON(self
, self
.ID_BUTTON_CHOICES
, self
.OnButtonChoices
)
64 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
= 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() == wxID_OK
:
93 for i
in range(listBox
.GetCount()):
94 if listBox
.IsChecked(i
):
95 value
.append(self
.values
[i
])
99 self
.SetValue(reduce(lambda a
,b
: a
+'|'+b
, value
))
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'
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
)
121 class ParamNonGenericStyle(ParamBinaryOr
):
122 def __init__(self
, parent
, name
):
123 self
.values
= g
.currentXXX
.winStyles
124 ParamBinaryOr
.__init
__(self
, parent
, name
)
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
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
)
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
150 listBoxSpecific
.Check(self
.valuesSpecific
.index(i
))
153 if self
.equal
.has_key(i
):
154 listBoxSpecific
.Check(self
.valuesSpecific
.index(self
.equal
[i
]))
158 # Set generic styles, collect non-standart values
161 listBoxGeneric
.Check(self
.valuesGeneric
.index(i
))
164 if self
.equal
.has_key(i
):
165 listBoxGeneric
.Check(self
.valuesGeneric
.index(self
.equal
[i
]))
167 print 'WARNING: unknown flag: %s: ignored.' % 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
177 self
.SetValue(reduce(lambda a
,b
: a
+'|'+b
, value
))
183 class ParamExStyle(ParamBinaryOr
):
184 def __init__(self
, parent
, name
):
186 self
.values
= g
.currentXXX
.exStyles
+ genericExStyles
189 ParamBinaryOr
.__init
__(self
, parent
, name
)
191 class ParamColour(PPanel
):
192 def __init__(self
, parent
, name
):
193 PPanel
.__init
__(self
, parent
, name
)
194 self
.ID_TEXT_CTRL
= wxNewId()
195 self
.ID_BUTTON
= wxNewId()
197 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(80,-1))
198 sizer
.Add(self
.text
, 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM
, 2)
199 self
.button
= wxPanel(self
, self
.ID_BUTTON
, wxDefaultPosition
, wxSize(20, 20))
200 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL | wxLEFT
, 5)
201 self
.SetAutoLayout(True)
204 self
.textModified
= False
205 EVT_PAINT(self
.button
, self
.OnPaintButton
)
206 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
207 EVT_LEFT_DOWN(self
.button
, self
.OnLeftDown
)
209 return self
.text
.GetValue()
210 def SetValue(self
, value
):
212 if not value
: value
= '#FFFFFF'
213 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 except: # ignore errors
219 self
.button
.Refresh()
221 def OnPaintButton(self
, evt
):
222 dc
= wxPaintDC(self
.button
)
223 dc
.SetBrush(wxTRANSPARENT_BRUSH
)
224 if self
.IsEnabled(): dc
.SetPen(wxBLACK_PEN
)
225 else: dc
.SetPen(wxGREY_PEN
)
226 size
= self
.button
.GetSize()
227 dc
.DrawRectangle(0, 0, size
.width
, size
.height
)
228 def OnLeftDown(self
, evt
):
229 data
= wxColourData()
230 data
.SetColour(self
.GetValue())
231 dlg
= wxColourDialog(self
, data
)
232 if dlg
.ShowModal() == wxID_OK
:
233 self
.SetValue('#%02X%02X%02X' % dlg
.GetColourData().GetColour().Get())
237 ################################################################################
239 # Mapping from wx constants to XML strings
240 fontFamiliesWx2Xml
= {wxDEFAULT
: 'default', wxDECORATIVE
: 'decorative',
241 wxROMAN
: 'roman', wxSCRIPT
: 'script', wxSWISS
: 'swiss',
243 fontStylesWx2Xml
= {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'}
244 fontWeightsWx2Xml
= {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'}
247 for k
,v
in m
.items(): rm
[v
] = k
249 fontFamiliesXml2wx
= ReverseMap(fontFamiliesWx2Xml
)
250 fontStylesXml2wx
= ReverseMap(fontStylesWx2Xml
)
251 fontWeightsXml2wx
= ReverseMap(fontWeightsWx2Xml
)
253 class ParamFont(PPanel
):
254 def __init__(self
, parent
, name
):
255 PPanel
.__init
__(self
, parent
, name
)
256 self
.ID_TEXT_CTRL
= wxNewId()
257 self
.ID_BUTTON_SELECT
= wxNewId()
259 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(200,-1))
260 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
261 self
.button
= wxButton(self
, self
.ID_BUTTON_SELECT
, 'Select...', size
=buttonSize
)
262 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
)
263 self
.SetAutoLayout(True)
266 self
.textModified
= False
267 EVT_BUTTON(self
, self
.ID_BUTTON_SELECT
, self
.OnButtonSelect
)
268 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
269 def OnChange(self
, evt
):
270 PPanel
.OnChange(self
, evt
)
271 self
.textModified
= True
272 def _defaultValue(self
):
273 return [`g
._sysFont
.GetPointSize()`
, 'default', 'normal', 'normal', '0', '', '']
275 if self
.textModified
: # text has newer value
277 return eval(self
.text
.GetValue())
279 wxLogError('Syntax error in parameter value: ' + self
.GetName())
280 return self
._defaultValue
()
282 def SetValue(self
, value
):
283 self
.freeze
= True # disable other handlers
284 if not value
: value
= self
._defaultValue
()
286 self
.text
.SetValue(str(value
)) # update text ctrl
288 def OnButtonSelect(self
, evt
):
289 if self
.textModified
: # text has newer value
291 self
.value
= eval(self
.text
.GetValue())
293 wxLogError('Syntax error in parameter value: ' + self
.GetName())
294 self
.value
= self
._defaultValue
()
297 size
= g
._sysFont
.GetPointSize()
299 style
= weight
= wxNORMAL
302 enc
= wxFONTENCODING_DEFAULT
303 # Fall back to default if exceptions
306 try: size
= int(self
.value
[0])
307 except ValueError: error
= True; wxLogError('Invalid size specification')
308 try: family
= fontFamiliesXml2wx
[self
.value
[1]]
309 except KeyError: error
= True; wxLogError('Invalid family specification')
310 try: style
= fontStylesXml2wx
[self
.value
[2]]
311 except KeyError: error
= True; wxLogError('Invalid style specification')
312 try: weight
= fontWeightsXml2wx
[self
.value
[3]]
313 except KeyError: error
= True; wxLogError('Invalid weight specification')
314 try: underlined
= bool(self
.value
[4])
315 except ValueError: error
= True; wxLogError('Invalid underlined flag specification')
319 mapper
= wxFontMapper()
320 if not self
.value
[6]: enc
= mapper
.CharsetToEncoding(self
.value
[6])
322 if error
: wxLogError('Invalid font specification')
323 if enc
== wxFONTENCODING_DEFAULT
: enc
= wxFONTENCODING_SYSTEM
324 font
= wxFont(size
, family
, style
, weight
, underlined
, face
, enc
)
326 data
.SetInitialFont(font
)
327 dlg
= wxFontDialog(self
, data
)
328 if dlg
.ShowModal() == wxID_OK
:
329 font
= dlg
.GetFontData().GetChosenFont()
330 print font
.GetEncoding()
331 if font
.GetEncoding() == wxFONTENCODING_SYSTEM
:
334 encName
= wxFontMapper_GetEncodingName(font
.GetEncoding()).encode()
335 value
= [str(font
.GetPointSize()),
336 fontFamiliesWx2Xml
.get(font
.GetFamily(), "default"),
337 fontStylesWx2Xml
.get(font
.GetStyle(), "normal"),
338 fontWeightsWx2Xml
.get(font
.GetWeight(), "normal"),
339 str(int(font
.GetUnderlined())),
340 font
.GetFaceName().encode(),
345 self
.textModified
= False
348 ################################################################################
350 class ParamInt(PPanel
):
351 def __init__(self
, parent
, name
):
352 PPanel
.__init
__(self
, parent
, name
)
353 self
.ID_SPIN_CTRL
= wxNewId()
355 self
.spin
= wxSpinCtrl(self
, self
.ID_SPIN_CTRL
, size
=(60,-1))
356 self
.spin
.SetRange(-2147483648, 2147483647) # min/max integers
358 self
.SetAutoLayout(True)
361 EVT_SPINCTRL(self
, self
.ID_SPIN_CTRL
, self
.OnChange
)
363 return str(self
.spin
.GetValue())
364 def SetValue(self
, value
):
366 if not value
: value
= 0
367 self
.spin
.SetValue(int(value
))
370 # Non-negative number
371 class ParamIntNN(PPanel
):
372 def __init__(self
, parent
, name
):
373 PPanel
.__init
__(self
, parent
, name
)
374 self
.ID_SPIN_CTRL
= wxNewId()
376 self
.spin
= wxSpinCtrl(self
, self
.ID_SPIN_CTRL
, size
=(60,-1))
377 self
.spin
.SetRange(0, 10000) # min/max integers
379 self
.SetAutoLayout(True)
382 EVT_SPINCTRL(self
, self
.ID_SPIN_CTRL
, self
.OnChange
)
384 return str(self
.spin
.GetValue())
385 def SetValue(self
, value
):
387 if not value
: value
= 0
388 self
.spin
.SetValue(int(value
))
391 # Same as int but allows dialog units (XXXd)
392 class ParamUnit(PPanel
):
393 def __init__(self
, parent
, name
):
394 PPanel
.__init
__(self
, parent
, name
)
395 self
.ID_TEXT_CTRL
= wxNewId()
396 self
.ID_SPIN_BUTTON
= wxNewId()
397 sizer
= wxBoxSizer(wxHORIZONTAL
)
398 self
.spin
= wxSpinButton(self
, self
.ID_SPIN_BUTTON
, style
= wxSP_VERTICAL
, size
=(-1,1))
399 textW
= 60 - self
.spin
.GetSize()[0]
400 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(textW
,-1))
401 self
.spin
.SetRange(-10000, 10000)
402 sizer
.Add(self
.text
, 0, wxEXPAND
)
403 sizer
.Add(self
.spin
, 0, wxEXPAND
)
404 #sizer.SetMinSize((50,-1))
405 self
.SetAutoLayout(True)
408 EVT_SPIN_UP(self
, self
.ID_SPIN_BUTTON
, self
.OnSpinUp
)
409 EVT_SPIN_DOWN(self
, self
.ID_SPIN_BUTTON
, self
.OnSpinDown
)
411 return self
.text
.GetValue()
412 def SetValue(self
, value
):
414 if not value
: value
= '0'
415 self
.text
.SetValue(value
)
418 # Check if we are working with dialog units
419 value
= self
.text
.GetValue()
421 if value
[-1].upper() == 'D':
425 intValue
= int(value
) + x
426 self
.spin
.SetValue(intValue
)
427 self
.text
.SetValue(str(intValue
) + units
)
430 # !!! Strange, if I use wxLogWarning, event is re-generated
431 print 'incorrect unit format'
432 def OnSpinUp(self
, evt
):
434 def OnSpinDown(self
, evt
):
437 class ParamMultilineText(PPanel
):
438 def __init__(self
, parent
, name
, textWidth
=-1):
439 PPanel
.__init
__(self
, parent
, name
)
440 self
.ID_TEXT_CTRL
= wxNewId()
441 self
.ID_BUTTON_EDIT
= wxNewId()
443 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1))
444 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
445 self
.button
= wxButton(self
, self
.ID_BUTTON_EDIT
, 'Edit...', size
=buttonSize
)
446 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
)
447 self
.SetAutoLayout(True)
450 EVT_BUTTON(self
, self
.ID_BUTTON_EDIT
, self
.OnButtonEdit
)
451 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
453 return self
.text
.GetValue()
454 def SetValue(self
, value
):
455 self
.freeze
= True # disable other handlers
456 self
.text
.SetValue(value
)
457 self
.freeze
= False # disable other handlers
458 def OnButtonEdit(self
, evt
):
459 dlg
= g
.frame
.res
.LoadDialog(self
, 'DIALOG_TEXT')
460 textCtrl
= XRCCTRL(dlg
, 'TEXT')
461 textCtrl
.SetValue(self
.text
.GetValue())
462 if dlg
.ShowModal() == wxID_OK
:
463 self
.text
.SetValue(textCtrl
.GetValue())
467 class ParamText(PPanel
):
468 def __init__(self
, parent
, name
, textWidth
=-1):
469 PPanel
.__init
__(self
, parent
, name
)
470 self
.ID_TEXT_CTRL
= wxNewId()
471 # We use sizer even here to have the same size of text control
473 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(textWidth
,-1))
474 if textWidth
== -1: option
= 1
476 sizer
.Add(self
.text
, option
, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM
, 2)
477 self
.SetAutoLayout(True)
480 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
482 return self
.text
.GetValue()
483 def SetValue(self
, value
):
484 self
.freeze
= True # disable other handlers
485 self
.text
.SetValue(value
)
486 self
.freeze
= False # disable other handlers
488 class ParamAccel(ParamText
):
489 def __init__(self
, parent
, name
):
490 ParamText
.__init
__(self
, parent
, name
, 100)
492 class ParamPosSize(ParamText
):
493 def __init__(self
, parent
, name
):
494 ParamText
.__init
__(self
, parent
, name
, 80)
496 class ParamLabel(ParamText
):
497 def __init__(self
, parent
, name
):
498 ParamText
.__init
__(self
, parent
, name
, 200)
500 class ParamEncoding(ParamText
):
501 def __init__(self
, parent
, name
):
502 ParamText
.__init
__(self
, parent
, name
, 100)
504 class ContentDialog(wxDialog
):
505 def __init__(self
, parent
, value
):
508 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_CONTENT')
510 self
._setOORInfo
(self
)
511 self
.list = XRCCTRL(self
, 'LIST')
515 self
.SetAutoLayout(True)
516 self
.GetSizer().Fit(self
)
518 self
.ID_BUTTON_APPEND
= XRCID('BUTTON_APPEND')
519 self
.ID_BUTTON_REMOVE
= XRCID('BUTTON_REMOVE')
520 self
.ID_BUTTON_UP
= XRCID('BUTTON_UP')
521 self
.ID_BUTTON_DOWN
= XRCID('BUTTON_DOWN')
522 EVT_BUTTON(self
, self
.ID_BUTTON_UP
, self
.OnButtonUp
)
523 EVT_BUTTON(self
, self
.ID_BUTTON_DOWN
, self
.OnButtonDown
)
524 EVT_BUTTON(self
, self
.ID_BUTTON_APPEND
, self
.OnButtonAppend
)
525 EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
526 EVT_UPDATE_UI(self
, self
.ID_BUTTON_UP
, self
.OnUpdateUI
)
527 EVT_UPDATE_UI(self
, self
.ID_BUTTON_DOWN
, self
.OnUpdateUI
)
528 EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
529 def OnButtonUp(self
, evt
):
530 i
= self
.list.GetSelection()
531 str = self
.list.GetString(i
)
533 self
.list.InsertItems([str], i
-1)
534 self
.list.SetSelection(i
-1)
535 def OnButtonDown(self
, evt
):
536 i
= self
.list.GetSelection()
537 str = self
.list.GetString(i
)
539 self
.list.InsertItems([str], i
+1)
540 self
.list.SetSelection(i
+1)
541 def OnButtonAppend(self
, evt
):
542 str = wxGetTextFromUser('Enter new item:', 'Append', '', self
)
543 self
.list.Append(str)
544 def OnButtonRemove(self
, evt
):
545 self
.list.Delete(self
.list.GetSelection())
546 def OnUpdateUI(self
, evt
):
547 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
548 evt
.Enable(self
.list.GetSelection() != -1)
549 elif evt
.GetId() == self
.ID_BUTTON_UP
:
550 evt
.Enable(self
.list.GetSelection() > 0)
551 elif evt
.GetId() == self
.ID_BUTTON_DOWN
:
552 evt
.Enable(self
.list.GetSelection() != -1 and \
553 self
.list.GetSelection() < self
.list.GetCount() - 1)
555 class ContentCheckListDialog(wxDialog
):
556 def __init__(self
, parent
, value
):
558 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_CONTENT_CHECKLIST')
560 self
._setOORInfo
(self
)
561 self
.list = XRCCTRL(self
, 'CHECKLIST')
566 self
.list.Check(i
, ch
)
568 self
.SetAutoLayout(True)
569 self
.GetSizer().Fit(self
)
571 self
.ID_BUTTON_APPEND
= XRCID('BUTTON_APPEND')
572 self
.ID_BUTTON_REMOVE
= XRCID('BUTTON_REMOVE')
573 self
.ID_BUTTON_UP
= XRCID('BUTTON_UP')
574 self
.ID_BUTTON_DOWN
= XRCID('BUTTON_DOWN')
575 EVT_CHECKLISTBOX(self
, self
.list.GetId(), self
.OnCheck
)
576 EVT_BUTTON(self
, self
.ID_BUTTON_UP
, self
.OnButtonUp
)
577 EVT_BUTTON(self
, self
.ID_BUTTON_DOWN
, self
.OnButtonDown
)
578 EVT_BUTTON(self
, self
.ID_BUTTON_APPEND
, self
.OnButtonAppend
)
579 EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
580 EVT_UPDATE_UI(self
, self
.ID_BUTTON_UP
, self
.OnUpdateUI
)
581 EVT_UPDATE_UI(self
, self
.ID_BUTTON_DOWN
, self
.OnUpdateUI
)
582 EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
583 def OnCheck(self
, evt
):
584 # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking
585 self
.list.Deselect(evt
.GetSelection())
586 def OnButtonUp(self
, evt
):
587 i
= self
.list.GetSelection()
588 str, ch
= self
.list.GetString(i
), self
.list.IsChecked(i
)
590 self
.list.InsertItems([str], i
-1)
591 self
.list.Check(i
-1, ch
)
592 self
.list.SetSelection(i
-1)
593 def OnButtonDown(self
, evt
):
594 i
= self
.list.GetSelection()
595 str, ch
= self
.list.GetString(i
), self
.list.IsChecked(i
)
597 self
.list.InsertItems([str], i
+1)
598 self
.list.Check(i
+1, ch
)
599 self
.list.SetSelection(i
+1)
600 def OnButtonAppend(self
, evt
):
601 str = wxGetTextFromUser('Enter new item:', 'Append', '', self
)
602 self
.list.Append(str)
603 def OnButtonRemove(self
, evt
):
604 self
.list.Delete(self
.list.GetSelection())
605 def OnUpdateUI(self
, evt
):
606 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
607 evt
.Enable(self
.list.GetSelection() != -1)
608 elif evt
.GetId() == self
.ID_BUTTON_UP
:
609 evt
.Enable(self
.list.GetSelection() > 0)
610 elif evt
.GetId() == self
.ID_BUTTON_DOWN
:
611 evt
.Enable(self
.list.GetSelection() != -1 and \
612 self
.list.GetSelection() < self
.list.GetCount() - 1)
614 class ParamContent(PPanel
):
615 def __init__(self
, parent
, name
):
616 PPanel
.__init
__(self
, parent
, name
)
617 self
.ID_TEXT_CTRL
= wxNewId()
618 self
.ID_BUTTON_EDIT
= wxNewId()
620 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1))
621 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
622 self
.button
= wxButton(self
, self
.ID_BUTTON_EDIT
, 'Edit...', size
=buttonSize
)
623 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
)
624 self
.SetAutoLayout(True)
627 self
.textModified
= False
628 EVT_BUTTON(self
, self
.ID_BUTTON_EDIT
, self
.OnButtonEdit
)
629 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
630 def OnChange(self
, evt
):
631 PPanel
.OnChange(self
, evt
)
632 self
.textModified
= True
634 if self
.textModified
: # text has newer value
636 return eval(self
.text
.GetValue())
638 wxLogError('Syntax error in parameter value: ' + self
.GetName())
641 def SetValue(self
, value
):
643 if not value
: value
= []
645 self
.text
.SetValue(str(value
)) # update text ctrl
647 def OnButtonEdit(self
, evt
):
648 if self
.textModified
: # text has newer value
650 self
.value
= eval(self
.text
.GetValue())
652 wxLogError('Syntax error in parameter value: ' + self
.GetName())
654 dlg
= ContentDialog(self
, self
.value
)
655 if dlg
.ShowModal() == wxID_OK
:
657 for i
in range(dlg
.list.GetCount()):
658 value
.append(dlg
.list.GetString(i
))
661 self
.textModified
= False
665 class ParamContentCheckList(ParamContent
):
666 def __init__(self
, parent
, name
):
667 ParamContent
.__init
__(self
, parent
, name
)
668 def OnButtonEdit(self
, evt
):
669 if self
.textModified
: # text has newer value
671 self
.value
= eval(self
.text
.GetValue())
673 wxLogError('Syntax error in parameter value: ' + self
.GetName())
675 dlg
= ContentCheckListDialog(self
, self
.value
)
676 if dlg
.ShowModal() == wxID_OK
:
678 for i
in range(dlg
.list.GetCount()):
679 value
.append((dlg
.list.GetString(i
), int(dlg
.list.IsChecked(i
))))
682 self
.textModified
= False
685 class IntListDialog(wxDialog
):
686 def __init__(self
, parent
, value
):
688 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_INTLIST')
690 self
._setOORInfo
(self
)
691 self
.list = XRCCTRL(self
, 'LIST')
695 if type(v
) != IntType
:
696 wxLogError('Invalid item type')
698 self
.list.Append(str(v
))
699 self
.SetAutoLayout(True)
700 self
.GetSizer().Fit(self
)
702 self
.spinCtrl
= XRCCTRL(self
, 'SPIN')
703 EVT_BUTTON(self
, XRCID('BUTTON_ADD'), self
.OnButtonAdd
)
704 self
.ID_BUTTON_REMOVE
= XRCID('BUTTON_REMOVE')
705 EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
706 EVT_BUTTON(self
, XRCID('BUTTON_CLEAR'), self
.OnButtonClear
)
707 EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
708 def OnButtonAdd(self
, evt
):
709 # Check that it's unique
711 v
= self
.spinCtrl
.GetValue()
712 s
= str(v
) # to be sure
713 i
= self
.list.FindString(s
)
714 if i
== -1: # ignore non-unique
715 # Find place to insert
717 for i
in range(self
.list.GetCount()):
718 if int(self
.list.GetString(i
)) > v
:
721 if found
: self
.list.InsertItems([s
], i
)
722 else: self
.list.Append(s
)
724 wxLogError('List item is not an int!')
725 def OnButtonRemove(self
, evt
):
726 self
.list.Delete(self
.list.GetSelection())
727 def OnButtonClear(self
, evt
):
729 def OnUpdateUI(self
, evt
):
730 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
731 evt
.Enable(self
.list.GetSelection() != -1)
734 class ParamIntList(ParamContent
):
735 def __init__(self
, parent
, name
):
736 ParamContent
.__init
__(self
, parent
, name
)
737 def OnButtonEdit(self
, evt
):
738 if self
.textModified
: # text has newer value
740 self
.value
= eval(self
.text
.GetValue())
742 wxLogError('Syntax error in parameter value: ' + self
.GetName())
744 dlg
= IntListDialog(self
, self
.value
)
745 if dlg
.ShowModal() == wxID_OK
:
747 for i
in range(dlg
.list.GetCount()):
748 value
.append(int(dlg
.list.GetString(i
)))
751 self
.textModified
= False
755 class RadioBox(PPanel
):
756 def __init__(self
, parent
, id, choices
,
757 pos
=wxDefaultPosition
, name
='radiobox'):
758 PPanel
.__init
__(self
, parent
, name
)
759 self
.choices
= choices
760 topSizer
= wxBoxSizer()
762 button
= wxRadioButton(self
, -1, i
, size
=(-1,buttonSize
[1]), name
=i
)
763 topSizer
.Add(button
, 0, wxRIGHT
, 5)
764 EVT_RADIOBUTTON(self
, button
.GetId(), self
.OnRadioChoice
)
765 self
.SetAutoLayout(True)
766 self
.SetSizer(topSizer
)
768 def SetStringSelection(self
, value
):
770 for i
in self
.choices
:
771 self
.FindWindowByName(i
).SetValue(i
== value
)
774 def OnRadioChoice(self
, evt
):
775 if self
.freeze
: return
776 if evt
.GetSelection():
777 self
.value
= evt
.GetEventObject().GetName()
779 def GetStringSelection(self
):
782 class ParamBool(RadioBox
):
783 values
= {'yes': '1', 'no': '0'}
784 seulav
= {'1': 'yes', '0': 'no'}
785 def __init__(self
, parent
, name
):
786 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
788 return self
.values
[self
.GetStringSelection()]
789 def SetValue(self
, value
):
790 if not value
: value
= '1'
791 self
.SetStringSelection(self
.seulav
[value
])
793 class ParamOrient(RadioBox
):
794 values
= {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
795 seulav
= {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'}
796 def __init__(self
, parent
, name
):
797 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
799 return self
.values
[self
.GetStringSelection()]
800 def SetValue(self
, value
):
801 if not value
: value
= 'wxHORIZONTAL'
802 self
.SetStringSelection(self
.seulav
[value
])
804 class ParamOrientation(RadioBox
):
805 values
= {'horizontal': 'horizontal', 'vertical': 'vertical'}
806 seulav
= {'horizontal': 'horizontal', 'vertical': 'vertical'}
807 def __init__(self
, parent
, name
):
808 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
810 return self
.values
[self
.GetStringSelection()]
811 def SetValue(self
, value
):
812 if not value
: value
= 'vertical'
813 self
.SetStringSelection(self
.seulav
[value
])
815 class ParamFile(PPanel
):
816 def __init__(self
, parent
, name
):
817 PPanel
.__init
__(self
, parent
, name
)
818 self
.ID_TEXT_CTRL
= wxNewId()
819 self
.ID_BUTTON_BROWSE
= wxNewId()
821 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1))
822 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
823 self
.button
= wxButton(self
, self
.ID_BUTTON_BROWSE
, 'Browse...',size
=buttonSize
)
824 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
)
825 self
.SetAutoLayout(True)
828 self
.textModified
= False
829 EVT_BUTTON(self
, self
.ID_BUTTON_BROWSE
, self
.OnButtonBrowse
)
830 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
831 def OnChange(self
, evt
):
832 PPanel
.OnChange(self
, evt
)
833 self
.textModified
= True
835 if self
.textModified
: # text has newer value
836 return self
.text
.GetValue()
838 def SetValue(self
, value
):
841 self
.text
.SetValue(value
) # update text ctrl
843 def OnButtonBrowse(self
, evt
):
844 if self
.textModified
: # text has newer value
845 self
.value
= self
.text
.GetValue()
846 dlg
= wxFileDialog(self
,
847 defaultDir
= os
.path
.abspath(os
.path
.dirname(self
.value
)),
848 defaultFile
= os
.path
.basename(self
.value
))
849 if dlg
.ShowModal() == wxID_OK
:
850 # Get common part of selected path and current
852 curpath
= os
.path
.abspath(g
.frame
.dataFile
)
854 curpath
= os
.path
.join(os
.getcwd(), '')
855 common
= os
.path
.commonprefix([curpath
, dlg
.GetPath()])
856 self
.SetValue(dlg
.GetPath()[len(common
):])
858 self
.textModified
= False
861 class ParamBitmap(PPanel
):
862 def __init__(self
, parent
, name
):
864 g
.frame
.res
.LoadOnPanel(pre
, parent
, 'PANEL_BITMAP')
866 self
._setOORInfo
(self
)
867 self
.modified
= self
.freeze
= False
868 self
.radio_std
= XRCCTRL(self
, 'RADIO_STD')
869 self
.radio_file
= XRCCTRL(self
, 'RADIO_FILE')
870 self
.combo
= XRCCTRL(self
, 'COMBO_STD')
871 self
.text
= XRCCTRL(self
, 'TEXT_FILE')
872 self
.button
= XRCCTRL(self
, 'BUTTON_BROWSE')
873 self
.textModified
= False
874 self
.SetAutoLayout(True)
875 self
.GetSizer().SetMinSize((260, -1))
876 self
.GetSizer().Fit(self
)
877 EVT_RADIOBUTTON(self
, XRCID('RADIO_STD'), self
.OnRadioStd
)
878 EVT_RADIOBUTTON(self
, XRCID('RADIO_FILE'), self
.OnRadioFile
)
879 EVT_BUTTON(self
, XRCID('BUTTON_BROWSE'), self
.OnButtonBrowse
)
880 EVT_COMBOBOX(self
, XRCID('COMBO_STD'), self
.OnCombo
)
881 EVT_TEXT(self
, XRCID('COMBO_STD'), self
.OnChange
)
882 EVT_TEXT(self
, XRCID('TEXT_FILE'), self
.OnChange
)
883 def OnRadioStd(self
, evt
):
885 self
.SetValue(['wxART_MISSING_IMAGE',''])
886 def OnRadioFile(self
, evt
):
888 self
.SetValue(['',''])
889 def updateRadios(self
):
891 self
.radio_std
.SetValue(True)
892 self
.radio_file
.SetValue(False)
893 self
.text
.Enable(False)
894 self
.button
.Enable(False)
895 self
.combo
.Enable(True)
897 self
.radio_std
.SetValue(False)
898 self
.radio_file
.SetValue(True)
899 self
.text
.Enable(True)
900 self
.button
.Enable(True)
901 self
.combo
.Enable(False)
902 def OnChange(self
, evt
):
903 PPanel
.OnChange(self
, evt
)
904 self
.textModified
= True
905 def OnCombo(self
, evt
):
906 PPanel
.OnChange(self
, evt
)
907 self
.value
[0] = self
.combo
.GetValue()
909 if self
.textModified
: # text has newer value
910 return [self
.combo
.GetValue(), self
.text
.GetValue()]
912 def SetValue(self
, value
):
915 self
.value
= ['', '']
918 self
.combo
.SetValue(self
.value
[0])
919 self
.text
.SetValue(self
.value
[1]) # update text ctrl
922 def OnButtonBrowse(self
, evt
):
923 if self
.textModified
: # text has newer value
924 self
.value
[1] = self
.text
.GetValue()
925 dlg
= wxFileDialog(self
,
926 defaultDir
= os
.path
.abspath(os
.path
.dirname(self
.value
[1])),
927 defaultFile
= os
.path
.basename(self
.value
[1]))
928 if dlg
.ShowModal() == wxID_OK
:
929 # Get common part of selected path and current
931 curpath
= os
.path
.abspath(g
.frame
.dataFile
)
933 curpath
= os
.path
.join(os
.getcwd(), '')
934 common
= os
.path
.commonprefix([curpath
, dlg
.GetPath()])
935 self
.SetValue(['', dlg
.GetPath()[len(common
):]])
937 self
.textModified
= False
942 'style': ParamStyle
, 'exstyle': ParamExStyle
,
943 'pos': ParamPosSize
, 'size': ParamPosSize
,
944 'cellpos': ParamPosSize
, 'cellspan': ParamPosSize
,
945 'border': ParamUnit
, 'cols': ParamIntNN
, 'rows': ParamIntNN
,
946 'vgap': ParamUnit
, 'hgap': ParamUnit
,
947 'checkable': ParamBool
, 'checked': ParamBool
, 'radio': ParamBool
,
949 'label': ParamMultilineText
, 'title': ParamText
, 'value': ParamText
,
950 'content': ParamContent
, 'selection': ParamIntNN
,
951 'min': ParamInt
, 'max': ParamInt
,
952 'fg': ParamColour
, 'bg': ParamColour
, 'font': ParamFont
,
953 'enabled': ParamBool
, 'focused': ParamBool
, 'hidden': ParamBool
,
954 'tooltip': ParamText
, 'bitmap': ParamBitmap
, 'icon': ParamBitmap
,
955 'encoding': ParamEncoding
, 'borders': ParamUnit