controls can be configured ("File">"Preferences..."). Implemented comment object for including simple one-line comments and comment directives as tree nodes. No validation is performed for a valid XML string so comments must not contain "-->". Comment directive is a special comment starting with '%' character, followed by a line of python code. It is executed using 'exec' when the resource file is opened. This is useful to import plugin modules containing custom handlers which are specific to the resource file, hovewer this is of course a security hole if you use foreign XRC files. A warning is displayed if the preference option 'ask' is selected (by default). Added support for custom controls and plugin modules. Refer to this wxPythonWiki for the details: http://wiki.wxpython.org/index.cgi/XRCed#custom Tool panel sections can be collapsed/expanded by clicking on the label of a tool group. Some undo/redo and other fixes. Fixes for wxMSW (notebook highlighting, control sizes, tree Unselect). Notebook page highlighting fix. Highlight resizes when the window is resized. ParamUnit spin button detects event handler re-entry (wxGTK probably has a bug in wxSpinButton with repeated events). Fix for dealing with empty 'growable' property, using MiniFrame for properties panel, the panel is restored together with the main window. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@44949 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
938 lines
38 KiB
Python
938 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):
|
|
self.enabled = 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, style=0):
|
|
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), style=style)
|
|
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],
|
|
style=wx.TE_PROCESS_ENTER)
|
|
|
|
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
|
|
}
|