Files
wxWidgets/wxPython/wx/tools/XRCed/params.py
Roman Rolinsky b372319fa0 Implemented xxxComment. Due to different minidom XML types (Comments
are not Elements) had to add xxxObject.isElement flag and changed
xxxObject.element variable to xxxObject.node (xxxComment is derived
from xxxObject to minimize changes in processing). More testing is still
needed to verify that things didn't break. Use previous commit (0.1.8-4
release on 2007/03/10) if you need a stable version.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44764 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2007-03-11 05:08:45 +00:00

936 lines
38 KiB
Python

# Name: params.py
# Purpose: Classes for parameter introduction
# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
# Created: 22.08.2001
# RCS-ID: $Id$
import string
import os.path
from globals import *
from types import *
genericStyles = [
'wxSIMPLE_BORDER', 'wxSUNKEN_BORDER', 'wxDOUBLE_BORDER',
'wxRAISED_BORDER', 'wxSTATIC_BORDER', 'wxNO_BORDER',
'wxCLIP_CHILDREN', 'wxTRANSPARENT_WINDOW', 'wxWANTS_CHARS',
'wxNO_FULL_REPAINT_ON_RESIZE', 'wxFULL_REPAINT_ON_RESIZE'
]
genericExStyles = [
'wxWS_EX_VALIDATE_RECURSIVELY',
'wxWS_EX_BLOCK_EVENTS',
'wxWS_EX_TRANSIENT',
'wxFRAME_EX_CONTEXTHELP',
'wxWS_EX_PROCESS_IDLE',
'wxWS_EX_PROCESS_UI_UPDATES'
]
# Global var initialized in Panel.__init__ for button size in screen pixels
buttonSize = None
# Button size in dialog units
buttonSizeD = (35,-1)
# Class that can properly disable children
class PPanel(wx.Panel):
def __init__(self, parent, name):
wx.Panel.__init__(self, parent, -1, name=name)
self.modified = self.freeze = False
def Enable(self, value):
# Something strange is going on with enable so we make sure...
for w in self.GetChildren():
w.Enable(value)
#wx.Panel.Enable(self, value)
def SetModified(self, state=True):
self.modified = state
if state: g.panel.SetModified(True)
# Common method to set modified state
def OnChange(self, evt):
if self.freeze: return
self.SetModified()
evt.Skip()
class ParamBinaryOr(PPanel):
def __init__(self, parent, name):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wx.NewId()
self.ID_BUTTON_CHOICES = wx.NewId()
sizer = wx.BoxSizer()
self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=wx.Size(200,-1))
sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
self.button = wx.Button(self, self.ID_BUTTON_CHOICES, 'Edit...', size=buttonSize)
sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL)
self.SetSizer(sizer)
wx.EVT_BUTTON(self, self.ID_BUTTON_CHOICES, self.OnButtonChoices)
wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
def GetValue(self):
return self.text.GetValue()
def SetValue(self, value):
self.freeze = True
self.text.SetValue(value)
self.freeze = False
def OnButtonChoices(self, evt):
dlg = g.frame.res.LoadDialog(self, 'DIALOG_CHOICES')
if self.GetName() == 'flag': dlg.SetTitle('Sizer item flags')
elif self.GetName() == 'style': dlg.SetTitle('Window styles')
elif self.GetName() == 'exstyle': dlg.SetTitle('Extended window styles')
listBox = xrc.XRCCTRL(dlg, 'CHECKLIST')
listBox.InsertItems(self.values, 0)
value = map(string.strip, self.text.GetValue().split('|'))
if value == ['']: value = []
ignored = []
for i in value:
try:
listBox.Check(self.values.index(i))
except ValueError:
# Try to find equal
if self.equal.has_key(i):
listBox.Check(self.values.index(self.equal[i]))
else:
print 'WARNING: unknown flag: %s: ignored.' % i
ignored.append(i)
if dlg.ShowModal() == wx.ID_OK:
value = []
for i in range(listBox.GetCount()):
if listBox.IsChecked(i):
value.append(self.values[i])
# Add ignored flags
value.extend(ignored)
self.SetValue('|'.join(value))
self.SetModified()
dlg.Destroy()
class ParamFlag(ParamBinaryOr):
values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL',
'wxEXPAND', 'wxGROW', 'wxSHAPED', 'wxSTRETCH_NOT',
'wxALIGN_CENTRE', 'wxALIGN_LEFT', 'wxALIGN_RIGHT',
'wxALIGN_TOP', 'wxALIGN_BOTTOM',
'wxALIGN_CENTRE_VERTICAL', 'wxALIGN_CENTRE_HORIZONTAL',
'wxADJUST_MINSIZE', 'wxFIXED_MINSIZE'
]
equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE',
'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL',
'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL',
'wxUP': 'wxTOP', 'wxDOWN': 'wxBOTTOM', 'wxNORTH': 'wxTOP',
'wxSOUTH': 'wxBOTTOM', 'wxWEST': 'wxLEFT', 'wxEAST': 'wxRIGHT'}
def __init__(self, parent, name):
ParamBinaryOr.__init__(self, parent, name)
class ParamNonGenericStyle(ParamBinaryOr):
def __init__(self, parent, name):
self.values = g.currentXXX.winStyles
ParamBinaryOr.__init__(self, parent, name)
class ParamStyle(ParamBinaryOr):
equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE'}
def __init__(self, parent, name):
ParamBinaryOr.__init__(self, parent, name)
self.valuesSpecific = g.currentXXX.winStyles
if self.valuesSpecific: # override if using specific styles
# Remove duplicates
self.valuesGeneric = [s for s in genericStyles
if s not in self.valuesSpecific]
wx.EVT_BUTTON(self, self.ID_BUTTON_CHOICES, self.OnButtonChoicesBoth)
else:
self.values = genericStyles
def OnButtonChoicesBoth(self, evt):
dlg = g.frame.res.LoadDialog(self, 'DIALOG_STYLES')
listBoxSpecific = xrc.XRCCTRL(dlg, 'CHECKLIST_SPECIFIC')
listBoxSpecific.InsertItems(self.valuesSpecific, 0)
listBoxGeneric = xrc.XRCCTRL(dlg, 'CHECKLIST_GENERIC')
listBoxGeneric.InsertItems(self.valuesGeneric, 0)
value = map(string.strip, self.text.GetValue().split('|'))
if value == ['']: value = []
# Set specific styles
value2 = [] # collect generic and ignored here
for i in value:
try:
listBoxSpecific.Check(self.valuesSpecific.index(i))
except ValueError:
# Try to find equal
if self.equal.has_key(i):
listBoxSpecific.Check(self.valuesSpecific.index(self.equal[i]))
else:
value2.append(i)
ignored = []
# Set generic styles, collect non-standart values
for i in value2:
try:
listBoxGeneric.Check(self.valuesGeneric.index(i))
except ValueError:
# Try to find equal
if self.equal.has_key(i):
listBoxGeneric.Check(self.valuesGeneric.index(self.equal[i]))
else:
print 'WARNING: unknown flag: %s: ignored.' % i
ignored.append(i)
if dlg.ShowModal() == wx.ID_OK:
value = [self.valuesSpecific[i]
for i in range(listBoxSpecific.GetCount())
if listBoxSpecific.IsChecked(i)] + \
[self.valuesGeneric[i]
for i in range(listBoxGeneric.GetCount())
if listBoxGeneric.IsChecked(i)] + ignored
self.SetValue('|'.join(value))
self.SetModified()
dlg.Destroy()
class ParamExStyle(ParamBinaryOr):
def __init__(self, parent, name):
if g.currentXXX:
self.values = g.currentXXX.exStyles + genericExStyles
else:
self.values = []
ParamBinaryOr.__init__(self, parent, name)
class ParamColour(PPanel):
def __init__(self, parent, name):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wx.NewId()
self.ID_BUTTON = wx.NewId()
sizer = wx.BoxSizer()
self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=(80,-1))
sizer.Add(self.text, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.BOTTOM, 2)
self.button = wx.Panel(self, self.ID_BUTTON, wx.DefaultPosition, wx.Size(20, 20))
sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5)
self.SetSizer(sizer)
self.textModified = False
wx.EVT_PAINT(self.button, self.OnPaintButton)
wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
wx.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
try:
colour = wx.Colour(int(value[1:3], 16), int(value[3:5], 16), int(value[5:7], 16))
self.button.SetBackgroundColour(colour)
except: # ignore errors
pass
self.button.Refresh()
self.freeze = False
def OnPaintButton(self, evt):
dc = wx.PaintDC(self.button)
dc.SetBrush(wx.TRANSPARENT_BRUSH)
if self.IsEnabled(): dc.SetPen(wx.BLACK_PEN)
else: dc.SetPen(wx.GREY_PEN)
size = self.button.GetSize()
dc.DrawRectangle(0, 0, size.width, size.height)
def OnLeftDown(self, evt):
data = wx.ColourData()
data.SetColour(self.GetValue())
dlg = wx.ColourDialog(self, data)
if dlg.ShowModal() == wx.ID_OK:
self.SetValue('#%02X%02X%02X' % dlg.GetColourData().GetColour().Get())
self.SetModified()
dlg.Destroy()
################################################################################
# Mapping from wx constants to XML strings
fontFamiliesWx2Xml = {wx.DEFAULT: 'default', wx.DECORATIVE: 'decorative',
wx.ROMAN: 'roman', wx.SCRIPT: 'script', wx.SWISS: 'swiss',
wx.MODERN: 'modern'}
fontStylesWx2Xml = {wx.NORMAL: 'normal', wx.SLANT: 'slant', wx.ITALIC: 'italic'}
fontWeightsWx2Xml = {wx.NORMAL: 'normal', wx.LIGHT: 'light', wx.BOLD: '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 = wx.NewId()
self.ID_BUTTON_SELECT = wx.NewId()
sizer = wx.BoxSizer()
self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=(200,-1))
sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
self.button = wx.Button(self, self.ID_BUTTON_SELECT, 'Select...', size=buttonSize)
sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL)
self.SetSizer(sizer)
self.textModified = False
wx.EVT_BUTTON(self, self.ID_BUTTON_SELECT, self.OnButtonSelect)
wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
def OnChange(self, evt):
PPanel.OnChange(self, evt)
self.textModified = True
def _defaultValue(self):
return [`g._sysFont.GetPointSize()`, 'default', 'normal', 'normal', '0', '', '']
def GetValue(self):
if self.textModified: # text has newer value
try:
return eval(self.text.GetValue())
except SyntaxError:
wx.LogError('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:
wx.LogError('Syntax error in parameter value: ' + self.GetName())
self.value = self._defaultValue()
# Make initial font
# Default values
size = g._sysFont.GetPointSize()
family = wx.DEFAULT
style = weight = wx.NORMAL
underlined = 0
face = ''
enc = wx.FONTENCODING_DEFAULT
# Fall back to default if exceptions
error = False
try:
try: size = int(self.value[0])
except ValueError: error = True; wx.LogError('Invalid size specification')
try: family = fontFamiliesXml2wx[self.value[1]]
except KeyError: error = True; wx.LogError('Invalid family specification')
try: style = fontStylesXml2wx[self.value[2]]
except KeyError: error = True; wx.LogError('Invalid style specification')
try: weight = fontWeightsXml2wx[self.value[3]]
except KeyError: error = True; wx.LogError('Invalid weight specification')
try: underlined = bool(self.value[4])
except ValueError: error = True; wx.LogError('Invalid underlined flag specification')
face = self.value[5]
except IndexError:
error = True
mapper = wx.FontMapper()
if not self.value[6]: enc = mapper.CharsetToEncoding(self.value[6])
if error: wx.LogError('Invalid font specification')
if enc == wx.FONTENCODING_DEFAULT: enc = wx.FONTENCODING_SYSTEM
font = wx.Font(size, family, style, weight, underlined, face, enc)
data = wx.FontData()
data.SetInitialFont(font)
dlg = wx.FontDialog(self, data)
if dlg.ShowModal() == wx.ID_OK:
font = dlg.GetFontData().GetChosenFont()
if font.GetEncoding() == wx.FONTENCODING_SYSTEM:
encName = ''
else:
encName = wx.FontMapper.GetEncodingName(font.GetEncoding()).encode()
value = [str(font.GetPointSize()),
fontFamiliesWx2Xml.get(font.GetFamily(), "default"),
fontStylesWx2Xml.get(font.GetStyle(), "normal"),
fontWeightsWx2Xml.get(font.GetWeight(), "normal"),
str(int(font.GetUnderlined())),
font.GetFaceName().encode(),
encName
]
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 = wx.NewId()
sizer = wx.BoxSizer()
self.spin = wx.SpinCtrl(self, self.ID_SPIN_CTRL, size=(60,-1))
self.spin.SetRange(-2147483648, 2147483647) # min/max integers
sizer.Add(self.spin)
self.SetSizer(sizer)
wx.EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange)
def GetValue(self):
return str(self.spin.GetValue())
def SetValue(self, value):
self.freeze = True
if not value: value = 0
self.spin.SetValue(int(value))
self.freeze = False
# Non-negative number
class ParamIntNN(PPanel):
def __init__(self, parent, name):
PPanel.__init__(self, parent, name)
self.ID_SPIN_CTRL = wx.NewId()
sizer = wx.BoxSizer()
self.spin = wx.SpinCtrl(self, self.ID_SPIN_CTRL, size=(60,-1))
self.spin.SetRange(0, 10000) # min/max integers
sizer.Add(self.spin)
self.SetSizer(sizer)
wx.EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange)
def GetValue(self):
return str(self.spin.GetValue())
def SetValue(self, value):
self.freeze = True
if not value: value = 0
self.spin.SetValue(int(value))
self.freeze = False
# Same as int but allows dialog units (XXXd)
class ParamUnit(PPanel):
def __init__(self, parent, name):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wx.NewId()
self.ID_SPIN_BUTTON = wx.NewId()
sizer = wx.BoxSizer(wx.HORIZONTAL)
self.spin = wx.SpinButton(self, self.ID_SPIN_BUTTON, style = wx.SP_VERTICAL, size=(-1,0))
textW = 60 - self.spin.GetSize()[0]
self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=(textW,-1))
self.spin.SetRange(-10000, 10000)
sizer.Add(self.text, 0, wx.EXPAND)
sizer.Add(self.spin, 0, wx.EXPAND)
self.SetSizer(sizer)
self.spin.Bind(wx.EVT_SPIN_UP, self.OnSpinUp)
self.spin.Bind(wx.EVT_SPIN_DOWN, self.OnSpinDown)
def GetValue(self):
return self.text.GetValue()
def SetValue(self, value):
if not value: value = '0'
self.text.SetValue(value)
self.Change(0)
def Change(self, x):
self.freeze = True
# Check if we are working with dialog units
value = self.text.GetValue()
units = ''
if value[-1].upper() == 'D':
units = value[-1]
value = value[:-1]
try:
intValue = int(value) + x
self.spin.SetValue(intValue)
if x: # 0 can be passed to update spin value only
self.text.SetValue(str(intValue) + units)
self.SetModified()
except:
# !!! Strange, if I use wx.LogWarning, event is re-generated
print 'ERROR: incorrect unit format'
self.freeze = False
def OnSpinUp(self, evt):
self.freeze = True
self.Change(1)
def OnSpinDown(self, evt):
if self.freeze: return
self.freeze = True
self.Change(-1)
class ParamMultilineText(PPanel):
def __init__(self, parent, name, textWidth=-1):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wx.NewId()
self.ID_BUTTON_EDIT = wx.NewId()
sizer = wx.BoxSizer()
self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=wx.Size(200,-1))
sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
self.button = wx.Button(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize)
sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL)
self.SetSizerAndFit(sizer)
wx.EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit)
wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
def GetValue(self):
return self.text.GetValue()
def SetValue(self, value):
self.freeze = True # disable other handlers
self.text.SetValue(value)
self.freeze = False # disable other handlers
def OnButtonEdit(self, evt):
dlg = g.frame.res.LoadDialog(self, 'DIALOG_TEXT')
textCtrl = xrc.XRCCTRL(dlg, 'TEXT')
textCtrl.SetValue(self.text.GetValue())
if dlg.ShowModal() == wx.ID_OK:
self.text.SetValue(textCtrl.GetValue())
self.SetModified()
dlg.Destroy()
class ParamText(PPanel):
def __init__(self, parent, name, textWidth=-1):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wx.NewId()
# We use sizer even here to have the same size of text control
sizer = wx.BoxSizer()
self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=wx.Size(textWidth,-1))
if textWidth == -1: option = 1
else: option = 0
sizer.Add(self.text, option, wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.BOTTOM, 2)
self.SetSizer(sizer)
wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
def GetValue(self):
return self.text.GetValue()
def SetValue(self, value):
self.freeze = True # disable other handlers
self.text.SetValue(value)
self.freeze = False # disable other handlers
class ParamAccel(ParamText):
def __init__(self, parent, name):
ParamText.__init__(self, parent, name, 100)
class ParamPosSize(ParamText):
def __init__(self, parent, name):
ParamText.__init__(self, parent, name, 80)
class ParamLabel(ParamText):
def __init__(self, parent, name):
ParamText.__init__(self, parent, name, 200)
class ParamEncoding(ParamText):
def __init__(self, parent, name):
ParamText.__init__(self, parent, name, 100)
class ParamComment(ParamText):
def __init__(self, parent, name):
ParamText.__init__(self, parent, name, 330 + buttonSize[0])
class ContentDialog(wx.Dialog):
def __init__(self, parent, value):
# Load from resource
pre = wx.PreDialog()
g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_CONTENT')
self.PostCreate(pre)
self.list = xrc.XRCCTRL(self, 'LIST')
# Set list items
for v in value:
self.list.Append(v)
self.SetAutoLayout(True)
self.GetSizer().Fit(self)
# Callbacks
self.ID_BUTTON_APPEND = xrc.XRCID('BUTTON_APPEND')
self.ID_BUTTON_REMOVE = xrc.XRCID('BUTTON_REMOVE')
self.ID_BUTTON_UP = xrc.XRCID('BUTTON_UP')
self.ID_BUTTON_DOWN = xrc.XRCID('BUTTON_DOWN')
wx.EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp)
wx.EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown)
wx.EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend)
wx.EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
wx.EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI)
wx.EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI)
wx.EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
def OnButtonUp(self, evt):
i = self.list.GetSelection()
str = self.list.GetString(i)
self.list.Delete(i)
self.list.InsertItems([str], i-1)
self.list.SetSelection(i-1)
def OnButtonDown(self, evt):
i = self.list.GetSelection()
str = self.list.GetString(i)
self.list.Delete(i)
self.list.InsertItems([str], i+1)
self.list.SetSelection(i+1)
def OnButtonAppend(self, evt):
str = wx.GetTextFromUser('Enter new item:', 'Append', '', self)
self.list.Append(str)
def OnButtonRemove(self, evt):
self.list.Delete(self.list.GetSelection())
def OnUpdateUI(self, evt):
if evt.GetId() == self.ID_BUTTON_REMOVE:
evt.Enable(self.list.GetSelection() != -1)
elif evt.GetId() == self.ID_BUTTON_UP:
evt.Enable(self.list.GetSelection() > 0)
elif evt.GetId() == self.ID_BUTTON_DOWN:
evt.Enable(self.list.GetSelection() != -1 and \
self.list.GetSelection() < self.list.GetCount() - 1)
class ContentCheckListDialog(wx.Dialog):
def __init__(self, parent, value):
pre = wx.PreDialog()
g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_CONTENT_CHECKLIST')
self.PostCreate(pre)
self.list = xrc.XRCCTRL(self, 'CHECK_LIST')
# Set list items
i = 0
for v,ch in value:
self.list.Append(v)
self.list.Check(i, ch)
i += 1
self.SetAutoLayout(True)
self.GetSizer().Fit(self)
# Callbacks
self.ID_BUTTON_APPEND = xrc.XRCID('BUTTON_APPEND')
self.ID_BUTTON_REMOVE = xrc.XRCID('BUTTON_REMOVE')
self.ID_BUTTON_UP = xrc.XRCID('BUTTON_UP')
self.ID_BUTTON_DOWN = xrc.XRCID('BUTTON_DOWN')
wx.EVT_CHECKLISTBOX(self, self.list.GetId(), self.OnCheck)
wx.EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp)
wx.EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown)
wx.EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend)
wx.EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
wx.EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI)
wx.EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI)
wx.EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
def OnCheck(self, evt):
# !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking
self.list.Deselect(evt.GetSelection())
def OnButtonUp(self, evt):
i = self.list.GetSelection()
str, ch = self.list.GetString(i), self.list.IsChecked(i)
self.list.Delete(i)
self.list.InsertItems([str], i-1)
self.list.Check(i-1, ch)
self.list.SetSelection(i-1)
def OnButtonDown(self, evt):
i = self.list.GetSelection()
str, ch = self.list.GetString(i), self.list.IsChecked(i)
self.list.Delete(i)
self.list.InsertItems([str], i+1)
self.list.Check(i+1, ch)
self.list.SetSelection(i+1)
def OnButtonAppend(self, evt):
str = wx.GetTextFromUser('Enter new item:', 'Append', '', self)
self.list.Append(str)
def OnButtonRemove(self, evt):
self.list.Delete(self.list.GetSelection())
def OnUpdateUI(self, evt):
if evt.GetId() == self.ID_BUTTON_REMOVE:
evt.Enable(self.list.GetSelection() != -1)
elif evt.GetId() == self.ID_BUTTON_UP:
evt.Enable(self.list.GetSelection() > 0)
elif evt.GetId() == self.ID_BUTTON_DOWN:
evt.Enable(self.list.GetSelection() != -1 and \
self.list.GetSelection() < self.list.GetCount() - 1)
class ParamContent(PPanel):
def __init__(self, parent, name):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wx.NewId()
self.ID_BUTTON_EDIT = wx.NewId()
sizer = wx.BoxSizer()
self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=wx.Size(200,-1))
sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
self.button = wx.Button(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize)
sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL)
self.SetSizer(sizer)
self.textModified = False
wx.EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit)
wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
def OnChange(self, evt):
PPanel.OnChange(self, evt)
self.textModified = True
def GetValue(self):
if self.textModified: # text has newer value
try:
return self.text.GetValue().split('|')
except ValueError:
return []
return self.value
def SetValue(self, value):
self.freeze = True
if not value: value = []
self.value = value
repr_ = '|'.join(map(str, value))
self.text.SetValue(repr_) # update text ctrl
self.freeze = False
def OnButtonEdit(self, evt):
if self.textModified: # text has newer value
self.value = self.GetValue()
dlg = ContentDialog(self, self.value)
if dlg.ShowModal() == wx.ID_OK:
value = []
for i in range(dlg.list.GetCount()):
value.append(dlg.list.GetString(i))
self.SetValue(value)
self.SetModified()
self.textModified = False
dlg.Destroy()
def SetModified(self, state=True):
PPanel.SetModified(self, state)
self.textModified = False
# CheckList content
class ParamContentCheckList(ParamContent):
def __init__(self, parent, name):
ParamContent.__init__(self, parent, name)
def OnButtonEdit(self, evt):
if self.textModified: # text has newer value
self.value = self.GetValue()
dlg = ContentCheckListDialog(self, self.value)
if dlg.ShowModal() == wx.ID_OK:
value = []
for i in range(dlg.list.GetCount()):
value.append((dlg.list.GetString(i), int(dlg.list.IsChecked(i))))
self.SetValue(value)
self.SetModified()
self.textModified = False
dlg.Destroy()
def SetValue(self, value):
self.freeze = True
if not value: value = []
self.value = value
repr_ = '|'.join(map(str,value))
self.text.SetValue(repr_) # update text ctrl
self.freeze = False
class IntListDialog(wx.Dialog):
def __init__(self, parent, value):
pre = wx.PreDialog()
g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_INTLIST')
self.PostCreate(pre)
self.list = xrc.XRCCTRL(self, 'LIST')
# Set list items
value.sort()
for v in value:
if type(v) != IntType:
wx.LogError('Invalid item type')
else:
self.list.Append(str(v))
self.SetAutoLayout(True)
self.GetSizer().Fit(self)
# Callbacks
self.spinCtrl = xrc.XRCCTRL(self, 'SPIN')
wx.EVT_BUTTON(self, xrc.XRCID('BUTTON_ADD'), self.OnButtonAdd)
self.ID_BUTTON_REMOVE = xrc.XRCID('BUTTON_REMOVE')
wx.EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
wx.EVT_BUTTON(self, xrc.XRCID('BUTTON_CLEAR'), self.OnButtonClear)
wx.EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
def OnButtonAdd(self, evt):
# Check that it's unique
try:
v = self.spinCtrl.GetValue()
s = str(v) # to be sure
i = self.list.FindString(s)
if i == -1: # ignore non-unique
# Find place to insert
found = False
for i in range(self.list.GetCount()):
if int(self.list.GetString(i)) > v:
found = True
break
if found: self.list.InsertItems([s], i)
else: self.list.Append(s)
except ValueError:
wx.LogError('List item is not an int!')
def OnButtonRemove(self, evt):
self.list.Delete(self.list.GetSelection())
def OnButtonClear(self, evt):
self.list.Clear()
def OnUpdateUI(self, evt):
if evt.GetId() == self.ID_BUTTON_REMOVE:
evt.Enable(self.list.GetSelection() != -1)
# For growable list
class ParamIntList(ParamContent):
def __init__(self, parent, name):
ParamContent.__init__(self, parent, name)
def OnButtonEdit(self, evt):
if self.textModified: # text has newer value
try:
self.value = map(int, self.text.GetValue().split('|'))
except ValueError:
self.value = []
dlg = IntListDialog(self, self.value)
if dlg.ShowModal() == wx.ID_OK:
value = []
for i in range(dlg.list.GetCount()):
value.append(int(dlg.list.GetString(i)))
self.SetValue(value)
self.SetModified()
self.textModified = False
dlg.Destroy()
# Boxless radiobox
class RadioBox(PPanel):
def __init__(self, parent, id, choices,
pos=wx.DefaultPosition, name='radiobox'):
PPanel.__init__(self, parent, name)
self.choices = choices
topSizer = wx.BoxSizer()
for i in choices:
button = wx.RadioButton(self, -1, i, size=(-1,buttonSize[1]), name=i)
topSizer.Add(button, 0, wx.RIGHT, 5)
wx.EVT_RADIOBUTTON(self, button.GetId(), self.OnRadioChoice)
self.SetSizer(topSizer)
def SetStringSelection(self, value):
self.freeze = True
for i in self.choices:
self.FindWindowByName(i).SetValue(i == value)
self.value = value
self.freeze = False
def OnRadioChoice(self, evt):
if self.freeze: return
if evt.GetSelection():
self.value = evt.GetEventObject().GetName()
self.SetModified()
def GetStringSelection(self):
return self.value
class ParamBool(RadioBox):
values = {'yes': '1', 'no': '0'}
seulav = {'1': 'yes', '0': 'no'}
def __init__(self, parent, name):
RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name)
def GetValue(self):
return self.values[self.GetStringSelection()]
def SetValue(self, value):
if not value: value = '1'
self.SetStringSelection(self.seulav[value])
class ParamOrient(RadioBox):
values = {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
seulav = {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'}
def __init__(self, parent, name):
RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name)
def GetValue(self):
return self.values[self.GetStringSelection()]
def SetValue(self, value):
if not value: value = 'wxHORIZONTAL'
self.SetStringSelection(self.seulav[value])
class ParamOrientation(RadioBox):
values = {'horizontal': 'horizontal', 'vertical': 'vertical'}
seulav = {'horizontal': 'horizontal', 'vertical': 'vertical'}
def __init__(self, parent, name):
RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name)
def GetValue(self):
return self.values[self.GetStringSelection()]
def SetValue(self, value):
if not value: value = 'vertical'
self.SetStringSelection(self.seulav[value])
class ParamFile(PPanel):
def __init__(self, parent, name):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wx.NewId()
self.ID_BUTTON_BROWSE = wx.NewId()
sizer = wx.BoxSizer()
self.text = wx.TextCtrl(self, self.ID_TEXT_CTRL, size=wx.Size(200,-1))
sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
self.button = wx.Button(self, self.ID_BUTTON_BROWSE, 'Browse...',size=buttonSize)
sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL)
self.SetSizer(sizer)
self.textModified = False
wx.EVT_BUTTON(self, self.ID_BUTTON_BROWSE, self.OnButtonBrowse)
wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
def OnChange(self, evt):
PPanel.OnChange(self, evt)
self.textModified = True
def GetValue(self):
if self.textModified: # text has newer value
return self.text.GetValue()
return self.value
def SetValue(self, value):
self.freeze = True
self.value = value
self.text.SetValue(value) # update text ctrl
self.freeze = False
def OnButtonBrowse(self, evt):
if self.textModified: # text has newer value
self.value = self.text.GetValue()
dlg = wx.FileDialog(self,
defaultDir = os.path.abspath(os.path.dirname(self.value)),
defaultFile = os.path.basename(self.value))
if dlg.ShowModal() == wx.ID_OK:
# Get common part of selected path and current
if g.frame.dataFile:
curpath = os.path.abspath(g.frame.dataFile)
else:
curpath = os.path.join(os.getcwd(), '')
common = os.path.commonprefix([curpath, dlg.GetPath()])
self.SetValue(dlg.GetPath()[len(common):])
self.SetModified()
self.textModified = False
dlg.Destroy()
class ParamBitmap(PPanel):
def __init__(self, parent, name):
pre = wx.PrePanel()
g.frame.res.LoadOnPanel(pre, parent, 'PANEL_BITMAP')
self.PostCreate(pre)
self.modified = self.freeze = False
self.radio_std = xrc.XRCCTRL(self, 'RADIO_STD')
self.radio_file = xrc.XRCCTRL(self, 'RADIO_FILE')
self.combo = xrc.XRCCTRL(self, 'COMBO_STD')
self.text = xrc.XRCCTRL(self, 'TEXT_FILE')
self.button = xrc.XRCCTRL(self, 'BUTTON_BROWSE')
self.textModified = False
self.SetAutoLayout(True)
self.GetSizer().SetMinSize((260, -1))
self.GetSizer().Fit(self)
wx.EVT_RADIOBUTTON(self, xrc.XRCID('RADIO_STD'), self.OnRadioStd)
wx.EVT_RADIOBUTTON(self, xrc.XRCID('RADIO_FILE'), self.OnRadioFile)
wx.EVT_BUTTON(self, xrc.XRCID('BUTTON_BROWSE'), self.OnButtonBrowse)
wx.EVT_COMBOBOX(self, xrc.XRCID('COMBO_STD'), self.OnCombo)
wx.EVT_TEXT(self, xrc.XRCID('COMBO_STD'), self.OnChange)
wx.EVT_TEXT(self, xrc.XRCID('TEXT_FILE'), self.OnChange)
def OnRadioStd(self, evt):
self.SetModified()
self.SetValue(['wxART_MISSING_IMAGE',''])
def OnRadioFile(self, evt):
self.SetModified()
self.SetValue(['',''])
def updateRadios(self):
if self.value[0]:
self.radio_std.SetValue(True)
self.radio_file.SetValue(False)
self.text.Enable(False)
self.button.Enable(False)
self.combo.Enable(True)
else:
self.radio_std.SetValue(False)
self.radio_file.SetValue(True)
self.text.Enable(True)
self.button.Enable(True)
self.combo.Enable(False)
def OnChange(self, evt):
PPanel.OnChange(self, evt)
self.textModified = True
def OnCombo(self, evt):
PPanel.OnChange(self, evt)
self.value[0] = self.combo.GetValue()
def GetValue(self):
if self.textModified: # text has newer value
return [self.combo.GetValue(), self.text.GetValue()]
return self.value
def SetValue(self, value):
self.freeze = True
if not value:
self.value = ['', '']
else:
self.value = value
self.combo.SetValue(self.value[0])
self.text.SetValue(self.value[1]) # update text ctrl
self.updateRadios()
self.freeze = False
def OnButtonBrowse(self, evt):
if self.textModified: # text has newer value
self.value[1] = self.text.GetValue()
dlg = wx.FileDialog(self,
defaultDir = os.path.abspath(os.path.dirname(self.value[1])),
defaultFile = os.path.basename(self.value[1]))
if dlg.ShowModal() == wx.ID_OK:
# Get common part of selected path and current
if g.frame.dataFile:
curpath = os.path.abspath(g.frame.dataFile)
else:
curpath = os.path.join(os.getcwd(), '')
common = os.path.commonprefix([curpath, dlg.GetPath()])
self.SetValue(['', dlg.GetPath()[len(common):]])
self.SetModified()
self.textModified = False
dlg.Destroy()
paramDict = {
'flag': ParamFlag,
'style': ParamStyle, 'exstyle': ParamExStyle,
'pos': ParamPosSize, 'size': ParamPosSize,
'cellpos': ParamPosSize, 'cellspan': ParamPosSize,
'border': ParamUnit, 'cols': ParamIntNN, 'rows': ParamIntNN,
'vgap': ParamUnit, 'hgap': ParamUnit,
'checkable': ParamBool, 'checked': ParamBool, 'radio': ParamBool,
'accel': ParamAccel,
'label': ParamMultilineText, 'title': ParamText, 'value': ParamText,
'content': ParamContent, 'selection': ParamIntNN,
'min': ParamInt, 'max': ParamInt,
'fg': ParamColour, 'bg': ParamColour, 'font': ParamFont,
'enabled': ParamBool, 'focused': ParamBool, 'hidden': ParamBool,
'tooltip': ParamText, 'bitmap': ParamBitmap, 'icon': ParamBitmap,
'encoding': ParamEncoding, 'borders': ParamUnit,
'comment': ParamComment
}