From 03b8e85293acbebc9e920a321100d186da6ba2a5 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Thu, 29 Jul 2010 12:08:23 -0400 Subject: [PATCH] Added BoolProperty and StringProperty A grep through hooke/plugins/ shows what we need to implement. I've checked the completed properties with '+'. $ grep 'type=' hooke/plugin/*.py | sed -n "s/.* type='\([^']*\)'.*/\1/p" | sort | uniq -c + 8 bool 2 curve 3 dict 1 driver 5 file 7 float 1 function 1 glob + 22 int 3 object 2 path 1 playlist 1 point + 6 string --- hooke/ui/gui/panel/propertyeditor2.py | 218 ++++++++++++-------------- 1 file changed, 103 insertions(+), 115 deletions(-) diff --git a/hooke/ui/gui/panel/propertyeditor2.py b/hooke/ui/gui/panel/propertyeditor2.py index f361a37..90eb32a 100644 --- a/hooke/ui/gui/panel/propertyeditor2.py +++ b/hooke/ui/gui/panel/propertyeditor2.py @@ -36,21 +36,77 @@ class Property (object): self.help = help def get_editor(self): - """Return a wx.Window instance containing a suitable editor. - - Retains a reference to the returned editory as `._editor`. + """Return a suitable grid editor. """ raise NotImplementedError() - def value_string(self, value): + def get_renderer(self): + """Return a suitable grid renderer. + + Returns `None` if no special renderer is required. + """ + return None + + def string_for_value(self, value): """Return a string representation of `value` for loading the table. """ return str(value) - def get_value(self): - """Return the value of `._editor`. + def value_for_string(self, string): + """Return the value represented by `string`. """ - raise NotImplementedError() + return string + + +class StringProperty (Property): + def __init__(self, **kwargs): + assert 'type' not in kwargs, kwargs + if 'default' not in kwargs: + kwargs['default'] = 0 + super(StringProperty, self).__init__(type='string', **kwargs) + + def get_editor(self): + return wx.grid.GridCellTextEditor() + + def get_renderer(self): + return wx.grid.GridCellStringRenderer() + + +class BoolProperty (Property): + """A boolean property. + + Notes + ----- + Unfortunately, changing a boolean property takes two clicks: + + 1) create the editor + 2) change the value + + There are `ways around this`_, but it's not pretty. + + .. _ways around this: + http://wiki.wxpython.org/Change%20wxGrid%20CheckBox%20with%20one%20click + """ + def __init__(self, **kwargs): + assert 'type' not in kwargs, kwargs + if 'default' not in kwargs: + kwargs['default'] = True + super(BoolProperty, self).__init__(type='bool', **kwargs) + + def get_editor(self): + return wx.grid.GridCellBoolEditor() + #return wx.grid.GridCellChoiceEditor(choices=['true', 'false']) + + def get_renderer(self): + return wx.grid.GridCellBoolRenderer() + + def string_for_value(self, value): + if value == True: + return '1' + return '' + + def value_for_string(self, string): + return string == '1' class IntProperty (Property): @@ -61,11 +117,13 @@ class IntProperty (Property): super(IntProperty, self).__init__(type='int', **kwargs) def get_editor(self): - self._editor = wx.grid.GridCellNumberEditor() - return self._editor + return wx.grid.GridCellNumberEditor() - def get_value(self): - raise int(self._editor.GetValue()) + def get_renderer(self): + return wx.grid.GridCellNumberRenderer() + + def value_for_string(self, string): + return int(string) #class PyFilesProperty(wxpg.PyArrayStringProperty): @@ -323,6 +381,17 @@ class PropertyPanel(Panel, wx.grid.Grid): self._last_tooltip = None self.GetGridWindow().Bind(wx.EVT_MOTION, self._on_mouse_over) + # add example properties for testing + self.append_property(StringProperty( + label='my string', + default='hithere', + help='help for my string', + )) + self.append_property(BoolProperty( + label='my bool', + default=True, + help='help for my bool', + )) self.append_property(IntProperty( label='my int', default=5, @@ -352,123 +421,42 @@ class PropertyPanel(Panel, wx.grid.Grid): if msg != self._last_tooltip: self._last_tooltip = msg event.GetEventObject().SetToolTipString(msg) + self._get_values() # for testing def append_property(self, property): - if len([p for p in self._properties if p.label == label]) > 0: + if len([p for p in self._properties if p.label == property.label]) > 0: raise ValueError(property) # property.label collision self._properties.append(property) row = len(self._properties) - 1 self.AppendRows(numRows=1) self.SetRowLabelValue(row, property.label) self.SetCellEditor(row=row, col=0, editor=property.get_editor()) + r = property.get_renderer() + if r != None: + self.SetCellRenderer(row=row, col=0, renderer=r) self.set_property(property.label, property.default) def set_property(self, label, value): + row,property = self._property_by_label(label) + self.SetCellValue(row=row, col=0, s=property.string_for_value(value)) + + def get_property(self, label): + row,property = self._property_by_label(label) + string = self.GetCellValue(row=row, col=0) + return property.value_for_string(string) + + def remove_property(self, label): + row,property = self._property_by_label(label) + raise NotImplementedError() + + def _property_by_label(self, label): props = [(i,p) for i,p in enumerate(self._properties) if p.label == label] assert len(props) == 1, props row,property = props[0] - self.SetCellValue(row=row, col=0, s=property.value_string(value)) + return (row, property) - def remove_property(self, property): - pass - - def GetPropertyValues(self): - raise NotImplementedError() - return self.pg.GetPropertyValues() - - def Initialize(self, properties): - raise NotImplementedError() - pg = self.pg - pg.Clear() - - if properties: - for element in properties: - if element[1]['type'] == 'arraystring': - elements = element[1]['elements'] - if 'value' in element[1]: - property_value = element[1]['value'] - else: - property_value = element[1]['default'] - #retrieve individual strings - property_value = split(property_value, ' ') - #remove " delimiters - values = [value.strip('"') for value in property_value] - pg.Append(wxpg.ArrayStringProperty(element[0], value=values)) - - if element[1]['type'] == 'boolean': - if 'value' in element[1]: - property_value = element[1].as_bool('value') - else: - property_value = element[1].as_bool('default') - property_control = wxpg.BoolProperty(element[0], value=property_value) - pg.Append(property_control) - pg.SetPropertyAttribute(element[0], 'UseCheckbox', True) - - #if element[0] == 'category': - #pg.Append(wxpg.PropertyCategory(element[1])) - - if element[1]['type'] == 'color': - if 'value' in element[1]: - property_value = element[1]['value'] - else: - property_value = element[1]['default'] - property_value = eval(property_value) - pg.Append(wxpg.ColourProperty(element[0], value=property_value)) - - if element[1]['type'] == 'enum': - elements = element[1]['elements'] - if 'value' in element[1]: - property_value = element[1]['value'] - else: - property_value = element[1]['default'] - pg.Append(wxpg.EnumProperty(element[0], element[0], elements, [], elements.index(property_value))) - - if element[1]['type'] == 'filename': - if 'value' in element[1]: - property_value = element[1]['value'] - else: - property_value = element[1]['default'] - pg.Append(wxpg.FileProperty(element[0], value=property_value)) - - if element[1]['type'] == 'float': - if 'value' in element[1]: - property_value = element[1].as_float('value') - else: - property_value = element[1].as_float('default') - property_control = wxpg.FloatProperty(element[0], value=property_value) - pg.Append(property_control) - - if element[1]['type'] == 'folder': - if 'value' in element[1]: - property_value = element[1]['value'] - else: - property_value = element[1]['default'] - pg.Append(wxpg.DirProperty(element[0], value=property_value)) - - if element[1]['type'] == 'integer': - if 'value' in element[1]: - property_value = element[1].as_int('value') - else: - property_value = element[1].as_int('default') - property_control = wxpg.IntProperty(element[0], value=property_value) - if 'maximum' in element[1]: - property_control.SetAttribute('Max', element[1].as_int('maximum')) - if 'minimum' in element[1]: - property_control.SetAttribute('Min', element[1].as_int('minimum')) - property_control.SetAttribute('Wrap', True) - pg.Append(property_control) - pg.SetPropertyEditor(element[0], 'SpinCtrl') - - if element[1]['type'] == 'string': - if 'value' in element[1]: - property_value = element[1]['value'] - else: - property_value = element[1]['default'] - pg.Append(wxpg.StringProperty(element[0], value=property_value)) - - pg.Refresh() - - def OnReserved(self, event): - raise NotImplementedError() - pass + def _get_values(self): # for testing + for property in self._properties: + v = self.get_property(property.label) + print property.label, property.type, type(v), v -- 2.26.2