def __init__(self,parent,attribute): super(_list_wx_widget,self).__init__(parent,-1) self.attribute = attribute self.SetExtraStyle(wx.WS_EX_VALIDATE_RECURSIVELY) sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) self.newbutton = wx.Button(self,self.__class__.ID_APPENDBUTTON,label="Append") sizer.Add(self.newbutton) wx.EVT_BUTTON(self,self.__class__.ID_APPENDBUTTON,self.onAppend) self.notifyclosure = NotifyClosure(self,self.node_changed) self.notifyclosure.register(self.attribute) i = 0 for element in attribute: sizer.Add(_listitem_wx_widget(self,element,i)) i += 1
def buildUi(self): self.sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(self.sizer) self.title = wx.StaticText(self,ID_LABEL) self.title.SetLabel(repr(self.obj) +" - \"" +str(self.obj)+"\"") self.sizer.Add(self.title,0) #Walk down the inheritance hierachy Finding each object. current = self.obj done = [] while current is not None: print repr(current) panel, included = self._buildObjectPanel(current,done,self.obj) self.sizer.Add(panel,0,wx.EXPAND) done += included #Hide empty panel - but leave them to simply our sync algorithm if not included: panel.Show(False) current = current.get_parent() self.notify = NotifyClosure(self,self.node_changed) self.notify.register(self.obj)
class ObjectPanel(wx.PyPanel): def __init__(self,parent,obj): super(ObjectPanel,self).__init__(parent,-1,wx.DefaultPosition,wx.Size(0,0)) self.obj = obj self.buildUi() self.SetExtraStyle(wx.WS_EX_VALIDATE_RECURSIVELY) self.TransferDataToWindow() self.Layout() self.SetAutoLayout(True) def getPanelName(self): return repr(self.obj) def buildUi(self): self.sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(self.sizer) self.title = wx.StaticText(self,ID_LABEL) self.title.SetLabel(repr(self.obj) +" - \"" +str(self.obj)+"\"") self.sizer.Add(self.title,0) #Walk down the inheritance hierachy Finding each object. current = self.obj done = [] while current is not None: print repr(current) panel, included = self._buildObjectPanel(current,done,self.obj) self.sizer.Add(panel,0,wx.EXPAND) done += included #Hide empty panel - but leave them to simply our sync algorithm if not included: panel.Show(False) current = current.get_parent() self.notify = NotifyClosure(self,self.node_changed) self.notify.register(self.obj) def node_changed(self,node): self.TransferDataToWindow() def _syncUi(self): current = self.obj done = [] for base_panel in self.GetChildren(): if not isinstance(base_panel,_object_section): continue panel_obj = base_panel.get_object() if current is not panel_obj: #What exaclty ? Hmm. #This mean we're out of touch with the parent seq. #And we need to rewrite the sequence from here down. raise RuntimeError("NYI: Parent heirachy change detected") else: done_in_current = [ ] for attrib_panel in base_panel.GetChildren(): if not isinstance(attrib_panel,_attribute_section): continue attribute = attrib_panel.attribute #If the attribute has been removed or overridden remove the panel. if (attribute.name not in current) or (attribute.name in done): base_panel.remove(attrib_panel) else: done_in_current += [ attribute.name ] #Add panels for new attributes.. done += done_in_current for attrib_obj in current: if attrib_obj.name in done: continue base_panel.add(_attribute_section(base_panel,-1,attrib_obj,self.obj)) current = current.get_parent() def TransferDataToWindow(self): #TODO: Walk thru attributes and hide/show overridden and new sections self._syncUi() super(ObjectPanel,self).TransferDataToWindow() self.Layout() def _buildObjectPanel(self,obj,overridden_list,top_object): section = _object_section(self,obj,overridden_list,top_object) return section, section.get_included()
class _list_wx_widget(wx.PyPanel): ID_APPENDBUTTON = NewUI_ID() def __init__(self,parent,attribute): super(_list_wx_widget,self).__init__(parent,-1) self.attribute = attribute self.SetExtraStyle(wx.WS_EX_VALIDATE_RECURSIVELY) sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) self.newbutton = wx.Button(self,self.__class__.ID_APPENDBUTTON,label="Append") sizer.Add(self.newbutton) wx.EVT_BUTTON(self,self.__class__.ID_APPENDBUTTON,self.onAppend) self.notifyclosure = NotifyClosure(self,self.node_changed) self.notifyclosure.register(self.attribute) i = 0 for element in attribute: sizer.Add(_listitem_wx_widget(self,element,i)) i += 1 def node_changed(self,obj): i =0 sizer = self.GetSizer() #Use list comprehension to copy elements into a list # - ignore the first (append button) element of the list display objects display_items = [ x.GetWindow() for x in sizer.GetChildren()][1:] index_elements = [x for x in self.attribute] element = _pop(index_elements) child = _pop(display_items) while (element is not None) or (child is not None): cname = child and child.get_stableindex() #Can't use the boolean eval trick to protect elements # against None, because they may test as false for their own # reasonns . Or may have no boolean conversion nname = element if element is not None: nname = nname.name if nname == cname: #Node in place in tree already, move on to next # but we may need to update it's index positions. child.set_index(i) element = _pop(index_elements) child = _pop(display_items) i += 1 elif _compare_names_lt(nname,cname): #Insert item newpanel=_listitem_wx_widget(self,element,i) sizer.Insert(i+1,newpanel) newpanel.TransferDataToWindow() i+=1 element = _pop(index_elements) else: # Remove item. child.Destroy() child = _pop(display_items) self.GetTopLevelParent().Layout() def onAppend(self,evt): from dialogs.newattribute import NewAttributeDialog dlg = NewAttributeDialog(self,-1,owner = self.attribute ,title ="Enter initial value", write = "append") dlg.Show()