2 # Purpose: Classes for parameter introduction
3 # Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
11 from wxPython
.xrc
import *
14 'wxSIMPLE_BORDER', 'wxDOUBLE_BORDER', 'wxSUNKEN_BORDER',
15 'wxRAISED_BORDER', 'wxSTATIC_BORDER', 'wxNO_BORDER',
16 'wxTRANSPARENT_WINDOW', 'wxTAB_TRAVERSAL',
18 'wxNO_FULL_REPAINT_ON_RESIZE',
19 'wxVSCROLL', 'wxHSCROLL', 'wxALWAYS_SHOW_SB',
21 'wxFULL_REPAINT_ON_RESIZE'
25 'wxWS_EX_VALIDATE_RECURSIVELY',
26 'wxWS_EX_BLOCK_EVENTS',
28 'wxFRAME_EX_CONTEXTHELP',
29 'wxWS_EX_PROCESS_IDLE',
30 'wxWS_EX_PROCESS_UI_UPDATES'
33 buttonSize
= (35,-1) # in dialog units, transformed to pixels in panel ctor
35 # Class that can properly disable children
36 class PPanel(wxPanel
):
37 def __init__(self
, parent
, name
):
38 wxPanel
.__init
__(self
, parent
, -1, name
=name
)
39 self
.modified
= self
.freeze
= False
40 def Enable(self
, value
):
41 # Something strange is going on with enable so we make sure...
42 for w
in self
.GetChildren():
44 wxPanel
.Enable(self
, value
)
45 def SetModified(self
):
47 g
.panel
.SetModified(True)
48 # Common method to set modified state
49 def OnChange(self
, evt
):
50 if self
.freeze
: return
54 class ParamBinaryOr(PPanel
):
55 def __init__(self
, parent
, name
):
56 PPanel
.__init
__(self
, parent
, name
)
57 self
.ID_TEXT_CTRL
= wxNewId()
58 self
.ID_BUTTON_CHOICES
= wxNewId()
60 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1))
61 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
62 self
.button
= wxButton(self
, self
.ID_BUTTON_CHOICES
, 'Edit...', size
=buttonSize
)
63 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
)
64 self
.SetAutoLayout(True)
67 EVT_BUTTON(self
, self
.ID_BUTTON_CHOICES
, self
.OnButtonChoices
)
68 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
70 return self
.text
.GetValue()
71 def SetValue(self
, value
):
73 self
.text
.SetValue(value
)
75 def OnButtonChoices(self
, evt
):
76 dlg
= g
.frame
.res
.LoadDialog(self
, 'DIALOG_CHOICES')
77 listBox
= XRCCTRL(dlg
, 'CHECK_LIST')
78 listBox
.InsertItems(self
.values
, 0)
79 value
= map(string
.strip
, self
.text
.GetValue().split('|'))
80 if value
== ['']: value
= []
84 listBox
.Check(self
.values
.index(i
))
87 if self
.equal
.has_key(i
):
88 listBox
.Check(self
.values
.index(self
.equal
[i
]))
90 print 'WARNING: unknown flag: %s: ignored.' % i
92 if dlg
.ShowModal() == wxID_OK
:
94 for i
in range(listBox
.GetCount()):
95 if listBox
.IsChecked(i
):
96 value
.append(self
.values
[i
])
100 self
.SetValue(reduce(lambda a
,b
: a
+'|'+b
, value
))
106 class ParamFlag(ParamBinaryOr
):
107 values
= ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL',
108 'wxEXPAND', 'wxGROW', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT',
110 'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL',
111 'wxALIGN_CENTRE_HORIZONTAL',
113 equal
= {'wxALIGN_CENTER': 'wxALIGN_CENTRE',
114 'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL',
115 'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL'}
116 def __init__(self
, parent
, name
):
117 ParamBinaryOr
.__init
__(self
, parent
, name
)
119 class ParamStyle(ParamBinaryOr
):
120 equal
= {'wxALIGN_CENTER': 'wxALIGN_CENTRE'}
121 def __init__(self
, parent
, name
):
122 self
.values
= g
.currentXXX
.winStyles
+ genericStyles
123 ParamBinaryOr
.__init
__(self
, parent
, name
)
125 class ParamNonGenericStyle(ParamBinaryOr
):
126 def __init__(self
, parent
, name
):
127 self
.values
= g
.currentXXX
.winStyles
128 ParamBinaryOr
.__init
__(self
, parent
, name
)
130 class ParamExStyle(ParamBinaryOr
):
131 def __init__(self
, parent
, name
):
133 self
.values
= g
.currentXXX
.exStyles
+ genericExStyles
136 ParamBinaryOr
.__init
__(self
, parent
, name
)
138 class ParamColour(PPanel
):
139 def __init__(self
, parent
, name
):
140 PPanel
.__init
__(self
, parent
, name
)
141 self
.ID_TEXT_CTRL
= wxNewId()
142 self
.ID_BUTTON
= wxNewId()
144 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(65,-1))
145 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
146 self
.button
= wxPanel(self
, self
.ID_BUTTON
, wxDefaultPosition
, wxSize(20, 1))
147 sizer
.Add(self
.button
, 0, wxGROW | wxALIGN_CENTER_VERTICAL
)
148 self
.SetAutoLayout(True)
151 self
.textModified
= False
152 EVT_PAINT(self
.button
, self
.OnPaintButton
)
153 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
154 EVT_LEFT_DOWN(self
.button
, self
.OnLeftDown
)
156 return self
.text
.GetValue()
157 def SetValue(self
, value
):
159 if not value
: value
= '#FFFFFF'
160 self
.text
.SetValue(str(value
)) # update text ctrl
161 colour
= wxColour(int(value
[1:3], 16), int(value
[3:5], 16), int(value
[5:7], 16))
162 self
.button
.SetBackgroundColour(colour
)
163 self
.button
.Refresh()
165 def OnPaintButton(self
, evt
):
166 dc
= wxPaintDC(self
.button
)
167 dc
.SetBrush(wxTRANSPARENT_BRUSH
)
168 if self
.IsEnabled(): dc
.SetPen(wxBLACK_PEN
)
169 else: dc
.SetPen(wxGREY_PEN
)
170 size
= self
.button
.GetSize()
171 dc
.DrawRectangle(0, 0, size
.width
, size
.height
)
172 def OnLeftDown(self
, evt
):
173 data
= wxColourData()
174 data
.SetColour(self
.GetValue())
175 dlg
= wxColourDialog(self
, data
)
176 if dlg
.ShowModal() == wxID_OK
:
177 self
.SetValue('#%02X%02X%02X' % dlg
.GetColourData().GetColour().Get())
181 ################################################################################
183 # Mapping from wx constants ro XML strings
184 fontFamiliesWx2Xml
= {wxDEFAULT
: 'default', wxDECORATIVE
: 'decorative',
185 wxROMAN
: 'roman', wxSCRIPT
: 'script', wxSWISS
: 'swiss',
187 fontStylesWx2Xml
= {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'}
188 fontWeightsWx2Xml
= {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'}
191 for k
,v
in m
.items(): rm
[v
] = k
193 fontFamiliesXml2wx
= ReverseMap(fontFamiliesWx2Xml
)
194 fontStylesXml2wx
= ReverseMap(fontStylesWx2Xml
)
195 fontWeightsXml2wx
= ReverseMap(fontWeightsWx2Xml
)
197 class ParamFont(PPanel
):
198 def __init__(self
, parent
, name
):
199 PPanel
.__init
__(self
, parent
, name
)
200 self
.ID_TEXT_CTRL
= wxNewId()
201 self
.ID_BUTTON_SELECT
= wxNewId()
203 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(200,-1))
204 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
205 self
.button
= wxButton(self
, self
.ID_BUTTON_SELECT
, 'Select...', size
=buttonSize
)
206 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
)
207 self
.SetAutoLayout(True)
210 self
.textModified
= False
211 EVT_BUTTON(self
, self
.ID_BUTTON_SELECT
, self
.OnButtonSelect
)
212 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
213 def OnChange(self
, evt
):
214 PPanel
.OnChange(self
, evt
)
215 self
.textModified
= True
216 def _defaultValue(self
):
217 return ['12', 'default', 'normal', 'normal', '0', '', '']
219 if self
.textModified
: # text has newer value
221 return eval(self
.text
.GetValue())
223 wxLogError('Syntax error in parameter value: ' + self
.GetName())
224 return self
._defaultValue
()
226 def SetValue(self
, value
):
227 self
.freeze
= True # disable other handlers
228 if not value
: value
= self
._defaultValue
()
230 self
.text
.SetValue(str(value
)) # update text ctrl
232 def OnButtonSelect(self
, evt
):
233 if self
.textModified
: # text has newer value
235 self
.value
= eval(self
.text
.GetValue())
237 wxLogError('Syntax error in parameter value: ' + self
.GetName())
238 self
.value
= self
._defaultValue
()
243 style
= weight
= wxNORMAL
246 enc
= wxFONTENCODING_DEFAULT
247 # Fall back to default if exceptions
250 try: size
= int(self
.value
[0])
251 except ValueError: error
= True; wxLogError('Invalid size specification')
252 try: family
= fontFamiliesXml2wx
[self
.value
[1]]
253 except KeyError: error
= True; wxLogError('Invalid family specification')
254 try: style
= fontStylesXml2wx
[self
.value
[2]]
255 except KeyError: error
= True; wxLogError('Invalid style specification')
256 try: weight
= fontWeightsXml2wx
[self
.value
[3]]
257 except KeyError: error
= True; wxLogError('Invalid weight specification')
258 try: underlined
= bool(self
.value
[4])
259 except ValueError: error
= True; wxLogError('Invalid underlined flag specification')
263 mapper
= wxFontMapper()
264 if not self
.value
[6]: enc
= mapper
.CharsetToEncoding(self
.value
[6])
266 if error
: wxLogError('Invalid font specification')
267 if enc
== wxFONTENCODING_DEFAULT
: enc
= wxFONTENCODING_SYSTEM
268 font
= wxFont(size
, family
, style
, weight
, underlined
, face
, enc
)
270 data
.SetInitialFont(font
)
271 dlg
= wxFontDialog(self
, data
)
272 if dlg
.ShowModal() == wxID_OK
:
273 font
= dlg
.GetFontData().GetChosenFont()
274 print font
.GetEncoding()
275 if font
.GetEncoding() == wxFONTENCODING_SYSTEM
:
278 encName
= wxFontMapper_GetEncodingName(font
.GetEncoding()).encode()
279 value
= [str(font
.GetPointSize()),
280 fontFamiliesWx2Xml
.get(font
.GetFamily(), "default"),
281 fontStylesWx2Xml
.get(font
.GetStyle(), "normal"),
282 fontWeightsWx2Xml
.get(font
.GetWeight(), "normal"),
283 str(int(font
.GetUnderlined())),
284 font
.GetFaceName().encode(),
290 self
.textModified
= False
293 ################################################################################
295 class ParamInt(PPanel
):
296 def __init__(self
, parent
, name
):
297 PPanel
.__init
__(self
, parent
, name
)
298 self
.ID_SPIN_CTRL
= wxNewId()
300 self
.spin
= wxSpinCtrl(self
, self
.ID_SPIN_CTRL
, size
=(50,-1))
302 self
.SetAutoLayout(True)
305 EVT_SPINCTRL(self
, self
.ID_SPIN_CTRL
, self
.OnChange
)
307 return str(self
.spin
.GetValue())
308 def SetValue(self
, value
):
310 if not value
: value
= 0
311 self
.spin
.SetValue(int(value
))
314 # Same as int but allows dialog units (XXXd)
315 class ParamUnit(PPanel
):
316 def __init__(self
, parent
, name
):
317 PPanel
.__init
__(self
, parent
, name
)
318 self
.ID_TEXT_CTRL
= wxNewId()
319 self
.ID_SPIN_BUTTON
= wxNewId()
321 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(35,-1))
322 self
.spin
= wxSpinButton(self
, self
.ID_SPIN_BUTTON
, style
= wxSP_VERTICAL
, size
=(-1,1))
323 self
.spin
.SetRange(-10000, 10000)
324 sizer
.Add(self
.text
, 0, wxEXPAND | wxRIGHT
, 2)
325 sizer
.Add(self
.spin
, 0, wxEXPAND
)
326 self
.SetAutoLayout(True)
329 EVT_SPIN_UP(self
, self
.ID_SPIN_BUTTON
, self
.OnSpinUp
)
330 EVT_SPIN_DOWN(self
, self
.ID_SPIN_BUTTON
, self
.OnSpinDown
)
332 return self
.text
.GetValue()
333 def SetValue(self
, value
):
335 if not value
: value
= '0'
336 self
.text
.SetValue(value
)
339 # Check if we are working with dialog units
340 value
= self
.text
.GetValue()
342 if value
[-1].upper() == 'D':
346 intValue
= int(value
) + x
347 self
.spin
.SetValue(intValue
)
348 self
.text
.SetValue(str(intValue
) + units
)
351 # !!! Strange, if I use wxLogWarning, event is re-generated
352 print 'incorrect unit format'
353 def OnSpinUp(self
, evt
):
355 def OnSpinDown(self
, evt
):
358 class ParamMultilineText(PPanel
):
359 def __init__(self
, parent
, name
, textWidth
=-1):
360 PPanel
.__init
__(self
, parent
, name
)
361 self
.ID_TEXT_CTRL
= wxNewId()
362 self
.ID_BUTTON_EDIT
= wxNewId()
364 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1))
365 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
366 self
.button
= wxButton(self
, self
.ID_BUTTON_EDIT
, 'Edit...', size
=buttonSize
)
367 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
)
368 self
.SetAutoLayout(True)
371 EVT_BUTTON(self
, self
.ID_BUTTON_EDIT
, self
.OnButtonEdit
)
372 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
374 return self
.text
.GetValue()
375 def SetValue(self
, value
):
376 self
.freeze
= True # disable other handlers
377 self
.text
.SetValue(value
)
378 self
.freeze
= False # disable other handlers
379 def OnButtonEdit(self
, evt
):
380 dlg
= g
.frame
.res
.LoadDialog(self
, 'DIALOG_TEXT')
381 textCtrl
= XRCCTRL(dlg
, 'TEXT')
382 textCtrl
.SetValue(self
.text
.GetValue())
383 if dlg
.ShowModal() == wxID_OK
:
384 self
.text
.SetValue(textCtrl
.GetValue())
388 class ParamText(PPanel
):
389 def __init__(self
, parent
, name
, textWidth
=-1):
390 PPanel
.__init
__(self
, parent
, name
)
391 self
.ID_TEXT_CTRL
= wxNewId()
392 # We use sizer even here to have the same size of text control
394 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(textWidth
,-1))
395 if textWidth
== -1: option
= 1
397 sizer
.Add(self
.text
, option
, wxALIGN_CENTER_VERTICAL
)
398 self
.SetAutoLayout(True)
401 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
403 return self
.text
.GetValue()
404 def SetValue(self
, value
):
405 self
.freeze
= True # disable other handlers
406 self
.text
.SetValue(value
)
407 self
.freeze
= False # disable other handlers
409 class ParamAccel(ParamText
):
410 def __init__(self
, parent
, name
):
411 ParamText
.__init
__(self
, parent
, name
, 100)
413 class ParamPosSize(ParamText
):
414 def __init__(self
, parent
, name
):
415 ParamText
.__init
__(self
, parent
, name
, 80)
417 class ParamLabel(ParamText
):
418 def __init__(self
, parent
, name
):
419 ParamText
.__init
__(self
, parent
, name
, 200)
421 class ParamEncoding(ParamText
):
422 def __init__(self
, parent
, name
):
423 ParamText
.__init
__(self
, parent
, name
, 100)
425 class ContentDialog(wxDialog
):
426 def __init__(self
, parent
, value
):
429 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_CONTENT')
431 self
._setOORInfo
(self
)
432 self
.list = XRCCTRL(self
, 'LIST')
436 self
.SetAutoLayout(True)
437 self
.GetSizer().Fit(self
)
439 self
.ID_BUTTON_APPEND
= XRCID('BUTTON_APPEND')
440 self
.ID_BUTTON_REMOVE
= XRCID('BUTTON_REMOVE')
441 self
.ID_BUTTON_UP
= XRCID('BUTTON_UP')
442 self
.ID_BUTTON_DOWN
= XRCID('BUTTON_DOWN')
443 EVT_BUTTON(self
, self
.ID_BUTTON_UP
, self
.OnButtonUp
)
444 EVT_BUTTON(self
, self
.ID_BUTTON_DOWN
, self
.OnButtonDown
)
445 EVT_BUTTON(self
, self
.ID_BUTTON_APPEND
, self
.OnButtonAppend
)
446 EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
447 EVT_UPDATE_UI(self
, self
.ID_BUTTON_UP
, self
.OnUpdateUI
)
448 EVT_UPDATE_UI(self
, self
.ID_BUTTON_DOWN
, self
.OnUpdateUI
)
449 EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
450 def OnButtonUp(self
, evt
):
451 i
= self
.list.GetSelection()
452 str = self
.list.GetString(i
)
454 self
.list.InsertItems([str], i
-1)
455 self
.list.SetSelection(i
-1)
456 def OnButtonDown(self
, evt
):
457 i
= self
.list.GetSelection()
458 str = self
.list.GetString(i
)
460 self
.list.InsertItems([str], i
+1)
461 self
.list.SetSelection(i
+1)
462 def OnButtonAppend(self
, evt
):
463 str = wxGetTextFromUser('Enter new item:', 'Append', '', self
)
464 self
.list.Append(str)
465 def OnButtonRemove(self
, evt
):
466 self
.list.Delete(self
.list.GetSelection())
467 def OnUpdateUI(self
, evt
):
468 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
469 evt
.Enable(self
.list.GetSelection() != -1)
470 elif evt
.GetId() == self
.ID_BUTTON_UP
:
471 evt
.Enable(self
.list.GetSelection() > 0)
472 elif evt
.GetId() == self
.ID_BUTTON_DOWN
:
473 evt
.Enable(self
.list.GetSelection() != -1 and \
474 self
.list.GetSelection() < self
.list.GetCount() - 1)
476 class ContentCheckListDialog(wxDialog
):
477 def __init__(self
, parent
, value
):
479 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_CONTENT_CHECK_LIST')
481 self
._setOORInfo
(self
)
482 self
.list = XRCCTRL(self
, 'CHECK_LIST')
487 self
.list.Check(i
, ch
)
489 self
.SetAutoLayout(True)
490 self
.GetSizer().Fit(self
)
492 self
.ID_BUTTON_APPEND
= XRCID('BUTTON_APPEND')
493 self
.ID_BUTTON_REMOVE
= XRCID('BUTTON_REMOVE')
494 self
.ID_BUTTON_UP
= XRCID('BUTTON_UP')
495 self
.ID_BUTTON_DOWN
= XRCID('BUTTON_DOWN')
496 EVT_CHECKLISTBOX(self
, self
.list.GetId(), self
.OnCheck
)
497 EVT_BUTTON(self
, self
.ID_BUTTON_UP
, self
.OnButtonUp
)
498 EVT_BUTTON(self
, self
.ID_BUTTON_DOWN
, self
.OnButtonDown
)
499 EVT_BUTTON(self
, self
.ID_BUTTON_APPEND
, self
.OnButtonAppend
)
500 EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
501 EVT_UPDATE_UI(self
, self
.ID_BUTTON_UP
, self
.OnUpdateUI
)
502 EVT_UPDATE_UI(self
, self
.ID_BUTTON_DOWN
, self
.OnUpdateUI
)
503 EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
504 def OnCheck(self
, evt
):
505 # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking
506 self
.list.Deselect(evt
.GetSelection())
507 def OnButtonUp(self
, evt
):
508 i
= self
.list.GetSelection()
509 str, ch
= self
.list.GetString(i
), self
.list.IsChecked(i
)
511 self
.list.InsertItems([str], i
-1)
512 self
.list.Check(i
-1, ch
)
513 self
.list.SetSelection(i
-1)
514 def OnButtonDown(self
, evt
):
515 i
= self
.list.GetSelection()
516 str, ch
= self
.list.GetString(i
), self
.list.IsChecked(i
)
518 self
.list.InsertItems([str], i
+1)
519 self
.list.Check(i
+1, ch
)
520 self
.list.SetSelection(i
+1)
521 def OnButtonAppend(self
, evt
):
522 str = wxGetTextFromUser('Enter new item:', 'Append', '', self
)
523 self
.list.Append(str)
524 def OnButtonRemove(self
, evt
):
525 self
.list.Delete(self
.list.GetSelection())
526 def OnUpdateUI(self
, evt
):
527 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
528 evt
.Enable(self
.list.GetSelection() != -1)
529 elif evt
.GetId() == self
.ID_BUTTON_UP
:
530 evt
.Enable(self
.list.GetSelection() > 0)
531 elif evt
.GetId() == self
.ID_BUTTON_DOWN
:
532 evt
.Enable(self
.list.GetSelection() != -1 and \
533 self
.list.GetSelection() < self
.list.GetCount() - 1)
535 class ParamContent(PPanel
):
536 def __init__(self
, parent
, name
):
537 PPanel
.__init
__(self
, parent
, name
)
538 self
.ID_TEXT_CTRL
= wxNewId()
539 self
.ID_BUTTON_EDIT
= wxNewId()
541 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1))
542 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
543 self
.button
= wxButton(self
, self
.ID_BUTTON_EDIT
, 'Edit...', size
=buttonSize
)
544 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
)
545 self
.SetAutoLayout(True)
548 self
.textModified
= False
549 EVT_BUTTON(self
, self
.ID_BUTTON_EDIT
, self
.OnButtonEdit
)
550 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
551 def OnChange(self
, evt
):
552 PPanel
.OnChange(self
, evt
)
553 self
.textModified
= True
555 if self
.textModified
: # text has newer value
557 return eval(self
.text
.GetValue())
559 wxLogError('Syntax error in parameter value: ' + self
.GetName())
562 def SetValue(self
, value
):
564 if not value
: value
= []
566 self
.text
.SetValue(str(value
)) # update text ctrl
568 def OnButtonEdit(self
, evt
):
569 if self
.textModified
: # text has newer value
571 self
.value
= eval(self
.text
.GetValue())
573 wxLogError('Syntax error in parameter value: ' + self
.GetName())
575 dlg
= ContentDialog(self
, self
.value
)
576 if dlg
.ShowModal() == wxID_OK
:
578 for i
in range(dlg
.list.GetCount()):
579 value
.append(dlg
.list.GetString(i
))
583 self
.textModified
= False
587 class ParamContentCheckList(ParamContent
):
588 def __init__(self
, parent
, name
):
589 ParamContent
.__init
__(self
, parent
, name
)
590 def OnButtonEdit(self
, evt
):
591 if self
.textModified
: # text has newer value
593 self
.value
= eval(self
.text
.GetValue())
595 wxLogError('Syntax error in parameter value: ' + self
.GetName())
597 dlg
= ContentCheckListDialog(self
, self
.value
)
598 if dlg
.ShowModal() == wxID_OK
:
600 for i
in range(dlg
.list.GetCount()):
601 value
.append((dlg
.list.GetString(i
), dlg
.list.IsChecked(i
)))
605 self
.textModified
= False
608 class IntListDialog(wxDialog
):
609 def __init__(self
, parent
, value
):
611 g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_INTLIST')
613 self
._setOORInfo
(self
)
614 self
.list = XRCCTRL(self
, 'LIST')
618 if type(v
) != IntType
:
619 wxLogError('Invalid item type')
621 self
.list.Append(str(v
))
622 self
.SetAutoLayout(True)
623 self
.GetSizer().Fit(self
)
625 self
.ID_BUTTON_ADD
= XRCID('BUTTON_ADD')
626 self
.ID_BUTTON_REMOVE
= XRCID('BUTTON_REMOVE')
627 EVT_BUTTON(self
, self
.ID_BUTTON_ADD
, self
.OnButtonAppend
)
628 EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
)
629 EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
)
630 def OnButtonAppend(self
, evt
):
631 s
= wxGetTextFromUser('Enter new number:', 'Add', '', self
)
633 # Check that it's unique
636 s
= str(v
) # to be sure
637 i
= self
.list.FindString(s
)
638 if i
== -1: # ignore non-unique
639 # Find place to insert
641 for i
in range(self
.list.GetCount()):
642 if int(self
.list.GetString(i
)) > v
:
645 if found
: self
.list.InsertItems([s
], i
)
646 else: self
.list.Append(s
)
648 wxLogError('List item is not an int!')
649 def OnButtonRemove(self
, evt
):
650 self
.list.Delete(self
.list.GetSelection())
651 def OnUpdateUI(self
, evt
):
652 if evt
.GetId() == self
.ID_BUTTON_REMOVE
:
653 evt
.Enable(self
.list.GetSelection() != -1)
656 class ParamIntList(ParamContent
):
657 def __init__(self
, parent
, name
):
658 ParamContent
.__init
__(self
, parent
, name
)
659 def OnButtonEdit(self
, evt
):
660 if self
.textModified
: # text has newer value
662 self
.value
= eval(self
.text
.GetValue())
664 wxLogError('Syntax error in parameter value: ' + self
.GetName())
666 dlg
= IntListDialog(self
, self
.value
)
667 if dlg
.ShowModal() == wxID_OK
:
669 for i
in range(dlg
.list.GetCount()):
670 value
.append(int(dlg
.list.GetString(i
)))
674 self
.textModified
= False
678 class RadioBox(PPanel
):
679 def __init__(self
, parent
, id, choices
,
680 pos
=wxDefaultPosition
, name
='radiobox'):
681 PPanel
.__init
__(self
, parent
, name
)
682 self
.choices
= choices
683 topSizer
= wxBoxSizer()
685 button
= wxRadioButton(self
, -1, i
, size
=(-1,buttonSize
[1]), name
=i
)
686 topSizer
.Add(button
, 0, wxRIGHT
, 5)
687 EVT_RADIOBUTTON(self
, button
.GetId(), self
.OnRadioChoice
)
688 self
.SetAutoLayout(True)
689 self
.SetSizer(topSizer
)
691 def SetStringSelection(self
, value
):
693 for i
in self
.choices
:
694 self
.FindWindowByName(i
).SetValue(i
== value
)
697 def OnRadioChoice(self
, evt
):
698 if self
.freeze
: return
699 if evt
.GetSelection():
700 self
.value
= evt
.GetEventObject().GetName()
702 def GetStringSelection(self
):
705 class ParamBool(RadioBox
):
706 values
= {'yes': '1', 'no': '0'}
707 seulav
= {'1': 'yes', '0': 'no'}
708 def __init__(self
, parent
, name
):
709 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
711 return self
.values
[self
.GetStringSelection()]
712 def SetValue(self
, value
):
713 if not value
: value
= '1'
714 self
.SetStringSelection(self
.seulav
[value
])
716 class ParamOrient(RadioBox
):
717 values
= {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
718 seulav
= {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'}
719 def __init__(self
, parent
, name
):
720 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
722 return self
.values
[self
.GetStringSelection()]
723 def SetValue(self
, value
):
724 if not value
: value
= 'wxHORIZONTAL'
725 self
.SetStringSelection(self
.seulav
[value
])
727 class ParamOrientation(RadioBox
):
728 values
= {'horizontal': 'horizontal', 'vertical': 'vertical'}
729 seulav
= {'horizontal': 'horizontal', 'vertical': 'vertical'}
730 def __init__(self
, parent
, name
):
731 RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
)
733 return self
.values
[self
.GetStringSelection()]
734 def SetValue(self
, value
):
735 if not value
: value
= 'vertical'
736 self
.SetStringSelection(self
.seulav
[value
])
738 class ParamFile(PPanel
):
739 def __init__(self
, parent
, name
):
740 PPanel
.__init
__(self
, parent
, name
)
741 self
.ID_TEXT_CTRL
= wxNewId()
742 self
.ID_BUTTON_BROWSE
= wxNewId()
744 self
.text
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1))
745 sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5)
746 self
.button
= wxButton(self
, self
.ID_BUTTON_BROWSE
, 'Browse...',size
=buttonSize
)
747 sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
)
748 self
.SetAutoLayout(True)
751 self
.textModified
= False
752 EVT_BUTTON(self
, self
.ID_BUTTON_BROWSE
, self
.OnButtonBrowse
)
753 EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
)
754 def OnChange(self
, evt
):
755 PPanel
.OnChange(self
, evt
)
756 self
.textModified
= True
758 if self
.textModified
: # text has newer value
759 return self
.text
.GetValue()
761 def SetValue(self
, value
):
764 self
.text
.SetValue(value
) # update text ctrl
766 def OnButtonBrowse(self
, evt
):
767 if self
.textModified
: # text has newer value
768 self
.value
= self
.text
.GetValue()
769 dlg
= wxFileDialog(self
,
770 defaultDir
= os
.path
.abspath(os
.path
.dirname(self
.value
)),
771 defaultFile
= os
.path
.basename(self
.value
))
772 if dlg
.ShowModal() == wxID_OK
:
773 # Get common part of selected path and current
775 curpath
= os
.path
.abspath(g
.frame
.dataFile
)
777 curpath
= os
.path
.join(os
.getcwd(), '')
778 common
= os
.path
.commonprefix([curpath
, dlg
.GetPath()])
779 self
.SetValue(dlg
.GetPath()[len(common
):])
781 self
.textModified
= False
784 class ParamBitmap(PPanel
):
785 def __init__(self
, parent
, name
):
787 g
.frame
.res
.LoadOnPanel(pre
, parent
, 'PANEL_BITMAP')
789 self
._setOORInfo
(self
)
790 self
.modified
= self
.freeze
= False
791 self
.radio_std
= XRCCTRL(self
, 'RADIO_STD')
792 self
.radio_file
= XRCCTRL(self
, 'RADIO_FILE')
793 self
.combo
= XRCCTRL(self
, 'COMBO_STD')
794 self
.text
= XRCCTRL(self
, 'TEXT_FILE')
795 self
.button
= XRCCTRL(self
, 'BUTTON_BROWSE')
796 self
.textModified
= False
797 self
.SetAutoLayout(True)
798 self
.GetSizer().SetMinSize((260, -1))
799 self
.GetSizer().Fit(self
)
800 EVT_RADIOBUTTON(self
, XRCID('RADIO_STD'), self
.OnRadioStd
)
801 EVT_RADIOBUTTON(self
, XRCID('RADIO_FILE'), self
.OnRadioFile
)
802 EVT_BUTTON(self
, XRCID('BUTTON_BROWSE'), self
.OnButtonBrowse
)
803 EVT_COMBOBOX(self
, XRCID('COMBO_STD'), self
.OnCombo
)
804 EVT_TEXT(self
, XRCID('COMBO_STD'), self
.OnChange
)
805 EVT_TEXT(self
, XRCID('TEXT_FILE'), self
.OnChange
)
806 def OnRadioStd(self
, evt
):
808 self
.SetValue(['wxART_MISSING_IMAGE',''])
809 def OnRadioFile(self
, evt
):
811 self
.SetValue(['',''])
812 def updateRadios(self
):
814 self
.radio_std
.SetValue(True)
815 self
.radio_file
.SetValue(False)
816 self
.text
.Enable(False)
817 self
.button
.Enable(False)
818 self
.combo
.Enable(True)
820 self
.radio_std
.SetValue(False)
821 self
.radio_file
.SetValue(True)
822 self
.text
.Enable(True)
823 self
.button
.Enable(True)
824 self
.combo
.Enable(False)
825 def OnChange(self
, evt
):
826 PPanel
.OnChange(self
, evt
)
827 self
.textModified
= True
828 def OnCombo(self
, evt
):
829 PPanel
.OnChange(self
, evt
)
830 self
.value
[0] = self
.combo
.GetValue()
832 if self
.textModified
: # text has newer value
833 return [self
.combo
.GetValue(), self
.text
.GetValue()]
835 def SetValue(self
, value
):
838 self
.value
= ['', '']
841 self
.combo
.SetValue(self
.value
[0])
842 self
.text
.SetValue(self
.value
[1]) # update text ctrl
845 def OnButtonBrowse(self
, evt
):
846 if self
.textModified
: # text has newer value
847 self
.value
[1] = self
.text
.GetValue()
848 dlg
= wxFileDialog(self
,
849 defaultDir
= os
.path
.abspath(os
.path
.dirname(self
.value
[1])),
850 defaultFile
= os
.path
.basename(self
.value
[1]))
851 if dlg
.ShowModal() == wxID_OK
:
852 # Get common part of selected path and current
854 curpath
= os
.path
.abspath(g
.frame
.dataFile
)
856 curpath
= os
.path
.join(os
.getcwd(), '')
857 common
= os
.path
.commonprefix([curpath
, dlg
.GetPath()])
858 self
.SetValue(['', dlg
.GetPath()[len(common
):]])
860 self
.textModified
= False
865 'style': ParamStyle
, 'exstyle': ParamExStyle
,
866 'pos': ParamPosSize
, 'size': ParamPosSize
,
867 'cellpos': ParamPosSize
, 'cellspan': ParamPosSize
,
868 'border': ParamUnit
, 'cols': ParamInt
, 'rows': ParamInt
,
869 'vgap': ParamUnit
, 'hgap': ParamUnit
,
870 'checkable': ParamBool
, 'checked': ParamBool
, 'radio': ParamBool
,
872 'label': ParamMultilineText
, 'title': ParamText
, 'value': ParamText
,
873 'content': ParamContent
, 'selection': ParamInt
,
874 'min': ParamInt
, 'max': ParamInt
,
875 'fg': ParamColour
, 'bg': ParamColour
, 'font': ParamFont
,
876 'enabled': ParamBool
, 'focused': ParamBool
, 'hidden': ParamBool
,
877 'tooltip': ParamText
, 'bitmap': ParamBitmap
, 'icon': ParamBitmap
,
878 'encoding': ParamEncoding