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
)
190 self
.SetTitle('Extended window styles')
192 class ParamColour(PPanel
):
193 def __init__(self
, parent
, name
):
194 PPanel
.__init
__(self
, parent
, name
)
195 self
.ID_TEXT_CTRL
= wxNewId()
196 self
.ID_BUTTON
= wxNewId()
198 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(80,-1))
199 sizer
.Add(self
.text
, 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM
, 2)
200 self
.button
= wxPanel(self
, self
.ID_BUTTON
, wxDefaultPosition
, wxSize(20, 20))
201 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL | wxLEFT
, 5)
202 self
.SetAutoLayout(True)
205 self
.textModified
= False
206 EVT_PAINT(self
.button
, self
.OnPaintButton
)
207 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
208 EVT_LEFT_DOWN(self
.button
, self
.OnLeftDown
)
210 return self
.text
.GetValue()
211 def SetValue(self
, value
):
213 if not value
: value
= '#FFFFFF'
214 self
.text
.SetValue(str(value
)) # update text ctrl
215 colour
= wxColour(int(value
[1:3], 16), int(value
[3:5], 16), int(value
[5:7], 16))
216 self
.button
.SetBackgroundColour(colour
)
217 self
.button
.Refresh()
219 def OnPaintButton(self
, evt
):
220 dc
= wxPaintDC(self
.button
)
221 dc
.SetBrush(wxTRANSPARENT_BRUSH
)
222 if self
.IsEnabled(): dc
.SetPen(wxBLACK_PEN
)
223 else: dc
.SetPen(wxGREY_PEN
)
224 size
= self
.button
.GetSize()
225 dc
.DrawRectangle(0, 0, size
.width
, size
.height
)
226 def OnLeftDown(self
, evt
):
227 data
= wxColourData()
228 data
.SetColour(self
.GetValue())
229 dlg
= wxColourDialog(self
, data
)
230 if dlg
.ShowModal() == wxID_OK
:
231 self
.SetValue('#%02X%02X%02X' % dlg
.GetColourData().GetColour().Get())
235 ################################################################################
237 # Mapping from wx constants ro XML strings
238 fontFamiliesWx2Xml
= {wxDEFAULT
: 'default', wxDECORATIVE
: 'decorative',
239 wxROMAN
: 'roman', wxSCRIPT
: 'script', wxSWISS
: 'swiss',
241 fontStylesWx2Xml
= {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'}
242 fontWeightsWx2Xml
= {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'}
245 for k
,v
in m
.items(): rm
[v
] = k
247 fontFamiliesXml2wx
= ReverseMap(fontFamiliesWx2Xml
)
248 fontStylesXml2wx
= ReverseMap(fontStylesWx2Xml
)
249 fontWeightsXml2wx
= ReverseMap(fontWeightsWx2Xml
)
251 class ParamFont(PPanel
):
252 def __init__(self
, parent
, name
):
253 PPanel
.__init
__(self
, parent
, name
)
254 self
.ID_TEXT_CTRL
= wxNewId()
255 self
.ID_BUTTON_SELECT
= wxNewId()
257 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(200,-1))
258 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
259 self
.button
= wxButton(self
, self
.ID_BUTTON_SELECT
, 'Select...', size
=buttonSize
)
260 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
)
261 self
.SetAutoLayout(True)
264 self
.textModified
= False
265 EVT_BUTTON(self
, self
.ID_BUTTON_SELECT
, self
.OnButtonSelect
)
266 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
267 def OnChange(self
, evt
):
268 PPanel
.OnChange(self
, evt
)
269 self
.textModified
= True
270 def _defaultValue(self
):
271 return [`g
._sysFont
.GetPointSize()`
, 'default', 'normal', 'normal', '0', '', '']
273 if self
.textModified
: # text has newer value
275 return eval(self
.text
.GetValue())
277 wxLogError('Syntax error in parameter value: ' + self
.GetName())
278 return self
._defaultValue
()
280 def SetValue(self
, value
):
281 self
.freeze
= True # disable other handlers
282 if not value
: value
= self
._defaultValue
()
284 self
.text
.SetValue(str(value
)) # update text ctrl
286 def OnButtonSelect(self
, evt
):
287 if self
.textModified
: # text has newer value
289 self
.value
= eval(self
.text
.GetValue())
291 wxLogError('Syntax error in parameter value: ' + self
.GetName())
292 self
.value
= self
._defaultValue
()
295 size
= g
._sysFont
.GetPointSize()
297 style
= weight
= wxNORMAL
300 enc
= wxFONTENCODING_DEFAULT
301 # Fall back to default if exceptions
304 try: size
= int(self
.value
[0])
305 except ValueError: error
= True; wxLogError('Invalid size specification')
306 try: family
= fontFamiliesXml2wx
[self
.value
[1]]
307 except KeyError: error
= True; wxLogError('Invalid family specification')
308 try: style
= fontStylesXml2wx
[self
.value
[2]]
309 except KeyError: error
= True; wxLogError('Invalid style specification')
310 try: weight
= fontWeightsXml2wx
[self
.value
[3]]
311 except KeyError: error
= True; wxLogError('Invalid weight specification')
312 try: underlined
= bool(self
.value
[4])
313 except ValueError: error
= True; wxLogError('Invalid underlined flag specification')
317 mapper
= wxFontMapper()
318 if not self
.value
[6]: enc
= mapper
.CharsetToEncoding(self
.value
[6])
320 if error
: wxLogError('Invalid font specification')
321 if enc
== wxFONTENCODING_DEFAULT
: enc
= wxFONTENCODING_SYSTEM
322 font
= wxFont(size
, family
, style
, weight
, underlined
, face
, enc
)
324 data
.SetInitialFont(font
)
325 dlg
= wxFontDialog(self
, data
)
326 if dlg
.ShowModal() == wxID_OK
:
327 font
= dlg
.GetFontData().GetChosenFont()
328 print font
.GetEncoding()
329 if font
.GetEncoding() == wxFONTENCODING_SYSTEM
:
332 encName
= wxFontMapper_GetEncodingName(font
.GetEncoding()).encode()
333 value
= [str(font
.GetPointSize()),
334 fontFamiliesWx2Xml
.get(font
.GetFamily(), "default"),
335 fontStylesWx2Xml
.get(font
.GetStyle(), "normal"),
336 fontWeightsWx2Xml
.get(font
.GetWeight(), "normal"),
337 str(int(font
.GetUnderlined())),
338 font
.GetFaceName().encode(),
343 self
.textModified
= False
346 ################################################################################
348 class ParamInt(PPanel
):
349 def __init__(self
, parent
, name
):
350 PPanel
.__init
__(self
, parent
, name
)
351 self
.ID_SPIN_CTRL
= wxNewId()
353 self
.spin
= wxSpinCtrl(self
, self
.ID_SPIN_CTRL
, size
=(60,-1))
354 self
.spin
.SetRange(-2147483648, 2147483647) # min/max integers
356 self
.SetAutoLayout(True)
359 EVT_SPINCTRL(self
, self
.ID_SPIN_CTRL
, self
.OnChange
)
361 return str(self
.spin
.GetValue())
362 def SetValue(self
, value
):
364 if not value
: value
= 0
365 self
.spin
.SetValue(int(value
))
368 # Non-negative number
369 class ParamIntNN(PPanel
):
370 def __init__(self
, parent
, name
):
371 PPanel
.__init
__(self
, parent
, name
)
372 self
.ID_SPIN_CTRL
= wxNewId()
374 self
.spin
= wxSpinCtrl(self
, self
.ID_SPIN_CTRL
, size
=(60,-1))
375 self
.spin
.SetRange(0, 10000) # min/max integers
377 self
.SetAutoLayout(True)
380 EVT_SPINCTRL(self
, self
.ID_SPIN_CTRL
, self
.OnChange
)
382 return str(self
.spin
.GetValue())
383 def SetValue(self
, value
):
385 if not value
: value
= 0
386 self
.spin
.SetValue(int(value
))
389 # Same as int but allows dialog units (XXXd)
390 class ParamUnit(PPanel
):
391 def __init__(self
, parent
, name
):
392 PPanel
.__init
__(self
, parent
, name
)
393 self
.ID_TEXT_CTRL
= wxNewId()
394 self
.ID_SPIN_BUTTON
= wxNewId()
395 sizer
= wxBoxSizer(wxHORIZONTAL
)
396 self
.spin
= wxSpinButton(self
, self
.ID_SPIN_BUTTON
, style
= wxSP_VERTICAL
, size
=(-1,1))
397 textW
= 60 - self
.spin
.GetSize()[0]
398 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(textW
,-1))
399 self
.spin
.SetRange(-10000, 10000)
400 sizer
.Add(self
.text
, 0, wxEXPAND
)
401 sizer
.Add(self
.spin
, 0, wxEXPAND
)
402 #sizer.SetMinSize((50,-1))
403 self
.SetAutoLayout(True)
406 EVT_SPIN_UP(self
, self
.ID_SPIN_BUTTON
, self
.OnSpinUp
)
407 EVT_SPIN_DOWN(self
, self
.ID_SPIN_BUTTON
, self
.OnSpinDown
)
409 return self
.text
.GetValue()
410 def SetValue(self
, value
):
412 if not value
: value
= '0'
413 self
.text
.SetValue(value
)
416 # Check if we are working with dialog units
417 value
= self
.text
.GetValue()
419 if value
[-1].upper() == 'D':
423 intValue
= int(value
) + x
424 self
.spin
.SetValue(intValue
)
425 self
.text
.SetValue(str(intValue
) + units
)
428 # !!! Strange, if I use wxLogWarning, event is re-generated
429 print 'incorrect unit format'
430 def OnSpinUp(self
, evt
):
432 def OnSpinDown(self
, evt
):
435 class ParamMultilineText(PPanel
):
436 def __init__(self
, parent
, name
, textWidth
=-1):
437 PPanel
.__init
__(self
, parent
, name
)
438 self
.ID_TEXT_CTRL
= wxNewId()
439 self
.ID_BUTTON_EDIT
= wxNewId()
441 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1))
442 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
443 self
.button
= wxButton(self
, self
.ID_BUTTON_EDIT
, 'Edit...', size
=buttonSize
)
444 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
)
445 self
.SetAutoLayout(True)
448 EVT_BUTTON(self
, self
.ID_BUTTON_EDIT
, self
.OnButtonEdit
)
449 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
451 return self
.text
.GetValue()
452 def SetValue(self
, value
):
453 self
.freeze
= True # disable other handlers
454 self
.text
.SetValue(value
)
455 self
.freeze
= False # disable other handlers
456 def OnButtonEdit(self
, evt
):
457 dlg
= g
.frame
.res
.LoadDialog(self
, 'DIALOG_TEXT')
458 textCtrl
= XRCCTRL(dlg
, 'TEXT')
459 textCtrl
.SetValue(self
.text
.GetValue())
460 if dlg
.ShowModal() == wxID_OK
:
461 self
.text
.SetValue(textCtrl
.GetValue())
465 class ParamText(PPanel
):
466 def __init__(self
, parent
, name
, textWidth
=-1):
467 PPanel
.__init
__(self
, parent
, name
)
468 self
.ID_TEXT_CTRL
= wxNewId()
469 # We use sizer even here to have the same size of text control
471 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(textWidth
,-1))
472 if textWidth
== -1: option
= 1
474 sizer
.Add(self
.text
, option
, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM
, 2)
475 self
.SetAutoLayout(True)
478 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
480 return self
.text
.GetValue()
481 def SetValue(self
, value
):
482 self
.freeze
= True # disable other handlers
483 self
.text
.SetValue(value
)
484 self
.freeze
= False # disable other handlers
486 class ParamAccel(ParamText
):
487 def __init__(self
, parent
, name
):
488 ParamText
.__init
__(self
, parent
, name
, 100)
490 class ParamPosSize(ParamText
):
491 def __init__(self
, parent
, name
):
492 ParamText
.__init
__(self
, parent
, name
, 80)
494 class ParamLabel(ParamText
):
495 def __init__(self
, parent
, name
):
496 ParamText
.__init
__(self
, parent
, name
, 200)
498 class ParamEncoding(ParamText
):
499 def __init__(self
, parent
, name
):
500 ParamText
.__init
__(self
, parent
, name
, 100)
502 class ContentDialog(wxDialog
):
503 def __init__(self
, parent
, value
):
506 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_CONTENT')
508 self
._setOORInfo
(self
)
509 self
.list = XRCCTRL(self
, 'LIST')
513 self
.SetAutoLayout(True)
514 self
.GetSizer().Fit(self
)
516 self
.ID_BUTTON_APPEND
= XRCID('BUTTON_APPEND')
517 self
.ID_BUTTON_REMOVE
= XRCID('BUTTON_REMOVE')
518 self
.ID_BUTTON_UP
= XRCID('BUTTON_UP')
519 self
.ID_BUTTON_DOWN
= XRCID('BUTTON_DOWN')
520 EVT_BUTTON(self
, self
.ID_BUTTON_UP
, self
.OnButtonUp
)
521 EVT_BUTTON(self
, self
.ID_BUTTON_DOWN
, self
.OnButtonDown
)
522 EVT_BUTTON(self
, self
.ID_BUTTON_APPEND
, self
.OnButtonAppend
)
523 EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
524 EVT_UPDATE_UI(self
, self
.ID_BUTTON_UP
, self
.OnUpdateUI
)
525 EVT_UPDATE_UI(self
, self
.ID_BUTTON_DOWN
, self
.OnUpdateUI
)
526 EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
527 def OnButtonUp(self
, evt
):
528 i
= self
.list.GetSelection()
529 str = self
.list.GetString(i
)
531 self
.list.InsertItems([str], i
-1)
532 self
.list.SetSelection(i
-1)
533 def OnButtonDown(self
, evt
):
534 i
= self
.list.GetSelection()
535 str = self
.list.GetString(i
)
537 self
.list.InsertItems([str], i
+1)
538 self
.list.SetSelection(i
+1)
539 def OnButtonAppend(self
, evt
):
540 str = wxGetTextFromUser('Enter new item:', 'Append', '', self
)
541 self
.list.Append(str)
542 def OnButtonRemove(self
, evt
):
543 self
.list.Delete(self
.list.GetSelection())
544 def OnUpdateUI(self
, evt
):
545 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
546 evt
.Enable(self
.list.GetSelection() != -1)
547 elif evt
.GetId() == self
.ID_BUTTON_UP
:
548 evt
.Enable(self
.list.GetSelection() > 0)
549 elif evt
.GetId() == self
.ID_BUTTON_DOWN
:
550 evt
.Enable(self
.list.GetSelection() != -1 and \
551 self
.list.GetSelection() < self
.list.GetCount() - 1)
553 class ContentCheckListDialog(wxDialog
):
554 def __init__(self
, parent
, value
):
556 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_CONTENT_CHECKLIST')
558 self
._setOORInfo
(self
)
559 self
.list = XRCCTRL(self
, 'CHECKLIST')
564 self
.list.Check(i
, ch
)
566 self
.SetAutoLayout(True)
567 self
.GetSizer().Fit(self
)
569 self
.ID_BUTTON_APPEND
= XRCID('BUTTON_APPEND')
570 self
.ID_BUTTON_REMOVE
= XRCID('BUTTON_REMOVE')
571 self
.ID_BUTTON_UP
= XRCID('BUTTON_UP')
572 self
.ID_BUTTON_DOWN
= XRCID('BUTTON_DOWN')
573 EVT_CHECKLISTBOX(self
, self
.list.GetId(), self
.OnCheck
)
574 EVT_BUTTON(self
, self
.ID_BUTTON_UP
, self
.OnButtonUp
)
575 EVT_BUTTON(self
, self
.ID_BUTTON_DOWN
, self
.OnButtonDown
)
576 EVT_BUTTON(self
, self
.ID_BUTTON_APPEND
, self
.OnButtonAppend
)
577 EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
578 EVT_UPDATE_UI(self
, self
.ID_BUTTON_UP
, self
.OnUpdateUI
)
579 EVT_UPDATE_UI(self
, self
.ID_BUTTON_DOWN
, self
.OnUpdateUI
)
580 EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
581 def OnCheck(self
, evt
):
582 # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking
583 self
.list.Deselect(evt
.GetSelection())
584 def OnButtonUp(self
, evt
):
585 i
= self
.list.GetSelection()
586 str, ch
= self
.list.GetString(i
), self
.list.IsChecked(i
)
588 self
.list.InsertItems([str], i
-1)
589 self
.list.Check(i
-1, ch
)
590 self
.list.SetSelection(i
-1)
591 def OnButtonDown(self
, evt
):
592 i
= self
.list.GetSelection()
593 str, ch
= self
.list.GetString(i
), self
.list.IsChecked(i
)
595 self
.list.InsertItems([str], i
+1)
596 self
.list.Check(i
+1, ch
)
597 self
.list.SetSelection(i
+1)
598 def OnButtonAppend(self
, evt
):
599 str = wxGetTextFromUser('Enter new item:', 'Append', '', self
)
600 self
.list.Append(str)
601 def OnButtonRemove(self
, evt
):
602 self
.list.Delete(self
.list.GetSelection())
603 def OnUpdateUI(self
, evt
):
604 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
605 evt
.Enable(self
.list.GetSelection() != -1)
606 elif evt
.GetId() == self
.ID_BUTTON_UP
:
607 evt
.Enable(self
.list.GetSelection() > 0)
608 elif evt
.GetId() == self
.ID_BUTTON_DOWN
:
609 evt
.Enable(self
.list.GetSelection() != -1 and \
610 self
.list.GetSelection() < self
.list.GetCount() - 1)
612 class ParamContent(PPanel
):
613 def __init__(self
, parent
, name
):
614 PPanel
.__init
__(self
, parent
, name
)
615 self
.ID_TEXT_CTRL
= wxNewId()
616 self
.ID_BUTTON_EDIT
= wxNewId()
618 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1))
619 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
620 self
.button
= wxButton(self
, self
.ID_BUTTON_EDIT
, 'Edit...', size
=buttonSize
)
621 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
)
622 self
.SetAutoLayout(True)
625 self
.textModified
= False
626 EVT_BUTTON(self
, self
.ID_BUTTON_EDIT
, self
.OnButtonEdit
)
627 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
628 def OnChange(self
, evt
):
629 PPanel
.OnChange(self
, evt
)
630 self
.textModified
= True
632 if self
.textModified
: # text has newer value
634 return eval(self
.text
.GetValue())
636 wxLogError('Syntax error in parameter value: ' + self
.GetName())
639 def SetValue(self
, value
):
641 if not value
: value
= []
643 self
.text
.SetValue(str(value
)) # update text ctrl
645 def OnButtonEdit(self
, evt
):
646 if self
.textModified
: # text has newer value
648 self
.value
= eval(self
.text
.GetValue())
650 wxLogError('Syntax error in parameter value: ' + self
.GetName())
652 dlg
= ContentDialog(self
, self
.value
)
653 if dlg
.ShowModal() == wxID_OK
:
655 for i
in range(dlg
.list.GetCount()):
656 value
.append(dlg
.list.GetString(i
))
659 self
.textModified
= False
663 class ParamContentCheckList(ParamContent
):
664 def __init__(self
, parent
, name
):
665 ParamContent
.__init
__(self
, parent
, name
)
666 def OnButtonEdit(self
, evt
):
667 if self
.textModified
: # text has newer value
669 self
.value
= eval(self
.text
.GetValue())
671 wxLogError('Syntax error in parameter value: ' + self
.GetName())
673 dlg
= ContentCheckListDialog(self
, self
.value
)
674 if dlg
.ShowModal() == wxID_OK
:
676 for i
in range(dlg
.list.GetCount()):
677 value
.append((dlg
.list.GetString(i
), int(dlg
.list.IsChecked(i
))))
680 self
.textModified
= False
683 class IntListDialog(wxDialog
):
684 def __init__(self
, parent
, value
):
686 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_INTLIST')
688 self
._setOORInfo
(self
)
689 self
.list = XRCCTRL(self
, 'LIST')
693 if type(v
) != IntType
:
694 wxLogError('Invalid item type')
696 self
.list.Append(str(v
))
697 self
.SetAutoLayout(True)
698 self
.GetSizer().Fit(self
)
700 self
.spinCtrl
= XRCCTRL(self
, 'SPIN')
701 EVT_BUTTON(self
, XRCID('BUTTON_ADD'), self
.OnButtonAdd
)
702 self
.ID_BUTTON_REMOVE
= XRCID('BUTTON_REMOVE')
703 EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
704 EVT_BUTTON(self
, XRCID('BUTTON_CLEAR'), self
.OnButtonClear
)
705 EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
706 def OnButtonAdd(self
, evt
):
707 # Check that it's unique
709 v
= self
.spinCtrl
.GetValue()
710 s
= str(v
) # to be sure
711 i
= self
.list.FindString(s
)
712 if i
== -1: # ignore non-unique
713 # Find place to insert
715 for i
in range(self
.list.GetCount()):
716 if int(self
.list.GetString(i
)) > v
:
719 if found
: self
.list.InsertItems([s
], i
)
720 else: self
.list.Append(s
)
722 wxLogError('List item is not an int!')
723 def OnButtonRemove(self
, evt
):
724 self
.list.Delete(self
.list.GetSelection())
725 def OnButtonClear(self
, evt
):
727 def OnUpdateUI(self
, evt
):
728 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
729 evt
.Enable(self
.list.GetSelection() != -1)
732 class ParamIntList(ParamContent
):
733 def __init__(self
, parent
, name
):
734 ParamContent
.__init
__(self
, parent
, name
)
735 def OnButtonEdit(self
, evt
):
736 if self
.textModified
: # text has newer value
738 self
.value
= eval(self
.text
.GetValue())
740 wxLogError('Syntax error in parameter value: ' + self
.GetName())
742 dlg
= IntListDialog(self
, self
.value
)
743 if dlg
.ShowModal() == wxID_OK
:
745 for i
in range(dlg
.list.GetCount()):
746 value
.append(int(dlg
.list.GetString(i
)))
749 self
.textModified
= False
753 class RadioBox(PPanel
):
754 def __init__(self
, parent
, id, choices
,
755 pos
=wxDefaultPosition
, name
='radiobox'):
756 PPanel
.__init
__(self
, parent
, name
)
757 self
.choices
= choices
758 topSizer
= wxBoxSizer()
760 button
= wxRadioButton(self
, -1, i
, size
=(-1,buttonSize
[1]), name
=i
)
761 topSizer
.Add(button
, 0, wxRIGHT
, 5)
762 EVT_RADIOBUTTON(self
, button
.GetId(), self
.OnRadioChoice
)
763 self
.SetAutoLayout(True)
764 self
.SetSizer(topSizer
)
766 def SetStringSelection(self
, value
):
768 for i
in self
.choices
:
769 self
.FindWindowByName(i
).SetValue(i
== value
)
772 def OnRadioChoice(self
, evt
):
773 if self
.freeze
: return
774 if evt
.GetSelection():
775 self
.value
= evt
.GetEventObject().GetName()
777 def GetStringSelection(self
):
780 class ParamBool(RadioBox
):
781 values
= {'yes': '1', 'no': '0'}
782 seulav
= {'1': 'yes', '0': 'no'}
783 def __init__(self
, parent
, name
):
784 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
786 return self
.values
[self
.GetStringSelection()]
787 def SetValue(self
, value
):
788 if not value
: value
= '1'
789 self
.SetStringSelection(self
.seulav
[value
])
791 class ParamOrient(RadioBox
):
792 values
= {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
793 seulav
= {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'}
794 def __init__(self
, parent
, name
):
795 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
797 return self
.values
[self
.GetStringSelection()]
798 def SetValue(self
, value
):
799 if not value
: value
= 'wxHORIZONTAL'
800 self
.SetStringSelection(self
.seulav
[value
])
802 class ParamOrientation(RadioBox
):
803 values
= {'horizontal': 'horizontal', 'vertical': 'vertical'}
804 seulav
= {'horizontal': 'horizontal', 'vertical': 'vertical'}
805 def __init__(self
, parent
, name
):
806 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
808 return self
.values
[self
.GetStringSelection()]
809 def SetValue(self
, value
):
810 if not value
: value
= 'vertical'
811 self
.SetStringSelection(self
.seulav
[value
])
813 class ParamFile(PPanel
):
814 def __init__(self
, parent
, name
):
815 PPanel
.__init
__(self
, parent
, name
)
816 self
.ID_TEXT_CTRL
= wxNewId()
817 self
.ID_BUTTON_BROWSE
= wxNewId()
819 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1))
820 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
821 self
.button
= wxButton(self
, self
.ID_BUTTON_BROWSE
, 'Browse...',size
=buttonSize
)
822 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
)
823 self
.SetAutoLayout(True)
826 self
.textModified
= False
827 EVT_BUTTON(self
, self
.ID_BUTTON_BROWSE
, self
.OnButtonBrowse
)
828 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
829 def OnChange(self
, evt
):
830 PPanel
.OnChange(self
, evt
)
831 self
.textModified
= True
833 if self
.textModified
: # text has newer value
834 return self
.text
.GetValue()
836 def SetValue(self
, value
):
839 self
.text
.SetValue(value
) # update text ctrl
841 def OnButtonBrowse(self
, evt
):
842 if self
.textModified
: # text has newer value
843 self
.value
= self
.text
.GetValue()
844 dlg
= wxFileDialog(self
,
845 defaultDir
= os
.path
.abspath(os
.path
.dirname(self
.value
)),
846 defaultFile
= os
.path
.basename(self
.value
))
847 if dlg
.ShowModal() == wxID_OK
:
848 # Get common part of selected path and current
850 curpath
= os
.path
.abspath(g
.frame
.dataFile
)
852 curpath
= os
.path
.join(os
.getcwd(), '')
853 common
= os
.path
.commonprefix([curpath
, dlg
.GetPath()])
854 self
.SetValue(dlg
.GetPath()[len(common
):])
856 self
.textModified
= False
859 class ParamBitmap(PPanel
):
860 def __init__(self
, parent
, name
):
862 g
.frame
.res
.LoadOnPanel(pre
, parent
, 'PANEL_BITMAP')
864 self
._setOORInfo
(self
)
865 self
.modified
= self
.freeze
= False
866 self
.radio_std
= XRCCTRL(self
, 'RADIO_STD')
867 self
.radio_file
= XRCCTRL(self
, 'RADIO_FILE')
868 self
.combo
= XRCCTRL(self
, 'COMBO_STD')
869 self
.text
= XRCCTRL(self
, 'TEXT_FILE')
870 self
.button
= XRCCTRL(self
, 'BUTTON_BROWSE')
871 self
.textModified
= False
872 self
.SetAutoLayout(True)
873 self
.GetSizer().SetMinSize((260, -1))
874 self
.GetSizer().Fit(self
)
875 EVT_RADIOBUTTON(self
, XRCID('RADIO_STD'), self
.OnRadioStd
)
876 EVT_RADIOBUTTON(self
, XRCID('RADIO_FILE'), self
.OnRadioFile
)
877 EVT_BUTTON(self
, XRCID('BUTTON_BROWSE'), self
.OnButtonBrowse
)
878 EVT_COMBOBOX(self
, XRCID('COMBO_STD'), self
.OnCombo
)
879 EVT_TEXT(self
, XRCID('COMBO_STD'), self
.OnChange
)
880 EVT_TEXT(self
, XRCID('TEXT_FILE'), self
.OnChange
)
881 def OnRadioStd(self
, evt
):
883 self
.SetValue(['wxART_MISSING_IMAGE',''])
884 def OnRadioFile(self
, evt
):
886 self
.SetValue(['',''])
887 def updateRadios(self
):
889 self
.radio_std
.SetValue(True)
890 self
.radio_file
.SetValue(False)
891 self
.text
.Enable(False)
892 self
.button
.Enable(False)
893 self
.combo
.Enable(True)
895 self
.radio_std
.SetValue(False)
896 self
.radio_file
.SetValue(True)
897 self
.text
.Enable(True)
898 self
.button
.Enable(True)
899 self
.combo
.Enable(False)
900 def OnChange(self
, evt
):
901 PPanel
.OnChange(self
, evt
)
902 self
.textModified
= True
903 def OnCombo(self
, evt
):
904 PPanel
.OnChange(self
, evt
)
905 self
.value
[0] = self
.combo
.GetValue()
907 if self
.textModified
: # text has newer value
908 return [self
.combo
.GetValue(), self
.text
.GetValue()]
910 def SetValue(self
, value
):
913 self
.value
= ['', '']
916 self
.combo
.SetValue(self
.value
[0])
917 self
.text
.SetValue(self
.value
[1]) # update text ctrl
920 def OnButtonBrowse(self
, evt
):
921 if self
.textModified
: # text has newer value
922 self
.value
[1] = self
.text
.GetValue()
923 dlg
= wxFileDialog(self
,
924 defaultDir
= os
.path
.abspath(os
.path
.dirname(self
.value
[1])),
925 defaultFile
= os
.path
.basename(self
.value
[1]))
926 if dlg
.ShowModal() == wxID_OK
:
927 # Get common part of selected path and current
929 curpath
= os
.path
.abspath(g
.frame
.dataFile
)
931 curpath
= os
.path
.join(os
.getcwd(), '')
932 common
= os
.path
.commonprefix([curpath
, dlg
.GetPath()])
933 self
.SetValue(['', dlg
.GetPath()[len(common
):]])
935 self
.textModified
= False
940 'style': ParamStyle
, 'exstyle': ParamExStyle
,
941 'pos': ParamPosSize
, 'size': ParamPosSize
,
942 'cellpos': ParamPosSize
, 'cellspan': ParamPosSize
,
943 'border': ParamUnit
, 'cols': ParamIntNN
, 'rows': ParamIntNN
,
944 'vgap': ParamUnit
, 'hgap': ParamUnit
,
945 'checkable': ParamBool
, 'checked': ParamBool
, 'radio': ParamBool
,
947 'label': ParamMultilineText
, 'title': ParamText
, 'value': ParamText
,
948 'content': ParamContent
, 'selection': ParamIntNN
,
949 'min': ParamInt
, 'max': ParamInt
,
950 'fg': ParamColour
, 'bg': ParamColour
, 'font': ParamFont
,
951 'enabled': ParamBool
, 'focused': ParamBool
, 'hidden': ParamBool
,
952 'tooltip': ParamText
, 'bitmap': ParamBitmap
, 'icon': ParamBitmap
,
953 'encoding': ParamEncoding
, 'borders': ParamUnit