+ self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=(65,-1))
+ sizer.Add(self.text, 0, wxRIGHT, 5)
+ self.button = wxPanel(self, self.ID_BUTTON, wxDefaultPosition, wxSize(40, -1))
+ sizer.Add(self.button, 0, wxGROW)
+ self.SetAutoLayout(true)
+ self.SetSizer(sizer)
+ sizer.Fit(self)
+ self.textModified = false
+ EVT_PAINT(self.button, self.OnPaintButton)
+ EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
+ EVT_LEFT_DOWN(self.button, self.OnLeftDown)
+ def GetValue(self):
+ return self.text.GetValue()
+ def SetValue(self, value):
+ self.freeze = true
+ if not value: value = '#FFFFFF'
+ self.text.SetValue(str(value)) # update text ctrl
+ colour = wxColour(int(value[1:3], 16), int(value[3:5], 16), int(value[5:7], 16))
+ self.button.SetBackgroundColour(colour)
+ self.button.Refresh()
+ self.freeze = false
+ def OnChange(self, evt):
+ if self.freeze: return
+ self.SetModified()
+ evt.Skip()
+ def OnPaintButton(self, evt):
+ dc = wxPaintDC(self.button)
+ dc.SetBrush(wxTRANSPARENT_BRUSH)
+ if self.IsEnabled(): dc.SetPen(wxBLACK_PEN)
+ else: dc.SetPen(wxGREY_PEN)
+ size = self.button.GetSize()
+ dc.DrawRectangle(0, 0, size.x, size.y)
+ def OnLeftDown(self, evt):
+ data = wxColourData()
+ data.SetColour(self.GetValue())
+ dlg = wxColourDialog(self, data)
+ if dlg.ShowModal() == wxID_OK:
+ self.SetValue('#%02X%02X%02X' % dlg.GetColourData().GetColour().Get())
+ self.SetModified()
+ dlg.Destroy()
+
+################################################################################
+
+# Mapping from wx constants ro XML strings
+fontFamiliesWx2Xml = {wxDEFAULT: 'default', wxDECORATIVE: 'decorative',
+ wxROMAN: 'roman', wxSCRIPT: 'script', wxSWISS: 'swiss',
+ wxMODERN: 'modern'}
+fontStylesWx2Xml = {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'}
+fontWeightsWx2Xml = {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'}
+def ReverseMap(m):
+ rm = {}
+ for k,v in m.items(): rm[v] = k
+ return rm
+fontFamiliesXml2wx = ReverseMap(fontFamiliesWx2Xml)
+fontStylesXml2wx = ReverseMap(fontStylesWx2Xml)
+fontWeightsXml2wx = ReverseMap(fontWeightsWx2Xml)
+
+class ParamFont(PPanel):
+ def __init__(self, parent, name):
+ PPanel.__init__(self, parent, name)
+ self.ID_TEXT_CTRL = wxNewId()
+ self.ID_BUTTON_SELECT = wxNewId()
+ self.SetBackgroundColour(panel.GetBackgroundColour())
+ sizer = wxBoxSizer()
+ self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
+ sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
+ self.button = wxButton(self, self.ID_BUTTON_SELECT, 'Select...', size=buttonSize)
+ sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
+ self.SetAutoLayout(true)
+ self.SetSizer(sizer)
+ sizer.Fit(self)
+ self.textModified = false
+ EVT_BUTTON(self, self.ID_BUTTON_SELECT, self.OnButtonSelect)
+ EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
+ def OnChange(self, evt):
+ if self.freeze: return
+ self.SetModified()
+ self.textModified = true
+ evt.Skip()
+ def _defaultValue(self):
+ return ['12', 'default', 'normal', 'normal', '0', '', '']
+ def GetValue(self):
+ if self.textModified: # text has newer value
+ try:
+ return eval(self.text.GetValue())
+ except SyntaxError:
+ wxLogError('Syntax error in parameter value: ' + self.GetName())
+ return self._defaultValue()
+ return self.value
+ def SetValue(self, value):
+ self.freeze = true # disable other handlers
+ if not value: value = self._defaultValue()
+ self.value = value
+ self.text.SetValue(str(value)) # update text ctrl
+ self.freeze = false
+ def OnButtonSelect(self, evt):
+ if self.textModified: # text has newer value
+ try:
+ self.value = eval(self.text.GetValue())
+ except SyntaxError:
+ wxLogError('Syntax error in parameter value: ' + self.GetName())
+ self.value = self._defaultValue()
+ # Make initial font
+ # Default values
+ size = 12
+ family = wxDEFAULT
+ style = weight = wxNORMAL
+ underlined = 0
+ face = ''
+ enc = wxFONTENCODING_DEFAULT
+ # Fall back to default if exceptions
+ error = false
+ try:
+ try: size = int(self.value[0])
+ except ValueError: error = true
+ try: family = fontFamiliesXml2wx[self.value[1]]
+ except KeyError: error = true
+ try: style = fontStylesXml2wx[self.value[2]]
+ except KeyError: error = true
+ try: weight = fontWeightsXml2wx[self.value[3]]
+ except KeyError: error = true
+ try: underlined = int(self.value[4])
+ except ValueError: error = true
+ face = self.value[5]
+ mapper = wxFontMapper()
+ if not self.value[6]: enc = mapper.CharsetToEncoding(self.value[6])
+ except IndexError:
+ error = true
+ if error: wxLogError('Invalid font specification')
+ if enc == wxFONTENCODING_DEFAULT: enc = wxFONTENCODING_SYSTEM
+ font = wxFont(size, family, style, weight, underlined, face, enc)
+ data = wxFontData()
+ data.SetInitialFont(font)
+ dlg = wxFontDialog(self, data)
+ if dlg.ShowModal() == wxID_OK:
+ font = dlg.GetFontData().GetChosenFont()
+ value = [str(font.GetPointSize()),
+ fontFamiliesWx2Xml.get(font.GetFamily(), "default"),
+ fontStylesWx2Xml.get(font.GetStyle(), "normal"),
+ fontWeightsWx2Xml.get(font.GetWeight(), "normal"),
+ str(font.GetUnderlined()),
+ font.GetFaceName(),
+ wxFontMapper_GetEncodingName(font.GetEncoding())
+ ]
+ # Add ignored flags
+ self.SetValue(value)
+ self.SetModified()
+ self.textModified = false
+ dlg.Destroy()
+
+################################################################################
+
+class ParamInt(PPanel):
+ def __init__(self, parent, name):
+ PPanel.__init__(self, parent, name)
+ self.ID_SPIN_CTRL = wxNewId()
+ sizer = wxBoxSizer()
+ self.spin = wxSpinCtrl(self, self.ID_SPIN_CTRL, size=wxSize(50,-1))