#-----------------------------------------------------------------------------
# Name: SizerCompanions.py
# Purpose: Companion classes for Sizer objects
#
# Author: Riaan Booysen
#
# Created: 2003
# RCS-ID: $Id: SizerCompanions.py,v 1.17 2007/07/02 15:01:09 riaan Exp $
# Copyright: (c) 2003 - 2007
# Licence: GPL
#-----------------------------------------------------------------------------
print 'importing Companions.SizerCompanions'
# XXX _in_sizer is not necessary, use GetContainingSizer() instead
import os, sys, copy
import wx
#from wx.lib.rcsizer import RowColSizer
import Preferences, Utils
from Utils import _
from BaseCompanions import UtilityDTC,CollectionDTC,CollectionIddDTC,NYIDTC,HelperDTC
import Companions
from PropEdit.PropertyEditors import IntConstrPropEdit,StrConstrPropEdit,\
CollectionPropEdit, ObjEnumConstrPropEdit, EnumConstrPropEdit, \
FlagsConstrPropEdit, WinEnumConstrPropEdit, BoolConstrPropEdit, \
BoolPropEdit, EnumPropEdit, ReadOnlyConstrPropEdit, \
SizerEnumConstrPropEdit, SizeConstrPropEdit, ConstrPropEdit, \
IntPropEdit, esExpandable
from PropEdit.InspectorEditorControls import TextCtrlIEC
from PropEdit.FlexGridGrowablesDlg import FlexGridGrowablesDlg
from PropEdit import Enumerations
import EventCollections, RTTI, methodparse
class SizerItemsColPropEdit(CollectionPropEdit): pass
class BlankSizer(wx.BoxSizer):
""" Used as a placeholder for initial sizer items which has None for
the window or sizer """
def __init__(self):
wx.BoxSizer.__init__(self, wx.VERTICAL)
self.AddSpacer((24, 24))
class SizerDTC(UtilityDTC):
host = 'Sizers'
def __init__(self, name, designer, objClass):
UtilityDTC.__init__(self, name, designer, objClass)
self.editors['Items'] = SizerItemsColPropEdit
self.subCompanions['Items'] = SizerItemsCDTC
def properties(self):
props = UtilityDTC.properties(self)
props.update({'Items': ('NoneRoute', None, None)})
return props
def dependentProps(self):
return UtilityDTC.dependentProps(self) + ['Items']
def designTimeSource(self):
return {}
def defaultAction(self):
nv = self.designer.inspector.props.getNameValue('Items')
if nv: nv.propEditor.edit(None)
def renameCtrl(self, oldName, newName):
UtilityDTC.renameCtrl(self, oldName, newName)
self.designer.checkSizerConnectRename(oldName, newName)
def renameCtrlRefs(self, oldName, newName):
UtilityDTC.renameCtrlRefs(self, oldName, newName)
self.designer.checkCollectionRename(oldName, newName, self)
def recreateSizer(self):
args = self.designer.setupArgs(self.name, self.textConstr.params,
self.handledConstrParams, evalDct = self.designer.model.specialAttrs)
self.control = self.designTimeObject(args)
self.designer.objects[self.name][1] = self.control
def recreateSizerItems(self):
for collComp in self.collections.values():
collComp.control = self.control
for crt in collComp.textConstrLst:
collComp.applyDesignTimeDefaults(crt.params, crt.method)
class SizerFlagsDTC(Companions.FlagsDTC):
paramName = 'flag'
propName = 'Flag'
class SizerFlagsConstrPropEdit(FlagsConstrPropEdit):
def getSubCompanion(self):
return SizerFlagsDTC
class SizerWinEnumConstrPropEdit(ObjEnumConstrPropEdit):
def getObjects(self):
designer = self.companion.designer.controllerView
windows = designer.getObjectsOfClass(wx.Window)
for n, w in windows.items():
if hasattr(w, '_in_sizer') or n == 'self':
del windows[n]
windowNames = windows.keys()
windowNames.sort()
res = ['None'] + windowNames
if self.value != 'None':
res.insert(1, self.value)
return res
def getCtrlValue(self):
return self.companion.GetWindow()
def setCtrlValue(self, oldValue, value):
self.companion.SetWindow(value)
# XXX Remove 'Insert' special casing, no longer used
class SizerItemsCDTC(CollectionDTC):
propName = 'Items'
displayProp = 0
indexProp = '(None)'
insertionMethod = 'AddWindow'
deletionMethod = 'Remove'
additionalMethods = { 'AddSizer': (_('Add sizer'), 0, '(None)'),
'AddSpacer': (_('Add spacer'), '', '(None)'),
#'AddStretchSpacer': ('Add stretch spacer', '', '(None)')
}
def __init__(self, name, designer, parentCompanion, ctrl):
CollectionDTC.__init__(self, name, designer, parentCompanion, ctrl)
self.editors = {'Window': SizerWinEnumConstrPropEdit,
'Sizer': SizerEnumConstrPropEdit,
'Proportion': IntConstrPropEdit,
'Flag': SizerFlagsConstrPropEdit,
'Border': IntConstrPropEdit,
'Size': SizeConstrPropEdit,
}
self.windowStyles = ['wx.LEFT', 'wx.RIGHT', 'wx.TOP', 'wx.BOTTOM', 'wx.ALL',
'wx.SHRINK', 'wx.GROW', 'wx.EXPAND', 'wx.SHAPED',
'wx.ALIGN_LEFT', 'wx.ALIGN_CENTER_HORIZONTAL',
'wx.ALIGN_RIGHT', 'wx.ALIGN_BOTTOM',
'wx.ALIGN_CENTER_VERTICAL', 'wx.ALIGN_TOP',
'wx.ALIGN_CENTER', 'wx.ADJUST_MINSIZE']
def constructor(self):
tcl = self.textConstrLst[self.index]
if tcl.method == 'AddWindow':
return {'Window': 0, 'Proportion': 1, 'Flag': 'flag',
'Border': 'border'}
elif tcl.method == 'AddSizer':
return {'Sizer': 0, 'Proportion': 1, 'Flag': 'flag',
'Border': 'border'}
elif tcl.method == 'AddSpacer':
return {'Size': 0, 'Flag': 'flag',
'Border': 'border'}
#elif tcl.method == 'AddStretchSpacer':
# return {'Proportion': 0}
def designTimeSource(self, wId, method=None):
if method is None:
method = self.insertionMethod
if method == 'AddWindow':
return {0: 'None', 1: '0', 'flag': '0', 'border': '0'}
elif method == 'AddSizer':
return {0: 'None', 1: '0', 'flag': '0', 'border': '0'}
elif method == 'AddSpacer':
return {0: 'wx.Size(8, 8)', 'flag': '0', 'border': '0'}
#elif method == 'AddStretchSpacer':
# return {0: '1'}
def notification(self, compn, action):
if action == 'delete':
if not isinstance(compn, CollectionDTC):
compnSrcRef = Utils.srcRefFromCtrlName(compn.name)
for constr in self.textConstrLst:
if compnSrcRef == constr.params[0]:
constr.params[0] = 'None'
self.recreateSizers()
return
def appendItem(self, method=None, srcParams={}):
CollectionDTC.appendItem(self, method, srcParams)
self.recreateSizers()
#self.updateGUI()
def deleteItem(self, idx):
CollectionDTC.deleteItem(self, idx)
del self.textConstrLst[idx]
self.recreateSizers()
#self.updateGUI()
def moveItem(self, idx, dir):
newIdx = CollectionDTC.moveItem(self, idx, dir)
if newIdx != idx:
self.recreateSizers()
return newIdx
def defaultAction(self):
constr = self.textConstrLst[self.index]
if constr.method == 'AddWindow':
if constr.params[0] != 'None':
name = Utils.ctrlNameFromSrcRef(constr.params[0])
designer = self.designer.controllerView
compn, ctrl = designer.objects[name][:2]
designer.inspector.selectObject(compn, True)
designer.Raise()
designer.selection.selectCtrl(ctrl, compn)
wx.CallAfter(designer.SetFocus)
return True
elif constr.method == 'AddSizer':
if constr.params[0] != 'None':
name = Utils.ctrlNameFromSrcRef(constr.params[0])
compn = self.designer.objects[name][0]
self.designer.inspector.selectObject(compn, True)
self.designer.selectCtrls([name])
wx.CallAfter(self.designer.SetFocus)
return True
def designTimeDefaults(self, vals, method=None):
if method is None:
method = self.insertionMethod
if method in ('AddWindow', 'AddSizer', 'Insert'):
if method in ('AddWindow', 'AddSizer'): ctrlIdx = 0
elif method == 'Insert': ctrlIdx = 1
if vals[ctrlIdx] != 'None':
srcRef = vals[ctrlIdx]
try:
# XXX improve
int(srcRef)
except:
params = copy.copy(vals)
del params[ctrlIdx]
dtd = CollectionDTC.designTimeDefaults(self, params, method)
dtd[ctrlIdx] = self.designer.controllerView.getAllObjects()[srcRef]
if method == 'AddSizer':
dtd[ctrlIdx]._sub_sizer = self.control
elif method == 'AddWindow':
dtd[ctrlIdx]._in_sizer = self.control
return dtd
return CollectionDTC.designTimeDefaults(self, vals, method)
def applyDesignTimeDefaults(self, params, method=None):
if method is None:
method = self.insertionMethod
if (method in ('AddWindow', 'AddSizer') and params[0] == 'None') or \
(method == 'Insert' and params[1] == 'None'):
defaults = self.designTimeDefaults(params, method)
if method == 'Insert':
proportion = defaults[2]
import warnings; warnings.warn('Insert called with BlankSizer')
else:
proportion = defaults[1]
self.control.AddSizer(BlankSizer(), proportion, defaults['flag'],
defaults['border'])
else:
CollectionDTC.applyDesignTimeDefaults(self, params, method)
def setParamAndUpdate(self, key, value):
constr = self.textConstrLst[self.index]
constr.params[key] = value
self.recreateSizers()
def GetWindow(self):
return self.textConstrLst[self.index].params[0]
def SetWindow(self, value):
self.setParamAndUpdate(0, value)
colEdKey = (self.parentCompanion.name, 'Items')
if self.designer.collEditors.has_key(colEdKey):
collEditView = self.designer.collEditors[colEdKey]
wx.CallAfter(self.setWindowRefresh, collEditView)
def setWindowRefresh(self, collEditView):
collEditView.refreshCtrl(1)
collEditView.selectObject(self.index)
if collEditView.frame:
collEditView.frame.selectObject(self.index)
GetSizer = GetWindow
SetSizer = SetWindow
def persistProp(self, name, setterName, value):
CollectionDTC.persistProp(self, name, setterName, value)
if name in ('Size',):
self.recreateSizers()
elif name in ('Flag', 'Border', 'Proportion'):
si = self.control.GetChildren()[self.index]
getattr(si, 'Set'+name)(self.eval(value))
self.updateGUI()
def writeCollectionItems(self, output, stripFrmId=''):
CollectionDTC.writeCollectionItems(self, output, stripFrmId)
warn = 0
for constr in self.textConstrLst:
if constr.params[0] == 'None':
wx.LogWarning(_('No control/sizer for sizer item of %s')%(
self.parentCompanion.name))
warn = 1
if warn:
wx.LogWarning(_('None values are only valid in the Designer.\n'
'The generated source will be invalid outside the '
'Designer and should be fixed before executing.'))
def recreateSizers(self):
self.designer.recreateSizers()
self.updateGUI()
def updateGUI(self):
self.control.Layout()
wx.CallAfter(self.designer.controllerView.Refresh)
class BoxSizerDTC(SizerDTC):
def __init__(self, name, designer, objClass):
SizerDTC.__init__(self, name, designer, objClass)
self.editors['Orientation'] = EnumPropEdit
self.names['Orientation'] = {'wx.VERTICAL': wx.VERTICAL,
'wx.HORIZONTAL': wx.HORIZONTAL}
self.options['Orientation'] = [wx.VERTICAL, wx.HORIZONTAL]
def constructor(self):
return {'Name': 'name', 'Orientation': 'orient'}
def designTimeSource(self):
return {'orient': 'wx.VERTICAL'}
class GridSizerDTC(SizerDTC):
def constructor(self):
return {'Name': 'name', 'Rows': 'rows', 'Cols': 'cols',
'VGap': 'vgap', 'HGap': 'hgap'}
def designTimeSource(self):
return {'rows': '1', 'cols': '0', 'vgap': '0', 'hgap': '0'}
class GrowablesColPropEdit(CollectionPropEdit):
def edit(self, event):
ce = self.companion.designer.showCollectionEditor(self.companion.name,
self.name, False)
growableRows, growableCols = ce.companion.getGrowables()
fgsCompn = ce.companion.parentCompanion
numRows, numCols = fgsCompn.getNumRowsCols(ce.companion)
if not numRows and not numCols:
wx.LogError(_('Rows and Cols may not both be 0'))
return
if not numRows or not numCols:
numItems = len(self.companion.designer.showCollectionEditor(
self.companion.name, 'Items', False).companion.textConstrLst)
else:
numItems = -1
rows, cols = [], []
if not numRows:
numRows = numItems/float(numCols)
numRows = int(numRows)+(numRows > int(numRows))
for row in range(numRows):
rows.append(row in growableRows)
if not numCols:
numCols = numItems/float(numRows)
numCols = int(numCols)+(numCols > int(numCols))
for col in range(numCols):
cols.append(col in growableCols)
dlg = FlexGridGrowablesDlg(self.parent, rows, cols)
try:
res = dlg.ShowModal()
if res == wx.ID_CANCEL:
return
if res == wx.ID_YES:
ce.show()
return
rows = dlg.rows
cols = dlg.cols
finally:
dlg.Destroy()
ce.companion.setGrowables(rows, cols)
ce.companion.recreateSizers()
class GrowablesCDTC(CollectionDTC):
propName = 'Growables'
displayProp = 0
indexProp = '(None)'
insertionMethod = '(None)'
deletionMethod = '(None)'
additionalMethods = { 'AddGrowableRow': ('Add growable row', 0, '(None)'),
'AddGrowableCol': ('Add growable column', 0, '(None)')
}
def __init__(self, name, designer, parentCompanion, ctrl):
CollectionDTC.__init__(self, name, designer, parentCompanion, ctrl)
self.editors['Index'] = IntConstrPropEdit
def constructor(self):
return {'Index': 0}
def designTimeSource(self, wId, method=None):
return {0: '0'}
def getGrowables(self):
rows, cols = [], []
for constr in self.textConstrLst:
if constr.method == 'AddGrowableRow':
rows.append(self.eval(constr.params[0]))
elif constr.method == 'AddGrowableCol':
cols.append(self.eval(constr.params[0]))
return rows, cols
def _appendItem(self, method, idx):
self.index = self.getCount()
if method is None:
method = self.insertionMethod
collItemInit = methodparse.CollectionItemInitParse(None,
self.sourceObjName, method, {0: str(idx)})
self.textConstrLst.append(collItemInit)
self.setConstr(collItemInit)
def setGrowables(self, rows, cols):
self.textConstrLst = []
for idx, row in zip(range(len(rows)), rows):
if row:
self._appendItem('AddGrowableRow', idx)
for idx, col in zip(range(len(cols)), cols):
if col:
self._appendItem('AddGrowableCol', idx)
def recreateSizers(self):
self.designer.recreateSizers()
self.updateGUI()
def updateGUI(self):
self.control.Layout()
wx.CallAfter(self.designer.controllerView.Refresh)
class FlexGridSizerDTC(GridSizerDTC):
def __init__(self, name, designer, objClass):
GridSizerDTC.__init__(self, name, designer, objClass)
self.editors['Growables'] = GrowablesColPropEdit
self.subCompanions['Growables'] = GrowablesCDTC
self.editors['FlexibleDirection'] = EnumPropEdit
self.names['FlexibleDirection'] = {'wx.VERTICAL': wx.VERTICAL,
'wx.HORIZONTAL': wx.HORIZONTAL,
'wx.BOTH': wx.BOTH}
self.options['FlexibleDirection'] = [wx.VERTICAL, wx.HORIZONTAL, wx.BOTH]
self.editors['NonFlexibleGrowMode'] = EnumPropEdit
self.names['NonFlexibleGrowMode'] = {'wx.FLEX_GROWMODE_NONE': wx.FLEX_GROWMODE_NONE,
'wx.FLEX_GROWMODE_SPECIFIED': wx.FLEX_GROWMODE_SPECIFIED,
'wx.FLEX_GROWMODE_ALL': wx.FLEX_GROWMODE_ALL}
self.options['NonFlexibleGrowMode'] = [wx.FLEX_GROWMODE_NONE,
wx.FLEX_GROWMODE_SPECIFIED,
wx.FLEX_GROWMODE_ALL]
def properties(self):
props = GridSizerDTC.properties(self)
props.update({'Growables': ('NoneRoute', None, None)})
return props
def dependentProps(self):
return GridSizerDTC.dependentProps(self) + ['Growables']
def getNumRowsCols(self, childCompanion):
numRows = self.eval(self.textConstr.params['rows'])
numCols = self.eval(self.textConstr.params['cols'])
return numRows, numCols
#class RowColSizerDTC(FlexGridSizerDTC):
# def writeImports(self):
# return '\n'.join( (GridSizerDTC.writeImports(self),
# 'from wx.lib.rcsizer import RowColSizer') )
class ControlLinkedSizerDTC(SizerDTC):
LinkClass = None
ctrlParam = ''
_linkName = ''
def designTimeObject(self, args = None):
if args is not None:
self.control = self.objClass(**args)
else:
linkClassName = self.LinkClass.__name__[:-3]
dtd = self.designTimeDefaults()
linkObjs = self.designer.controllerView.getObjectsOfClass(self.LinkClass).items()
if not linkObjs:
raise Exception, _('No %s controls available')%linkClassName
linkObjs.sort()
names, objs = [], []
for name, obj in linkObjs:
names.append(name); objs.append(obj)
dlg = wx.SingleChoiceDialog(self.designer, _('Choose control'),
_('Create sizer'), names)
try:
if dlg.ShowModal() != wx.ID_OK:
raise Exception, _('Must choose a control to link with sizer')
idx = dlg.GetSelection()
finally:
dlg.Destroy()
self._linkName = names[idx]
dtd[self.ctrlParam] = objs[idx]
self.control = self.objClass(**dtd)
return self.control
def setConstr(self, constr):
if self._linkName:
constr.params[self.ctrlParam] = self._linkName
SizerDTC.setConstr(self, constr)
def persistConstr(self, className, params):
if self._linkName:
params[self.ctrlParam] = self._linkName
SizerDTC.persistConstr(self, className, params)
def notification(self, compn, action):
if action == 'delete' and compn != self:
compnSrcRef = Utils.srcRefFromCtrlName(compn.name)
if self.textConstr.params.has_key(self.ctrlParam) and \
compnSrcRef == self.textConstr.params[self.ctrlParam]:
self.designer.deleteCtrl(self.name)
class StaticBoxSizerDTC(ControlLinkedSizerDTC):
LinkClass = wx.StaticBox
ctrlParam = 'box'
def __init__(self, name, designer, objClass):
ControlLinkedSizerDTC.__init__(self, name, designer, objClass)
self.editors['Orientation'] = EnumPropEdit
self.names['Orientation'] = {'wx.VERTICAL': wx.VERTICAL,
'wx.HORIZONTAL': wx.HORIZONTAL}
self.options['Orientation'] = [wx.VERTICAL, wx.HORIZONTAL]
self.editors['StaticBox'] = ReadOnlyConstrPropEdit
self._staticBoxParent = None
self._staticBoxLabel = ''
self._staticBoxName = wx.StaticBoxNameStr
def constructor(self):
return {'Name': 'name', 'StaticBox': 'box', 'Orientation': 'orient'}
def designTimeSource(self):
return {'box': 'None', 'orient': 'wx.VERTICAL'}
def designTimeObject(self, args = None):
if args and 'box' in args:
b = args['box']
if b is not None:
if not b: # deleted static box
args['box'] = wx.StaticBox(self._staticBoxParent, -1,
self._staticBoxLabel, name=self._staticBoxName)
else:
self._staticBoxParent = b.GetParent()
self._staticBoxLabel = b.GetLabel()
self._staticBoxName = b.GetName()
return ControlLinkedSizerDTC.designTimeObject(self, args)
##class NotebookSizerDTC(ControlLinkedSizerDTC):
## LinkClass = wx.Notebook
## ctrlParam = 'nb'
## def __init__(self, name, designer, objClass):
## ControlLinkedSizerDTC.__init__(self, name, designer, objClass)
## self.editors['Notebook'] = ReadOnlyConstrPropEdit
##
## def constructor(self):
## return {'Name': 'name', 'Notebook': 'nb'}
##
## def designTimeSource(self):
## wx.LogWarning('wx.NotebookSizer no longer needed, please remove from source. Support will be removed.')
## return {'nb': 'None'}
##
## def properties(self):
## props = ControlLinkedSizerDTC.properties(self)
## del props['Items']
## return props
##
## def defaultAction(self):
## pass
class GridBagSizerDTC(FlexGridSizerDTC):
def __init__(self, name, designer, objClass):
FlexGridSizerDTC.__init__(self, name, designer, objClass)
self.subCompanions['Items'] = GBSizerItemsCDTC
def constructor(self):
return {'Name': 'name', 'VGap': 'vgap', 'HGap': 'hgap'}
def designTimeSource(self):
return {'vgap': '0', 'hgap': '0'}
def getNumRowsCols(self, childCompanion):
maxRows = 0
maxCols = 0
for si in self.control.GetChildren():
(sipr, sipc), (sisr, sisc) = si.GetPos(), si.GetSpan()
if sipr + sisr > maxRows:
maxRows = sipr + sisr
if sipc + sisc > maxCols:
maxCols = sipc + sisc
return maxRows, maxCols
class GBSizerItemsCDTC(SizerItemsCDTC):
def __init__(self, name, designer, parentCompanion, ctrl):
SizerItemsCDTC.__init__(self, name, designer, parentCompanion, ctrl)
self.editors.update({'Position': PositionTuplePropEdit,
'Span': SpanTuplePropEdit })
def constructor(self):
tcl = self.textConstrLst[self.index]
if tcl.method == 'AddWindow':
return {'Window': 0, 'Position': 1,
'Span': 'span', 'Flag': 'flag', 'Border': 'border'}
elif tcl.method == 'AddSizer':
return {'Sizer': 0, 'Position': 1,
'Span': 'span', 'Flag': 'flag', 'Border': 'border'}
elif tcl.method == 'AddSpacer':
return {'Size': 0, 'Position': 1,
'Span': 'span', 'Flag': 'flag', 'Border': 'border'}
def designTimeSource(self, wId, method=None):
if method is None:
method = self.insertionMethod
pos = self.findOpenPosition()
if method == 'AddWindow':
return {0: 'None', 1: repr(pos), 'span': '(1, 1)',
'flag': '0', 'border': '0'}
elif method == 'AddSizer':
return {0: 'None', 1: repr(pos), 'span': '(1, 1)',
'flag': '0', 'border': '0'}
elif method == 'AddSpacer':
return {0: 'wx.Size(8, 8)', 1: repr(pos), 'span': '(1, 1)',
'flag': '0', 'border': '0'}
def findOpenPosition(self):
pos = [0, 0]
while self.control.FindItemAtPosition(tuple(pos)):
pos[1] += 1
return tuple(pos)
def applyDesignTimeDefaults(self, params, method=None):
if method is None:
method = self.insertionMethod
pos = self.eval(params[1])
if self.control.FindItemAtPosition(pos):
raise Exception, _('Cannot use Position %s, an item is already at that position')%params[1]
if pos[0] < 0 or pos[1] < 0:
raise Exception, _('Position %s invalid, cannot contain negative values')%params[1]
span = self.eval(params['span'])
if span[0] < 0 or span[1] < 0:
raise Exception, _('Span %s invalid, cannot contain negative values')%params[1]
if (method in ('AddWindow', 'AddSizer') and params[0] == 'None') or \
(method == 'Insert' and params[1] == 'None'):
defaults = self.designTimeDefaults(params, method)
self.control.AddSizer(BlankSizer(), defaults[1],
defaults['span'], defaults['flag'], defaults['border'])
else:
SizerItemsCDTC.applyDesignTimeDefaults(self, params, method)
def getSizerGUIObject(self):
""" Returns a control, sizer, integer or None """
constr = self.textConstrLst[self.index]
srcRef = constr.params[0]
if srcRef != 'None':
if srcRef.startswith('wx.Size'):
return self.index
else:
return self.designer.controllerView.getAllObjects()[srcRef]
else:
return None
def persistProp(self, name, setterName, value):
SizerItemsCDTC.persistProp(self, name, setterName, value)
if name in ('Position', 'Span'):
obj = self.getSizerGUIObject()
if obj is not None:
getattr(self.control, 'SetItem'+name)(obj, self.eval(value))
self.updateGUI()
class TupleConstrPropEdit(ConstrPropEdit):
def inspectorEdit(self):
self.editorCtrl = TextCtrlIEC(self, self.value)
self.editorCtrl.createControl(self.parent, self.value, self.idx,
self.width)
def getValue(self):
if self.editorCtrl:
self.value = self.editorCtrl.getValue()
else:
self.value = self.getCtrlValue()
return self.value
class PositionTuplePropEdit(TupleConstrPropEdit):
def getStyle(self):
return [esExpandable]
def getSubCompanion(self):
return PositionRowColDTC
class SpanTuplePropEdit(TupleConstrPropEdit):
def getStyle(self):
return [esExpandable]
def getSubCompanion(self):
return SpanRowColDTC
class PositiveIntPropEdit(IntPropEdit):
def inspectorEdit(self):
IntPropEdit.inspectorEdit(self)
self.editorCtrl.editorCtrl.SetRange(0, sys.maxint)
class RowColDTC(HelperDTC):
propName = 'Prop'
paramName = 'param'
setterMethod = 'Setter'
def __init__(self, name, designer, cmpn, obj, ownerPW):
HelperDTC.__init__(self, name, designer, cmpn, obj, ownerPW)
self.editors = {'Row' : PositiveIntPropEdit,
'Column' : PositiveIntPropEdit}
def properties(self):
return {'Row': ('NameRoute', self.GetRowCol, self.SetRowCol),
'Column': ('NameRoute', self.GetRowCol, self.SetRowCol)}
def GetRowCol(self, name):
t = self.eval(self.ownerCompn.textConstr.params[self.paramName])
if name == 'Row':
return t[0]
elif name == 'Column':
return t[1]
def SetRowCol(self, name, value):
t = self.eval(self.ownerCompn.textConstr.params[self.paramName])
obj = self.ownerCompn.getSizerGUIObject()
if name == 'Row':
newVal = (value, t[1])
elif name == 'Column':
newVal = (t[0], value)
self.ownerCompn.textConstr.params[self.paramName] = `newVal`
self.designer.inspector.constructorUpdate(self.propName)
# XXX Setting to an existing position causes asserts and is wrong
# XXX Not sure how to handle this everywhere in the GridBagSizer support
getattr(self.ownerCompn.control, self.setterMethod)( obj, newVal )
class PositionRowColDTC(RowColDTC):
propName = 'Position'
paramName = 1
setterMethod = 'SetItemPosition'
class SpanRowColDTC(RowColDTC):
propName = 'Span'
paramName = 'span'
setterMethod = 'SetItemSpan'
#-------------------------------------------------------------------------------
import Plugins
Plugins.registerComponents('ContainersLayout',
(wx.BoxSizer, 'wx.BoxSizer', BoxSizerDTC),
(wx.GridSizer, 'wx.GridSizer', GridSizerDTC),
(wx.FlexGridSizer, 'wx.FlexGridSizer', FlexGridSizerDTC),
(wx.StaticBoxSizer, 'wx.StaticBoxSizer', StaticBoxSizerDTC),
# (wx.NotebookSizer, 'wx.NotebookSizer', NotebookSizerDTC),
(wx.GridBagSizer, 'wx.GridBagSizer', GridBagSizerDTC),
)
|