[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnue] r8397 - in trunk: gnue-designer/src/base gnue-designer/src/base/t
From: |
jcater |
Subject: |
[gnue] r8397 - in trunk: gnue-designer/src/base gnue-designer/src/base/tools gnue-designer/src/forms gnue-designer/src/forms/PagePainter/skins gnue-designer/src/ui/wx/uihelpers/doccanvas gnue-forms/samples/intro gnue-forms/src |
Date: |
Mon, 10 Apr 2006 12:14:45 -0500 (CDT) |
Author: jcater
Date: 2006-04-10 12:14:44 -0500 (Mon, 10 Apr 2006)
New Revision: 8397
Modified:
trunk/gnue-designer/src/base/Document.py
trunk/gnue-designer/src/base/Incubator.py
trunk/gnue-designer/src/base/tools/PropertyEditor.py
trunk/gnue-designer/src/forms/PagePainter/skins/common.py
trunk/gnue-designer/src/forms/PropertyEditor.py
trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/canvas.py
trunk/gnue-forms/samples/intro/intro.gfd
trunk/gnue-forms/src/GFParser.py
Log:
more work on the new property editor, allowing multiple objects to be selected
Modified: trunk/gnue-designer/src/base/Document.py
===================================================================
--- trunk/gnue-designer/src/base/Document.py 2006-04-09 17:18:40 UTC (rev
8396)
+++ trunk/gnue-designer/src/base/Document.py 2006-04-10 17:14:44 UTC (rev
8397)
@@ -334,7 +334,7 @@
# Private functions
# ================================================================
- def __init__(self, app, properties, location=None,
+ def __init__(self, app, properties, location=None,
buffer=None, style=None):
EventController.__init__(self)
@@ -347,7 +347,7 @@
self.startCachingEvents()
self.ui = app.ui.createInstance(self)
-
+
# Local variables
self.wizardName = ""
self._isdirty = False
Modified: trunk/gnue-designer/src/base/Incubator.py
===================================================================
--- trunk/gnue-designer/src/base/Incubator.py 2006-04-09 17:18:40 UTC (rev
8396)
+++ trunk/gnue-designer/src/base/Incubator.py 2006-04-10 17:14:44 UTC (rev
8397)
@@ -100,7 +100,7 @@
# ----------------------------------------------------------------------
# Delete an object
# ----------------------------------------------------------------------
- def deleteObject(self, rootObject, object,
+ def deleteObject(self, rootObject, object,
newCurrentObject=None, firstRun=1):
if firstRun:
@@ -126,14 +126,12 @@
# Internal stuff
# ----------------------------------------------------------------------
- def __init__(self, instance):
- self.document = instance
+ def __init__(self, document):
+ self.document = document
- # Figure out tag dependencies
- self._calcDependencies()
+ # Calculate dependencies between tags
- def _calcDependencies(self):
self.elementMapping = elementMapping = {}
elements = self.elements
@@ -150,6 +148,35 @@
else:
parents = None
+ # Make sure attributes have all tags that designer requires
+ if t.has_key('Attributes'):
+ for attribute_name, attribute in t['Attributes'].items():
+ if not attribute.has_key('Label'):
+ # This little tidbit does mixed case
+ # with '_' converted to spaces
+ words = attribute_name.split(':',1)[-1].split('_')
+ for index, text in enumerate(words):
+ words[index] = text.capitalize()
+ label = " ".join(words)
+
+ # Cache it so we don't have to do this each time
+ attribute['Label'] = label
+ if not attribute.has_key('Required'):
+ attribute['Required'] = False
+ if not attribute.has_key('Unique'):
+ attribute['Unique'] = False
+ if not attribute.has_key('Deprecated'):
+ attribute['Deprecated'] = False
+ if not attribute.has_key('References'):
+ attribute['References'] = None
+ if not attribute.has_key('ValidSet'):
+ attribute['ValidSet'] = {}
+ if not attribute.has_key('Description'):
+ attribute['Description'] = attribute['Label']
+ else:
+ t['Attributes'] = {}
+
+
if parents != None:
for parent in parents:
try:
Modified: trunk/gnue-designer/src/base/tools/PropertyEditor.py
===================================================================
--- trunk/gnue-designer/src/base/tools/PropertyEditor.py 2006-04-09
17:18:40 UTC (rev 8396)
+++ trunk/gnue-designer/src/base/tools/PropertyEditor.py 2006-04-10
17:14:44 UTC (rev 8397)
@@ -20,7 +20,9 @@
# - Suite 330, Boston, MA 02111-1307, USA.
#
# $Id$
+
"""
+A property editor tool
"""
__all__ = ['PropertyEditor']
@@ -38,6 +40,12 @@
class PropertyEditor(ToolBase):
+ """
+ Edit the property of the currently selected object.
+
+ If multiple objects are selected, it shows the intersection
+ of common attributes.
+ """
runtime_section = 'PropertyEditor'
default_dock = 'left-1'
@@ -50,185 +58,202 @@
# 'ObjectModified' : self.object_modified_event,
# 'ObjectDeleted' : self.object_deleted_event,
})
-
+
self.listctrl = listctrl = PropertyEditorListCtrl(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(listctrl, 1, wx.EXPAND|wx.ALL, 0)
self.SetAutoLayout(True)
self.SetSizer(sizer)
+ listctrl.SetFont(wx.SMALL_FONT)
+
def object_selected_event (self, event):
"""
- Called on the ObjectSelected event.
-
- Display all properties of a widget, or the common
- properties of all selected widgets, if multiple
+ Called on the ObjectSelected event.
+
+ Display all properties of a widget, or the common
+ properties of all selected widgets, if multiple
widgets are selected.
"""
# Get selected objects, or the current object
- try:
+ try:
objects = event.selection
- except:
- objects = [event.object]
+ except:
+ if event.object:
+ objects = [event.object]
+ else:
+ objects = []
- self.objects = objects
+ self.__current_objects = objects
# Remove any previous entries
self.listctrl.ClearAll()
self.listctrl.InsertColumn(0,'Property')
self.listctrl.InsertColumn(1,'Value')
-
- for gobject in objects:
+ if not objects:
+ return
- definition_map = gobject.gparser_definition['Attributes']
-
- # Define our rows
- self.row_list = row_list = []
- add_row_list = row_list.append
- for attribute_name, attributes in definition_map.items():
+ # Merge the attribute lists from the selected properties.
+ common_attributes = {}
+ common_values = {}
+ unique_attributes = {}
+ dropped_attributes = {}
+ first_object = True
+ for gobject in objects:
+
+ attributes = gobject.gparser_definition['Attributes']
+
+ for attribute_name, attribute in attributes.items():
+
try:
- label = attributes['Label']
- except KeyError:
- # This little tidbit does mixed case w/'_' as separators
- words = attribute_name.split(':',1)[-1].split('_')
- index=0
- for text in words:
- words[index] = text.capitalize()
- index+=1
- label = " ".join(words)
-
- # Cache it so we don't have to do this each time
- attributes['Label'] = label
-
- add_row_list((label, attribute_name))
+ value = gobject[attribute_name]
+ except:
+ value = attributes.get('Default',None)
- index = self.listctrl.InsertStringItem(sys.maxint, label)
- self.listctrl.SetStringItem(index, 0, label)
- self.listctrl.SetStringItem(index, 1, "value")
- #self.listctrl.SetItemData(index, attribute_name)
-
- print label
-
- row_list.sort()
-
- return
-
-
- # Only show properties for nondeprecated values (unless set)
- i = 0
- for index in row_list:
- label, key = self.rowList[i]
- xkey = key.replace(':','__')
- if self.attributes[key].has_key ('Deprecated') and \
- self.attributes[key]['Deprecated'] and \
- (not hasattr(gobject, xkey) or \
- (self.attributes[key].has_key('Default') and \
- gobject.__dict__[xkey] ==
self.attributes[key]['Default'] ) ):
- self.rowList.pop(i)
+ # If we've already decided this attribute isn't
+ # common, don't do the tests again
+ if dropped_attributes.has_key(attribute_name):
+ continue
+
+ # This may be a tad drastic; drop any deprecated attributes
+ if attribute['Deprecated']:
+ continue
+
+ if first_object:
+ # First loop thru, nothing to compare
+ common_attributes[attribute_name] = attribute
+ common_values[attribute_name] = value
+ elif first_object or \
+ not common_attributes.has_key(attribute_name):
+ # First time seeing attribute, so nothing to compare
+ common_attributes[attribute_name] = attribute
+ common_values[attribute_name] = value
else:
- i = i + 1
+ # Do a diff of current and previous attribute instance
+ common = common_attributes[attribute_name]
+ if attribute['Typecast'] == common['Typecast'] and \
+ attribute['Label'] == common['Label'] and \
+ attribute['References'] == common['References'] and \
+ attribute['ValidSet'].keys() == common['ValidSet'].keys():
- return
- y = 2
- maxLabel = 0
- for text, key in self.rowList:
+ # Attributes match. Do the values?
+ if common_values.has_key(attribute_name) and \
+ value != common_values:
+ value = MixedValues
- xkey = key.replace(':','__')
+ common_values[attribute_name] == value
+ else:
+ # Attributes don't match, so add to our black list
+ dropped_attributes[attribute_name] = True
+ del common_attributes[attribute_name]
- # If an attribute has a "Label", use it;
- # otherwise create one from its name.
+ # Keep track of attributes that are unique
+ if attribute['Unique']:
+ unique_attributes[attribute_name] = True
- if self.attributes[key]['Typecast'] == GTypecast.boolean:
- text = u_('%s?') % text
- else:
- text = u_('%s:') % text
+ first_object = False
+ # Remove all "Unique" attributes if there's more than one object
+ if len(objects) > 1:
+ for attribute_name in unique_attributes.keys():
+ del common_attributes[attribute_name]
- try:
- label = wx.StaticText (self.labelPanel, -1, text)
- label.SetFont(wx.SMALL_FONT)
+ # Sort by label
+ sorted_attributes = [(attribute['Label'], (attribute_name, attribute))
+ for attribute_name, attribute in common_attributes.items()]
+ sorted_attributes.sort()
+ sorted_attributes = [ attribute_pair \
+ for label, attribute_pair in sorted_attributes]
- except:
- pass
+ # Save the sorted attribute list for future use
+ self.attribute_list = sorted_attributes
- # Determine the type of Cell Editor we want
- # (Integer, Boolean, Dropdown, Char)
- if self.attributes[key].has_key('ValueSet'):
- field = LimitedSetEditor(self.fieldPanel,self.attributes[key])
- wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
- elif self.attributes[key].has_key('References'):
- tag, attr = self.attributes[key]['References'].split('.')
- objectList = self.editor.document.getObjectList(tag)
- field = LinkedTextEditor(self.fieldPanel,
- self.attributes[key],
- objectList,
- attr)
- wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
- elif self.attributes[key]['Typecast'] == GTypecast.boolean:
- field = BoolEditor(self.fieldPanel,self.attributes[key])
- wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
- elif self.attributes[key]['Typecast'] in (GTypecast.integer,
- GTypecast.number, GTypecast.whole):
- field = IntEditor(self.fieldPanel,self.attributes[key])
- wx.EVT_SPINCTRL(field, field.GetId(), self.__valueModified)
- else:
- field = TextEditor(self.fieldPanel,self.attributes[key])
- wx.EVT_TEXT(field, field.GetId(), self.__valueModified)
+ # We have all the data we need, so add them to our edit list
+ for attribute_name, attribute in sorted_attributes:
- field.SetFont(wx.SMALL_FONT)
+ # Define our rows
+ index = self.listctrl.InsertStringItem(sys.maxint,
+ attribute['Label'])
+ self.listctrl.SetStringItem(index, 0, attribute['Label'])
+ self.listctrl.SetStringItem(index, 1,
+ str(common_values[attribute_name]))
+ #self.listctrl.SetItemData(index, attribute_name)
- # Generate a tooltip from the description.
- # Note that tooltips can have {Name} tokens
- try:
- tooltip = self.attributes[key]['Description']
- try:
- for v, l in self.attributes[key]['ValueSet'].items():
- tooltip = tooltip.replace('{%s}' % v,
- '"%s"' % l['Label'])
- except KeyError:
- pass
- tooltip = tooltip.replace('{Y}','"True"')
- tooltip = tooltip.replace('{N}','"False"')
- tooltip = tooltip.replace('{','"')
- tooltip = tooltip.replace('}','"')
- field.SetToolTip(wx.ToolTip(tooltip))
- except KeyError:
- pass
- # Align the centers of the field and label
- fx, fy = field.GetSizeTuple()
- lx, ly = label.GetSizeTuple()
- maxy = max(fy, ly)
- maxLabel = max(maxLabel, lx+4)
- field.SetPosition((2, int((maxy - fy)/2) + y))
- label.SetPosition((4, int((maxy - ly)/2) + y))
- # Next y...
- y += maxy
+ ## Determine the type of Cell Editor we want
+ ## (Integer, Boolean, Dropdown, Char)
+ #if self.attributes[key].has_key('ValueSet'):
+ #field = LimitedSetEditor(self.fieldPanel,self.attributes[key])
+ #wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
+ #elif self.attributes[key].has_key('References'):
+ #tag, attr = self.attributes[key]['References'].split('.')
+ #objectList = self.editor.document.getObjectList(tag)
+ #field = LinkedTextEditor(self.fieldPanel,
+ #self.attributes[key],
+ #objectList,
+ #attr)
+ #wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
+ #elif self.attributes[key]['Typecast'] == GTypecast.boolean:
+ #field = BoolEditor(self.fieldPanel,self.attributes[key])
+ #wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
+ #elif self.attributes[key]['Typecast'] in (GTypecast.integer,
+ #GTypecast.number, GTypecast.whole):
+ #field = IntEditor(self.fieldPanel,self.attributes[key])
+ #wx.EVT_SPINCTRL(field, field.GetId(), self.__valueModified)
+ #else:
+ #field = TextEditor(self.fieldPanel,self.attributes[key])
+ #wx.EVT_TEXT(field, field.GetId(), self.__valueModified)
- # Set the initial value of the cells to the current property values
- if hasattr(object, xkey):
- field.SetValue(object.__dict__[xkey])
+ #field.SetFont(wx.SMALL_FONT)
- self.fields.append(field)
- self.labels.append(label)
-
+ ## Generate a tooltip from the description.
+ ## Note that tooltips can have {Name} tokens
+ #try:
+ #tooltip = self.attributes[key]['Description']
+ #try:
+ #for v, l in self.attributes[key]['ValueSet'].items():
+ #tooltip = tooltip.replace('{%s}' % v,
+ #'"%s"' % l['Label'])
+ #except KeyError:
+ #pass
+ #tooltip = tooltip.replace('{Y}','"True"')
+ #tooltip = tooltip.replace('{N}','"False"')
+ #tooltip = tooltip.replace('{','"')
+ #tooltip = tooltip.replace('}','"')
+ #field.SetToolTip(wx.ToolTip(tooltip))
+ #except KeyError:
+ #pass
+ self.listctrl.SetColumnWidth(0, wx.LIST_AUTOSIZE)
-class PropertyEditorListCtrl(wx.ListCtrl, #mixins.TextEditMixin,
- mixins.ListCtrlAutoWidthMixin):
- def __init__(self, tool):
- wx.ListCtrl.__init__(self, tool, -1,
+class MixedValues:
+ """
+ Used internally
+ """
+ def __str__(self):
+ return u_("(Multiple)")
+
+class PropertyEditorListCtrl(wx.ListCtrl, mixins.TextEditMixin,
+ mixins.ListCtrlAutoWidthMixin):
+ def __init__(self, tool):
+ wx.ListCtrl.__init__(self, tool, -1,
style=wx.LC_REPORT|wx.LC_HRULES|wx.LC_VRULES)
- #mixins.TextEditMixin.__init__(self)
- #mixins.ListCtrlAutoWidthMixin.__init__(self)
- self.InsertColumn(0,'Property')
- self.InsertColumn(1,'Value')
- self.SetColumnWidth(0, wx.LIST_AUTOSIZE)
-
+ mixins.TextEditMixin.__init__(self)
+ mixins.ListCtrlAutoWidthMixin.__init__(self)
+
+ def OpenEditor(self, col, row):
+ """
+ Override OpenEditor to make our label column non-editable
+ """
+ if col == 0:
+ return
+
+ return mixins.TextEditMixin.OpenEditor(self, col, row)
+
# def SetStringItem(self, index, col, data):
# if col < 2:
# wx.ListCtrl.SetStringItem(self, index, col, data)
@@ -243,468 +268,3 @@
# data = self.GetItem(index, col-2).GetText()
# wx.ListCtrl.SetStringItem(self, index, col-2, data[0:datalen])
-
-class PropertyEditorXXX: # (ToolNotebook):
-
- runtime_section = 'PropertyEditor'
- default_dock = 'left-1'
-
- def init(self):
-
- self.object = None
-
- # EventAware provided by ToolBase
- self.registerEventListeners({
- 'ObjectSelected' : self.object_selected_event,
- 'ObjectCreated' : self.object_created_event,
- 'ObjectModified' : self.object_modified_event,
- 'ObjectDeleted' : self.object_deleted_event,
- })
-
- self.supplemental = []
- self.main = self.createMainPage()
- self.notebook.AddPage(self.main,'Properties')
- self.notebook.SetFont(wx.SMALL_FONT)
-
-
- def createMainPage(self):
- return InspectorPanel(self, self.notebook)
-
- def object_selected_event (self, event):
- return
- object = event.object
- handler = event.originator
- if object == None:
- return
- if object != self.object:
- self.setCurrent(object)
-
- def setCurrent(self, object):
- self.object = object
- self.reset()
- self.main.setCurrent(object)
- self.notebook.SetPageText(0, self.main.getPageText())
- i = 1
- for page in self.supplemental:
- page.setCurrent(object)
- self.notebook.SetPageText(i, page.getPageText())
- i += 1
-
- def addPage(self, inspector, label):
- self.supplemental.append(inspector)
- self.notebook.AddPage(inspector, label)
-
- def reset(self):
- for i in range(len(self.supplemental)):
- self.notebook.DeletePage(1)
- self.supplemental = []
-
- def object_created_event (self, event):
- object = event.object
- handler = event.originator
-
- def object_modified_event (self, event):
- object = event.object
- if object == None:
- return
-
- if event.originator != __name__:
- for page in [self.main] + self.supplemental:
- page.resetValues(object)
-
- def object_deleted_event (self, event):
- object = event.object
- handler = event.originator
- if object == None:
- return
- if handler != __name__:
- pass
-
-
-#
-#
-#
-class InspectorPanel(wx.ScrolledWindow):
-
- NAMESPACE = ""
-
- def __init__(self, editor, parent):
- wx.ScrolledWindow.__init__(self, parent, -1, style = wx.HSCROLL)
- self.splitter = splitter = wx.SplitterWindow(self, -1,
style=wx.SP_3DSASH | wx.SP_NOBORDER)
- self.object = None
- self.editor = editor
- self.fields = []
- self.labels = []
-
- # These will be set in _setCurrent
- self.maxy = 0
- self.maxLabel = 0
-
- self.labelPanel = wx.Panel(splitter, -1)
- self.fieldPanel = wx.Panel(splitter, -1)
- splitter.SplitVertically(self.labelPanel, self.fieldPanel)
- wx.EVT_SPLITTER_SASH_POS_CHANGED(self,
self.splitter.GetId(),self.__onSize)
- wx.EVT_SIZE(self, self.__onSize)
-
-
- def getAttributes(self, object):
- elements = self.editor.document.incubator.elements
- try:
- return elements[(object._type[2:]).lower()]['Attributes']
- except KeyError:
- return {}
-
-
- def _setCurrent(self, object):
- self.object = object
- self.attributes = self.getAttributes(object)
-
- # Define our rows
- self.rowList = []
- for key, attributes in self.attributes.items():
- try:
- label = attributes['Label']
- except KeyError:
- # This little tidbit does mixed case w/'_' as separators
- words = key.split(':',1)[-1].split('_')
- for j in xrange(len(words)):
- words[j] = words[j].capitalize()
- label = " ".join(words)
- self.rowList.append((label, key))
- self.rowList.sort()
-
- # Get rid of any old fields
- for i in range(len(self.fields)):
- field = self.fields.pop()
- field.Destroy()
- label = self.labels.pop()
- label.Destroy()
-
- # Only show properties for nondeprecated values (unless set)
- i = 0
- while i < len(self.rowList):
- label, key = self.rowList[i]
- xkey = key.replace(':','__')
- if self.attributes[key].has_key ('Deprecated') and \
- self.attributes[key]['Deprecated'] and \
- (not hasattr(object, xkey) or \
- (self.attributes[key].has_key('Default') and \
- object.__dict__[xkey] == self.attributes[key]['Default'] )
):
- self.rowList.pop(i)
- else:
- i = i + 1
-
- y = 2
- maxLabel = 0
- for text, key in self.rowList:
-
- xkey = key.replace(':','__')
-
- # If an attribute has a "Label", use it;
- # otherwise create one from its name.
-
- if self.attributes[key]['Typecast'] == GTypecast.boolean:
- text = u_('%s?') % text
- else:
- text = u_('%s:') % text
-
- try:
- label = wx.StaticText (self.labelPanel, -1, text)
- label.SetFont(wx.SMALL_FONT)
-
- except:
- pass
-
- # Determine the type of Cell Editor we want
- # (Integer, Boolean, Dropdown, Char)
- if self.attributes[key].has_key('ValueSet'):
- field = LimitedSetEditor(self.fieldPanel,self.attributes[key])
- wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
- elif self.attributes[key].has_key('References'):
- tag, attr = self.attributes[key]['References'].split('.')
- objectList = self.editor.document.getObjectList(tag)
- field = LinkedTextEditor(self.fieldPanel,
- self.attributes[key],
- objectList,
- attr)
- wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
- elif self.attributes[key]['Typecast'] == GTypecast.boolean:
- field = BoolEditor(self.fieldPanel,self.attributes[key])
- wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
- elif self.attributes[key]['Typecast'] in (GTypecast.integer,
- GTypecast.number, GTypecast.whole):
- field = IntEditor(self.fieldPanel,self.attributes[key])
- wx.EVT_SPINCTRL(field, field.GetId(), self.__valueModified)
- else:
- field = TextEditor(self.fieldPanel,self.attributes[key])
- wx.EVT_TEXT(field, field.GetId(), self.__valueModified)
-
- field.SetFont(wx.SMALL_FONT)
-
- # Generate a tooltip from the description.
- # Note that tooltips can have {Name} tokens
- try:
- tooltip = self.attributes[key]['Description']
- try:
- for v, l in self.attributes[key]['ValueSet'].items():
- tooltip = tooltip.replace('{%s}' % v,
- '"%s"' % l['Label'])
- except KeyError:
- pass
- tooltip = tooltip.replace('{Y}','"True"')
- tooltip = tooltip.replace('{N}','"False"')
- tooltip = tooltip.replace('{','"')
- tooltip = tooltip.replace('}','"')
- field.SetToolTip(wx.ToolTip(tooltip))
- except KeyError:
- pass
-
- # Align the centers of the field and label
- fx, fy = field.GetSizeTuple()
- lx, ly = label.GetSizeTuple()
- maxy = max(fy, ly)
- maxLabel = max(maxLabel, lx+4)
- field.SetPosition((2, int((maxy - fy)/2) + y))
- label.SetPosition((4, int((maxy - ly)/2) + y))
-
- # Next y...
- y += maxy
-
- # Set the initial value of the cells to the current property values
- if hasattr(object, xkey):
- field.SetValue(object.__dict__[xkey])
-
- self.fields.append(field)
- self.labels.append(label)
-
- self.splitter.SetSashPosition(maxLabel+2)
- self.maxy = y
- self.maxLabel = maxLabel
- self.__onSize(None)
-
- # Reset the values displayed based on the values on the object
- def resetValues(self, object):
- if object != self.object:
- return
- for i in range(len(self.fields)):
- xkey = self.rowList[i][1].replace(':','__')
- field = self.fields[i]
- # Set the initial value of the cells to the current property values
- if hasattr(object, xkey):
- field.SetValue(object.__dict__[xkey])
- else:
- try:
- field.Clear()
- except AttributeError:
- print 'TODO: IntEditor has no Clear()'
-
- def getPageText(self):
- return self.object._type[2:]
-
- def __onSize(self, event):
- x, y = self.GetClientSizeTuple()
- my = max(y, self.maxy)
- self.splitter.SetSize((x, my ))
- self.splitter.SetSashPosition(self.maxLabel+2)
- self.SetVirtualSize((x, my))
- if my > y:
- self.SetScrollRate(0,10)
- #fw = self.fieldPanel.GetSize().x - 4
- #for field in self.fields:
- # field.SetSize((fw, field.GetSize().y))
-
- # Notify system that the object has been modified
- def __valueModified(self, event):
- field = event.GetEventObject()
- try:
- attr = self.rowList[self.fields.index(field)][1]
- except ValueError:
- return
-
- value = field.GetValue()
-
- xkey = attr.replace(':','__')
- try:
- try:
- ov = self.object[attr]
- except KeyError:
- ov = None
-
- oldVal = {attr: ov}
-
- # We only care if user actually changed the current value...
- if ov != value and not (ov == None and value in (0,'')):
- # If value is None, then user basically selected "No value"
- if value != None:
- # Typecast the value, then store in the object's dictionary
- value = self.attributes[attr]['Typecast'](value)
- else:
- # No value... try to set value as "default" value
- try:
- value = self.attributes[attr]['Default']
- except KeyError:
- # Otherwise leave as None
- pass
-
- self.object.__dict__[xkey] = value
- newVal = {attr: value}
-
- self.editor.dispatchEvent('ObjectModified',
- object=self.object,
- originator=__name__,
- old=oldVal,
- new=newVal)
-
- except ValueError:
- wx.Bell()
-
- event.Skip()
-
-
-#
-# Property Editor derived from an attribute's ValueSet
-#
-class LimitedSetEditor(wx.ComboBox):
- def __init__(self, parent, attributes):
- wx.ComboBox.__init__(self, parent, -1,
- style=wx.TE_PROCESS_ENTER|wx.CB_DROPDOWN|wx.CB_READONLY)
- self.attributes = attributes
- self.selectionList = []
-
- try:
- default = self.attributes['Default']
- except KeyError:
- default = None
-
-
- if not (attributes.has_key('Required') and attributes['Required'] ):
- self.selectionList.append(None)
- self.Append('')
-
- # Sort the attribute names...
- keys = attributes['ValueSet'].keys()
- keys.sort()
-
- # .. but make the default always come first
- if default:
- keys.remove(default)
- keys.insert(0, default)
-
- # Add attributes to the combo box
- for v in keys:
- self.selectionList.append(v)
- try:
- text = attributes['ValueSet'][v]['Label']
- except KeyError:
- text = v
- self.Append("%s%s" % (text, v == default and '*' or '' ))
-
- def GetValue(self):
- return self.selectionList[self.GetSelection()]
-
- def SetValue(self, value):
- self.SetSelection(self.selectionList.index(value))
-
-
-#
-# Property Editor whose selections are linked to lists of other objects
-#
-class LinkedTextEditor(wx.ComboBox):
- def __init__(self, parent, attributes, objectList, attr):
- wx.ComboBox.__init__(self, parent, -1,
- style=wx.TE_PROCESS_ENTER|wx.CB_DROPDOWN|wx.CB_SORT)
- self.attributes = attributes
- self.objectList = objectList
- self.attr = attr
- self.updateList()
- objectList.addListener(self.updateList)
-
- def Destroy(self):
- self.objectList.removeListener(self.updateList)
- wx.ComboBox.Destroy(self)
-
- def GetValue(self):
- return wx.ComboBox.GetValue(self) or None
-
- def SetValue(self, value):
- if value in self.list:
- self.SetSelection(self.list.index(value))
- elif value is None:
- wx.ComboBox.SetValue(self, "")
- else:
- wx.ComboBox.SetValue(self, value)
-
- def updateList(self):
- try:
- self.Clear()
- self.list = []
- if not (self.attributes.has_key('Required') and
self.attributes['Required'] ):
- self.list.append(None)
- self.Append('')
- for v in self.objectList:
- self.list.append(v[self.attr])
- self.Append("%s" % v[self.attr])
- except wx.PyDeadObjectError:
- # TODO: why are we getting this exception?
- # TODO: Destroy() is being explicitly called. :(
- pass
-
-#
-# Property editor for boolean types
-#
-class BoolEditor(wx.ComboBox):
- def __init__(self, parent, attributes):
- wx.ComboBox.__init__(self, parent, -1,
- style=wx.TE_PROCESS_ENTER|wx.CB_DROPDOWN|wx.CB_READONLY|wx.CB_SORT)
- self.attributes = attributes
-
- if not (self.attributes.has_key('Required') and
self.attributes['Required'] ):
- self.Append('')
-
- try:
- default = self.attributes['Default']
- except KeyError:
- default = None
-
- self.True = u_('Yes') + (default and '*' or '')
- self.False = u_('No') + (not default and '*' or '')
-
- self.Append(self.True)
- self.Append(self.False)
-
-
- def GetValue(self):
- v = wx.ComboBox.GetValue(self)
- if v == '':
- return None
- else:
- return v == self.True
-
- def SetValue(self, value):
- if value == None:
- wx.ComboBox.SetValue(self,'')
- elif value:
- wx.ComboBox.SetValue(self,self.True)
- else:
- wx.ComboBox.SetValue(self,self.False)
-
-#
-#
-#
-class IntEditor(wx.SpinCtrl):
- def __init__(self, parent, attributes):
- wx.SpinCtrl.__init__(self, parent, -1, style=wx.TE_PROCESS_ENTER)
- self.attributes = attributes
-
-#
-#
-#
-class TextEditor(wx.TextCtrl):
- def __init__(self, parent, attributes):
- wx.TextCtrl.__init__(self, parent, -1, style=wx.TE_PROCESS_ENTER)
- self.attributes = attributes
-
- def SetValue(self, value):
- if value == None:
- value = ""
- wx.TextCtrl.SetValue(self, wxEncode(value))
Modified: trunk/gnue-designer/src/forms/PagePainter/skins/common.py
===================================================================
--- trunk/gnue-designer/src/forms/PagePainter/skins/common.py 2006-04-09
17:18:40 UTC (rev 8396)
+++ trunk/gnue-designer/src/forms/PagePainter/skins/common.py 2006-04-10
17:14:44 UTC (rev 8397)
@@ -150,24 +150,31 @@
"""
self.force_canvas_refresh()
+ gobject = self.gobject
+
delta_char_width = int(round(delta_width / float(char_x_scale)))
delta_char_height = int(round(delta_height / float(char_y_scale)))
if delta_char_width or delta_char_height:
char_width = min(max(delta_char_width +
- self.gobject['Char:width'],
+ gobject['Char:width'],
self.char_min_width),
self.char_max_width)
+ try:
+ char_height = gobject['Char:height']
+ except KeyError:
+ char_height = self.char_default_height
+
char_height = min(max(delta_char_height +
- self.gobject['Char:height'],
+ char_height,
self.char_min_height),
- self.char_max_height)
+ self.char_max_height)
if delta_char_width:
- self.gobject['Char:width'] = char_width
+ gobject['Char:width'] = char_width
if delta_char_height:
- self.gobject['Char:height'] = char_height
+ gobject['Char:height'] = char_height
self.recalc_metrics()
self.force_canvas_refresh()
Modified: trunk/gnue-designer/src/forms/PropertyEditor.py
===================================================================
--- trunk/gnue-designer/src/forms/PropertyEditor.py 2006-04-09 17:18:40 UTC
(rev 8396)
+++ trunk/gnue-designer/src/forms/PropertyEditor.py 2006-04-10 17:14:44 UTC
(rev 8397)
@@ -24,12 +24,15 @@
PropertyEditor wrapper for forms
"""
-import sys, os, string
+import sys
+import os
+import string
+
import wx
+
from gnue.common.apps import GDebug
from gnue.common.formatting import GTypecast
from gnue.designer.base.tools.PropertyEditor import PropertyEditor as
BasePropertyEditor
-from gnue.designer.base.tools.PropertyEditor import InspectorPanel as
BaseInspectorPanel
from gnue.designer.base.ToolBase import *
class PropertyEditor (BasePropertyEditor):
@@ -76,65 +79,65 @@
self.addPage(CharPosInspectorPanel(self, self.notebook), 'Layout')
-#
-# Field properties (when Entry is selected)
-#
-class FieldInspectorPanel(BaseInspectorPanel):
+##
+## Field properties (when Entry is selected)
+##
+#class FieldInspectorPanel(BaseInspectorPanel):
- def setCurrent(self, object):
- self._setCurrent(object._field)
+ #def setCurrent(self, object):
+ #self._setCurrent(object._field)
-#
-# Block properties (when Entry/Field is selected)
-#
-class BlockInspectorPanel(BaseInspectorPanel):
+##
+## Block properties (when Entry/Field is selected)
+##
+#class BlockInspectorPanel(BaseInspectorPanel):
- def setCurrent(self, object):
- self._setCurrent(object.findParentOfType('GFBlock'))
+ #def setCurrent(self, object):
+ #self._setCurrent(object.findParentOfType('GFBlock'))
-class EntryBlockInspectorPanel(BaseInspectorPanel):
- def setCurrent(self, object):
- self._setCurrent(object._block)
+#class EntryBlockInspectorPanel(BaseInspectorPanel):
+ #def setCurrent(self, object):
+ #self._setCurrent(object._block)
-#
-# Datasource properties (when Block is selected)
-#
-class DatasourceInspectorPanel(BaseInspectorPanel):
- def setCurrent(self, object):
- try:
- if hasattr(object,'datasource') and object.datasource:
-
self._setCurrent(self.editor.document.datasources[object.datasource])
- except AttributeError:
- pass # Happens on startup
+##
+## Datasource properties (when Block is selected)
+##
+#class DatasourceInspectorPanel(BaseInspectorPanel):
+ #def setCurrent(self, object):
+ #try:
+ #if hasattr(object,'datasource') and object.datasource:
+
#self._setCurrent(self.editor.document.datasources[object.datasource])
+ #except AttributeError:
+ #pass # Happens on startup
-#
-# Character-cell layout (x,y) properties
-#
-class CharPosInspectorPanel(BaseInspectorPanel):
+##
+## Character-cell layout (x,y) properties
+##
+#class CharPosInspectorPanel(BaseInspectorPanel):
- NAMESPACE = "Char"
+ #NAMESPACE = "Char"
- def getAttributes(self, object):
- return {
- 'Char:x': { 'Typecast': GTypecast.whole },
- 'Char:y': { 'Typecast': GTypecast.whole },
- 'Char:width': { 'Typecast': GTypecast.whole },
- 'Char:height': { 'Typecast': GTypecast.whole } }
+ #def getAttributes(self, object):
+ #return {
+ #'Char:x': { 'Typecast': GTypecast.whole },
+ #'Char:y': { 'Typecast': GTypecast.whole },
+ #'Char:width': { 'Typecast': GTypecast.whole },
+ #'Char:height': { 'Typecast': GTypecast.whole } }
- def getPageText(self):
- return "Display"
+ #def getPageText(self):
+ #return "Display"
-#
-# Character-cell layout (x,y) properties
-#
-class CharSizeInspectorPanel(BaseInspectorPanel):
+##
+## Character-cell layout (x,y) properties
+##
+#class CharSizeInspectorPanel(BaseInspectorPanel):
- NAMESPACE = "Char"
+ #NAMESPACE = "Char"
- def getAttributes(self, object):
- return {
- 'Char:width': { 'Typecast': GTypecast.whole },
- 'Char:height': { 'Typecast': GTypecast.whole } }
+ #def getAttributes(self, object):
+ #return {
+ #'Char:width': { 'Typecast': GTypecast.whole },
+ #'Char:height': { 'Typecast': GTypecast.whole } }
- def getPageText(self):
- return "Display"
+ #def getPageText(self):
+ #return "Display"
Modified: trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/canvas.py
===================================================================
--- trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/canvas.py 2006-04-09
17:18:40 UTC (rev 8396)
+++ trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/canvas.py 2006-04-10
17:14:44 UTC (rev 8397)
@@ -327,7 +327,7 @@
# Draw widgets (in the reverse order they are stored in our list)
for widget in self.ordered_widget_list[::-1]:
-
+
refresh_area = widget.refresh_area
(obj_x, obj_y,
@@ -502,9 +502,9 @@
if not new_action:
selected = self.select_hit_test(x, y)
if selected:
- if event.CmdDown() or event.ShiftDown():
+ if event.CmdDown() or event.ShiftDown():
widgets = self.___merge_selections([selected])
- else:
+ else:
self.selected_from_canvas([selected])
new_action = 'move'
@@ -545,13 +545,13 @@
else:
widget = self.select_hit_test(area.x, area.y)
widgets = widget and [widget] or []
-
- if event.CmdDown() or event.ShiftDown():
- # If ctrl, cmd, or shift were pressed,
+
+ if event.CmdDown() or event.ShiftDown():
+ # If ctrl, cmd, or shift were pressed,
# then the user was adding or removing widgets
- # and not selecting a whole new set.
+ # and not selecting a whole new set.
self.__merge_selections(widgets)
- else:
+ else:
self.selected_from_canvas(widgets)
elif current_action == 'move':
@@ -707,20 +707,20 @@
return results
- def ___merge_selections(self, new_selection):
+ def ___merge_selections(self, new_selection):
"""
Merge a new selection with an old selection, eliminating
any widgets in both. (This is used when Cmd+Click is used
to select a widget.
"""
- # If ctrl, cmd, or shift were pressed,
+ # If ctrl, cmd, or shift were pressed,
# then the user was adding or removing widgets
- # and not selecting a whole new set.
+ # and not selecting a whole new set.
selection = self.get_selected_widgets()
- for widget in new_selection:
- if widget in selection:
+ for widget in new_selection:
+ if widget in selection:
selection.remove(widget)
- else:
+ else:
selection.append(widget)
self.selected_from_canvas(selection)
@@ -744,7 +744,7 @@
self.CaptureMouse()
-
+
# These will visually move, but not necessarily have their x,y changed.
self.__mouse_move_all = all_widgets = []
@@ -754,40 +754,40 @@
# Start out with the selected widgets
selected_widgets = self.get_selected_widgets()
self.__mouse_move_selected = selected_widgets
-
+
unvisited_widgets = selected_widgets[:]
- # And recursively add any siblings or children
+ # And recursively add any siblings or children
# (TODO: it's not recursive yet)
area = wx.Rect()
- while unvisited_widgets:
+ while unvisited_widgets:
widget = unvisited_widgets.pop()
all_widgets.append(widget)
movable_widgets.append(widget)
-
+
# Process child widgets
- for child_widget in widget.get_movable_children():
- if child_widget not in all_widgets:
+ for child_widget in widget.get_movable_children():
+ if child_widget not in all_widgets:
all_widgets.append(child_widget)
-
+
# Process movable widgets
- for child_widget in widget.get_movable_siblings():
- if child_widget not in all_widgets:
+ for child_widget in widget.get_movable_siblings():
+ if child_widget not in all_widgets:
all_widgets.append(child_widget)
movable_widgets.append(child_widget)
-
+
# Unselect any selected ones
for widget in selected_widgets:
widget.selected = False
-
+
# And hide all of them
- for widget in all_widgets:
+ for widget in all_widgets:
widget.visible = False
area = area.Union(widget.refresh_area)
-
-
+
+
# Create a bitmap of our widgets in an offscreen buffer
# so we can redraw them as the mouse moves
@@ -812,18 +812,18 @@
memory_dc.SetDeviceOrigin(obj_x - buff_x, obj_y - buff_y)
widget.draw_widget(memory_dc)
- # If the widget is implicitly being moved because it is a
- # sibling (i.e., labels attached to fields), draw a special
- # border around the sibling.
- if wx.IntersectRect(widget.hit_test_area,
- self.__selection_area) != widget.hit_test_area:
+ # If the widget is implicitly being moved because it is a
+ # sibling (i.e., labels attached to fields), draw a special
+ # border around the sibling.
+ if wx.IntersectRect(widget.hit_test_area,
+ self.__selection_area) != widget.hit_test_area:
widget.draw_sibling_border(memory_dc)
-
+
memory_dc.SetDeviceOrigin(0,0)
# Draw a selection box
sel_x, sel_y, sel_w, sel_h = self.__selection_area.Get()
- self.__draw_selection_box(memory_dc, sel_x - buff_x,
+ self.__draw_selection_box(memory_dc, sel_x - buff_x,
sel_y - buff_y, sel_w, sel_h)
memory_dc.EndDrawing()
@@ -869,11 +869,11 @@
for widget in self.__mouse_move_selected:
widget.selected = True
-
- for widget in self.__mouse_move_all:
+
+ for widget in self.__mouse_move_all:
widget.show()
-
- for widget in self.__mouse_move_items:
+
+ for widget in self.__mouse_move_items:
if x != self.__mouse_move_start_x or \
y != self.__mouse_move_start_y:
widget.move_from_canvas(x - self.__mouse_move_start_x,
@@ -882,7 +882,7 @@
self.__mouse_move_items = None
self.__mouse_move_all = None
self.__mouse_move_selected = None
-
+
self.refresh_selection()
self.refresh_scrolled_area(old_area)
@@ -988,13 +988,13 @@
orientation = self.__mouse_resize_orientation
- delta_width = x - self.__mouse_resize_start_x
- delta_height = y - self.__mouse_resize_start_y
+ delta_width = x - self.__mouse_resize_start_x
+ delta_height = y - self.__mouse_resize_start_y
# Discard width or height if only a side was moved
- if orientation in ('top','bottom'):
+ if orientation in ('top','bottom'):
delta_width = 0
- if orientation in ('left','right'):
+ if orientation in ('left','right'):
delta_height = 0
# Determine if the widget moved while being resized
@@ -1006,9 +1006,9 @@
if orientation in ('top','ul','ur') and delta_height:
delta_y = delta_height
delta_height *= -1
-
-
+
+
# Figure out the resize amount
for widget in self.get_selected_widgets():
if delta_x or delta_y:
@@ -1142,14 +1142,14 @@
"""
Add a DocumentWidget to the canvas
"""
- if widget.container:
+ if widget.container:
self.ordered_widget_bottom.insert(0,widget)
- else:
+ else:
self.ordered_widget_top.insert(0,widget)
-
+
self.ordered_widget_list = self.ordered_widget_top + \
self.ordered_widget_bottom
-
+
self.gobject_map[widget.gobject] = widget
widget.force_canvas_refresh()
@@ -1159,13 +1159,13 @@
Remove a DocumentWidget from the canvas
"""
self.ordered_widget_list.remove(widget)
- try:
+ try:
self.ordered_widget_top.remove(widget)
- except:
+ except:
self.ordered_widget_bottom.remove(widget)
-
+
del self.gobject_map[widget.gobject]
-
+
area = widget.refresh_area
self.refresh_scrolled_area(refresh_area)
widget.Destroy()
Modified: trunk/gnue-forms/samples/intro/intro.gfd
===================================================================
--- trunk/gnue-forms/samples/intro/intro.gfd 2006-04-09 17:18:40 UTC (rev
8396)
+++ trunk/gnue-forms/samples/intro/intro.gfd 2006-04-10 17:14:44 UTC (rev
8397)
@@ -124,20 +124,20 @@
<page name="Sample">
<box name="Box_2" c:height="8" label="Sample" c:width="38" c:x="1"
c:y="0"/>
- <label name="Label_5" text="Your Name:" c:width="11" c:x="3" c:y="2"/>
- <label name="Label_6" text="Year you were born:" c:width="20" c:x="3"
+ <label for="nameField" name="Label_5" text="Your Name:" c:width="11"
c:x="3" c:y="2"/>
+ <label for="yearField" name="Label_6" text="Year you were born:"
c:width="20" c:x="3"
c:y="3"/>
- <label name="Label_7" text="Your Code Name:" c:width="15" c:x="3"
+ <label for="codeField" name="Label_7" text="Your Code Name:"
c:width="15" c:x="3"
c:y="5"/>
- <entry block="SampleBlock" field="NameEntry" c:width="23" c:x="14"
+ <entry name="nameField" block="SampleBlock" field="NameEntry"
c:width="23" c:x="14"
c:y="2"/>
- <entry block="SampleBlock" field="YearEntry" c:width="6" c:x="22"
+ <entry name="yearField" block="SampleBlock" field="YearEntry"
c:width="6" c:x="22"
c:y="3"/>
<button name="btnClear" c:height="1" label="Fortune" c:width="8"
c:x="29" c:y="3">
<trigger src="MyFortune" type="On-Action"/>
</button>
- <entry block="SampleBlock" field="CodeNameEntry" c:width="34" c:x="3"
+ <entry name="codeField" block="SampleBlock" field="CodeNameEntry"
c:width="34" c:x="3"
c:y="6"/>
<entry block="SampleBlock" field="FortuneEntry" c:height="4"
c:width="36" c:x="2" c:y="8"/>
Modified: trunk/gnue-forms/src/GFParser.py
===================================================================
--- trunk/gnue-forms/src/GFParser.py 2006-04-09 17:18:40 UTC (rev 8396)
+++ trunk/gnue-forms/src/GFParser.py 2006-04-10 17:14:44 UTC (rev 8397)
@@ -312,11 +312,12 @@
'Required': True,
'Typecast': GTypecast.text,
'Description': 'The text to be displayed.' },
- 'for': {
+ 'for': {
'Required': False,
+ 'References': 'entry.name',
'Typecast': GTypecast.name,
'Description': 'If this label is for a specific object, '
- 'name it here.' },
+ 'name it here.' },
'alignment': {
'Typecast': GTypecast.name,
'ValueSet': {
@@ -649,7 +650,7 @@
'Description': 'The unique name of the image.' },
'field': {
'Typecast': GTypecast.name,
- 'References': 'field.name',
+ 'References': 'block.name>field.name',
'Required': True,
'Description': 'The name of the field that this ties to.' },
'block': {
@@ -708,7 +709,7 @@
'Description': 'The unique name of the component.' },
'field': {
'Typecast': GTypecast.name,
- 'References': 'field.name',
+ 'References': 'block.name>field.name',
'Required': True,
'Description': 'The name of the field that this ties to.' },
'block': {
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r8397 - in trunk: gnue-designer/src/base gnue-designer/src/base/tools gnue-designer/src/forms gnue-designer/src/forms/PagePainter/skins gnue-designer/src/ui/wx/uihelpers/doccanvas gnue-forms/samples/intro gnue-forms/src,
jcater <=