daboide Commit Revision 120 Date: 2005-06-30 11:12:58 -0700 (Thu, 30 Jun 2005) Author: ed
Changed: U trunk/Designer.py U trunk/DesignerControlMixin.py U trunk/DesignerFormMixin.py U trunk/DesignerPropSheet.py
Log: Added support for custom property editors. Instead of trying to build them into the grid as wx.grid editor/renderers, you can simply specify a "customEditor" key in the property dict for a given property. If this is a simple string, it is assumed that it is the name of a standard editor included in the PropSheet class (e.g., 'colorEditor'). It can also be a method reference in the custom object being edited, allowing for any level of customization desired.
If such a custom editor is defined, a button labeled 'Edit...' will appear, and clicking it will call the custom editor method. These methods expect to receive the following parameters: - A list containing the currently selected objects - The name of the property being edited - The current value of that property The method is responsible for getting the new value, and updating the Designer.
Also fixed some bugs that were throwing errors upon exiting the app.
Diff: Modified: trunk/Designer.py =================================================================== --- trunk/Designer.py 2005-06-30 14:29:45 UTC (rev 119) +++ trunk/Designer.py 2005-06-30 18:12:58 UTC (rev 120) @@ -27,6 +27,7 @@ self._treeForm = None self._selection = [] self._editors = [] + self.isClosing = False self.MainFormClass = None self.setup()
Modified: trunk/DesignerControlMixin.py =================================================================== --- trunk/DesignerControlMixin.py 2005-06-30 14:29:45 UTC (rev 119) +++ trunk/DesignerControlMixin.py 2005-06-30 18:12:58 UTC (rev 120) @@ -290,11 +290,14 @@ def _getDesProps(self): - ret = {"BackColor": {"type" : "color", "readonly" : False}, + ret = {"BackColor": {"type" : "color", "readonly" : False, + "customEditor": "editColor"}, "Caption": {"type" : str, "readonly" : False}, "FontBold": {"type" : bool, "readonly" : False}, "FontItalic": {"type" : bool, "readonly" : False}, "FontSize": {"type" : int, "readonly" : False}, + "ForeColor": {"type" : "color", "readonly" : False, + "customEditor": "editColor"}, "Left": {"type" : int, "readonly" : True}, "Name": {"type" : str, "readonly" : True}, "Sizer_Proportion": {"type" : int, "readonly" : False},
Modified: trunk/DesignerFormMixin.py =================================================================== --- trunk/DesignerFormMixin.py 2005-06-30 14:29:45 UTC (rev 119) +++ trunk/DesignerFormMixin.py 2005-06-30 18:12:58 UTC (rev 120) @@ -442,8 +442,12 @@ obj = evt.EventObject self.selectControl(obj) + + def close(self): + # Needed to avoid resizing errors when quitting + self.app.isClosing = True + super(DesignerFormMixin, self).close() - def onMouseDrag(self, evt): if self.dragging: if self.handleDragged is not None: @@ -534,7 +538,8 @@ return self._canContain def _getDesProps(self): - return {"BackColor": {"type" : "color", "readonly" : False}, + return {"BackColor": {"type" : "color", "readonly" : False, + "customEditor": "editColor"}, "Caption": {"type" : str, "readonly" : False}, "Height": {"type" : int, "readonly" : False}, "Width": {"type" : int, "readonly" : False},
Modified: trunk/DesignerPropSheet.py =================================================================== --- trunk/DesignerPropSheet.py 2005-06-30 14:29:45 UTC (rev 119) +++ trunk/DesignerPropSheet.py 2005-06-30 18:12:58 UTC (rev 120) @@ -44,6 +44,8 @@ def getPropDictForRow(self, row): prop = self.getValue(row, 0) + if not prop: + return None try: return self.propDict[prop] except KeyError, e: @@ -78,6 +80,7 @@ ed = gridlib.GridCellTextEditor() self.SetCellEditor(row, 1, ed) self.SetCellRenderer(row, 1, rnd) + self.updateGridDisplay() def customCanGetValueAs(self, row, col, typ): @@ -114,18 +117,38 @@ if self.RowCount < 1: return row, col = evt.EventData["row"], evt.EventData["col"] - # Only the second column is editable - if col == 1: - pd = self.getPropDictForRow(row) - self.Editable = not pd["readonly"] - else: + self.updateGridDisplay(row, col) + + + def updateGridDisplay(self, row=None, col=None): + if row is None: + row = self.CurrentRow + if col is None: + col = self.CurrentColumn + pd = self.getPropDictForRow(row) + if pd is None: + return + self.Editable = not pd["readonly"] + custEditor = None + try: + if self.Editable: + custEditor = pd["customEditor"] + self.Editable = False + except KeyError: + custEditor = None + if col == 0: + # Only the second column is directly editable self.Editable = False - if self.Editable: - self._origVal = self.getValue(row, col) - # For some reason, this doesn't seem to work... - dabo.ui.callAfter(self.EnableCellEditControl) - else: - dabo.ui.callAfter(self.DisableCellEditControl) + # Tell the parent how to handle any custom edits + self.Parent.setCustomEditor(custEditor) + + if not self.Parent.app.isClosing: + if self.Editable: + self._origVal = self.getValue(row, col) + # For some reason, this doesn't seem to work... + dabo.ui.callAfter(self.EnableCellEditControl) + else: + dabo.ui.callAfter(self.DisableCellEditControl) def onGridCellEdited(self, row, col, newVal): @@ -134,25 +157,58 @@ if newVal != self._origVal: prop = self.getValue(row, 0) self.Parent.updateVal(prop, newVal, typ) + + + def _getCurrProp(self): + return self.getValue(self.CurrentRow, 0) + + def _getCurrVal(self): + return self.getValue(self.CurrentRow, 1) + def _setCurrVal(self, val): + self.setValue(self.CurrentRow, 1, val) + + CurrentProperty = property(_getCurrProp, None, None, + _("Name of currently selected property (string)") ) + CurrentValue = property(_getCurrVal, _setCurrVal, None, + _("Value of currently selected property (varies)") ) + + class PropSheet(dabo.ui.dPanel): def afterInit(self): - self.txtObj = dabo.ui.dTextBox(self) - self.txtObj.Enabled = False + self.txtObj = dabo.ui.dTextBox(self, Enabled=False) + self.btnEdit = dabo.ui.dButton(self, Caption=_("Edit...")) + self.btnEdit.bindEvent(dEvents.Hit, self.onEdit) self.propGrid = pg = PropertyGrid(self) self.Sizer = sz = dabo.ui.dSizer("v") - sz.append(self.txtObj, "x") + hsz = dabo.ui.dSizer("h") + hsz.append(self.txtObj, 1, "x") + hsz.appendSpacer(12) + hsz.append(self.btnEdit, "x") + sz.append(hsz, "x") # Don't expand the grid; the onResize will handle that. sz.append(pg, 1) + # Reference to the currently selected object(s) + self._selected = [] + # Holds a reference to the custom editor method + self._custEditor = None def initEvents(self): self.bindEvent(dEvents.Resize, self.onResize) + def onEdit(self, evt): + ed = self._custEditor + if ed is not None: + # Pass the selected object(s), and the prop being edited + pg = self.propGrid + ed(self._selected, pg.CurrentProperty, pg.CurrentValue) + + def setInitialSizing(self): - """Called to fit the prop sheet to the form""" + """Called to fit the prop sheet to the form""" self.propGrid.autoSizeCol(0) # Give it a little extra self.propGrid.Columns[0].Width += 25 @@ -168,6 +224,15 @@ pg.Columns[1].Width = wd - wd0 + def setCustomEditor(self, ed): + if isinstance(ed, basestring): + # it is the name of a method in this class + ed = eval("self.%s" % ed) + self._custEditor = ed + self.btnEdit.Visible = (ed is not None) + self.layout() + + def select(self, obj): """Called when the selected object changes. 'obj' will be a list containing either a single object or multiple @@ -176,6 +241,7 @@ editing to only those props that are common to all of the selection. """ + self._selected = obj mult = len(obj) > 1 ob = obj[0] # If the selected object is an empty sizer slot, the way that this @@ -222,7 +288,8 @@ propDict = ob.DesignerProps # Copy it to the grid - self.propGrid.propDict = copy.deepcopy(propDict) + pg = self.propGrid + pg.propDict = copy.deepcopy(propDict) props = propDict.keys() props.sort() if mult: @@ -275,9 +342,9 @@ rec["val"] = "" break ds.append(rec) - self.propGrid.dataSet = ds - self.propGrid.Enabled = (len(props) > 0) - self.propGrid.fillGrid() + pg.dataSet = ds + pg.Enabled = (len(props) > 0) + pg.fillGrid() def updateVal(self, prop, val, typ): @@ -287,7 +354,22 @@ """ self.app.updatePropVal(prop, val, typ) + + ############################## + # Custom property editor methods + ############################## + def editColor(self, objs, prop, val): + obj = objs[0] + newVal = dabo.ui.getColor(val) + if newVal is not None: + self.app.updatePropVal(prop, newVal, "color") + self.propGrid.CurrentValue = newVal + + + + + class ColorCellRenderer(gridlib.PyGridCellRenderer): def Draw(self, grid, attr, dc, rect, row, col, isSelected): dc.SetBackgroundMode(wx.SOLID)
©2005 Ed Leafe |
|