git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@45793 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			266 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			266 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import wx, wx.lib.customtreectrl, wx.gizmos
 | |
| try:
 | |
|     import treemixin 
 | |
| except ImportError:
 | |
|     from wx.lib.mixins import treemixin
 | |
| 
 | |
| overview = treemixin.__doc__
 | |
| 
 | |
| class TreeModel(object):
 | |
|     ''' TreeModel holds the domain objects that are shown in the different
 | |
|     tree controls. Each domain object is simply a two-tuple consisting of
 | |
|     a label and a list of child tuples, i.e. (label, [list of child tuples]). 
 | |
|     '''
 | |
|     def __init__(self, *args, **kwargs):
 | |
|         self.items = []
 | |
|         self.itemCounter = 0
 | |
|         super(TreeModel, self).__init__(*args, **kwargs)
 | |
| 
 | |
|     def GetItem(self, indices):
 | |
|         text, children = 'Hidden root', self.items
 | |
|         for index in indices:
 | |
|             text, children = children[index]
 | |
|         return text, children
 | |
| 
 | |
|     def GetText(self, indices):
 | |
|         return self.GetItem(indices)[0]
 | |
| 
 | |
|     def GetChildren(self, indices):
 | |
|         return self.GetItem(indices)[1]
 | |
| 
 | |
|     def GetChildrenCount(self, indices):
 | |
|         return len(self.GetChildren(indices))
 | |
| 
 | |
|     def SetChildrenCount(self, indices, count):
 | |
|         children = self.GetChildren(indices)
 | |
|         while len(children) > count:
 | |
|             children.pop()
 | |
|         while len(children) < count:
 | |
|             children.append(('item %d'%self.itemCounter, []))
 | |
|             self.itemCounter += 1
 | |
| 
 | |
|     def MoveItem(self, itemToMoveIndex, newParentIndex):
 | |
|         itemToMove = self.GetItem(itemToMoveIndex)
 | |
|         newParentChildren = self.GetChildren(newParentIndex)
 | |
|         newParentChildren.append(itemToMove)
 | |
|         oldParentChildren = self.GetChildren(itemToMoveIndex[:-1])
 | |
|         oldParentChildren.remove(itemToMove)
 | |
| 
 | |
| 
 | |
| class DemoTreeMixin(treemixin.VirtualTree, treemixin.DragAndDrop, 
 | |
|                     treemixin.ExpansionState):
 | |
|     def __init__(self, *args, **kwargs):
 | |
|         self.model = kwargs.pop('treemodel')
 | |
|         self.log = kwargs.pop('log')
 | |
|         super(DemoTreeMixin, self).__init__(*args, **kwargs)
 | |
|         self.CreateImageList()
 | |
| 
 | |
|     def CreateImageList(self):
 | |
|         size = (16, 16)
 | |
|         self.imageList = wx.ImageList(*size)
 | |
|         for art in wx.ART_FOLDER, wx.ART_FILE_OPEN, wx.ART_NORMAL_FILE:
 | |
|             self.imageList.Add(wx.ArtProvider.GetBitmap(art, wx.ART_OTHER, 
 | |
|                                                         size))
 | |
|         self.AssignImageList(self.imageList)
 | |
| 
 | |
|     def OnGetItemText(self, indices):
 | |
|         return self.model.GetText(indices)
 | |
| 
 | |
|     def OnGetChildrenCount(self, indices):
 | |
|         return self.model.GetChildrenCount(indices)
 | |
| 
 | |
|     def OnGetItemFont(self, indices):
 | |
|         # Show how to change the item font. Here we use a small font for
 | |
|         # items that have children and the default font otherwise.
 | |
|         if self.model.GetChildrenCount(indices) > 0:
 | |
|             return wx.SMALL_FONT
 | |
|         else:
 | |
|             return super(DemoTreeMixin, self).OnGetItemFont(indices)
 | |
| 
 | |
|     def OnGetItemTextColour(self, indices):
 | |
|         # Show how to change the item text colour. In this case second level
 | |
|         # items are coloured red and third level items are blue. All other
 | |
|         # items have the default text colour.
 | |
|         if len(indices) % 2 == 0:
 | |
|             return wx.RED
 | |
|         elif len(indices) % 3 == 0:
 | |
|             return wx.BLUE
 | |
|         else:
 | |
|             return super(DemoTreeMixin, self).OnGetItemTextColour(indices)
 | |
| 
 | |
|     def OnGetItemBackgroundColour(self, indices):
 | |
|         # Show how to change the item background colour. In this case the
 | |
|         # background colour of each third item is green.
 | |
|         if indices[-1] == 2:
 | |
|             return wx.GREEN
 | |
|         else: 
 | |
|             return super(DemoTreeMixin, 
 | |
|                          self).OnGetItemBackgroundColour(indices)
 | |
| 
 | |
|     def OnGetItemImage(self, indices, which):
 | |
|         # Return the right icon depending on whether the item has children.
 | |
|         if which in [wx.TreeItemIcon_Normal, wx.TreeItemIcon_Selected]:
 | |
|             if self.model.GetChildrenCount(indices):
 | |
|                 return 0
 | |
|             else:
 | |
|                 return 2
 | |
|         else:
 | |
|             return 1
 | |
| 
 | |
|     def OnDrop(self, dropTarget, dragItem):
 | |
|         dropIndex = self.GetIndexOfItem(dropTarget)
 | |
|         dropText = self.model.GetText(dropIndex)
 | |
|         dragIndex = self.GetIndexOfItem(dragItem)
 | |
|         dragText = self.model.GetText(dragIndex)
 | |
|         self.log.write('drop %s %s on %s %s'%(dragText, dragIndex,
 | |
|             dropText, dropIndex))
 | |
|         self.model.MoveItem(dragIndex, dropIndex)
 | |
|         self.GetParent().RefreshItems()
 | |
| 
 | |
| 
 | |
| class VirtualTreeCtrl(DemoTreeMixin, wx.TreeCtrl):
 | |
|     pass
 | |
| 
 | |
| 
 | |
| class VirtualTreeListCtrl(DemoTreeMixin, wx.gizmos.TreeListCtrl):
 | |
|     def __init__(self, *args, **kwargs):
 | |
|         kwargs['style'] = wx.TR_DEFAULT_STYLE | wx.TR_FULL_ROW_HIGHLIGHT
 | |
|         super(VirtualTreeListCtrl, self).__init__(*args, **kwargs)
 | |
|         self.AddColumn('Column 0')
 | |
|         self.AddColumn('Column 1')
 | |
|         for art in wx.ART_TIP, wx.ART_WARNING:
 | |
|             self.imageList.Add(wx.ArtProvider.GetBitmap(art, wx.ART_OTHER, 
 | |
|                                                         (16, 16)))
 | |
| 
 | |
|     def OnGetItemText(self, indices, column=0):
 | |
|         # Return a different label depending on column.
 | |
|         return '%s, column %d'%\
 | |
|             (super(VirtualTreeListCtrl, self).OnGetItemText(indices), column)
 | |
| 
 | |
|     def OnGetItemImage(self, indices, which, column=0):
 | |
|         # Also change the image of the other columns when the item has 
 | |
|         # children.
 | |
|         if column == 0:
 | |
|             return super(VirtualTreeListCtrl, self).OnGetItemImage(indices, 
 | |
|                                                                    which)
 | |
|         elif self.OnGetChildrenCount(indices):
 | |
|             return 4
 | |
|         else:
 | |
|             return 3
 | |
| 
 | |
| 
 | |
| class VirtualCustomTreeCtrl(DemoTreeMixin, 
 | |
|                             wx.lib.customtreectrl.CustomTreeCtrl):
 | |
|     def __init__(self, *args, **kwargs):
 | |
|         self.checked = {}
 | |
|         kwargs['style'] = wx.TR_HIDE_ROOT | \
 | |
|             wx.TR_HAS_BUTTONS | wx.TR_FULL_ROW_HIGHLIGHT
 | |
|         super(VirtualCustomTreeCtrl, self).__init__(*args, **kwargs)
 | |
|         self.Bind(wx.lib.customtreectrl.EVT_TREE_ITEM_CHECKED,
 | |
|                   self.OnItemChecked)
 | |
| 
 | |
|     def OnGetItemType(self, indices):
 | |
|         if len(indices) == 1:
 | |
|             return 1
 | |
|         elif len(indices) == 2:
 | |
|             return 2
 | |
|         else:
 | |
|             return 0
 | |
| 
 | |
|     def OnGetItemChecked(self, indices):
 | |
|         return self.checked.get(indices, False)
 | |
| 
 | |
|     def OnItemChecked(self, event):
 | |
|         item = event.GetItem()
 | |
|         itemIndex = self.GetIndexOfItem(item)
 | |
|         if self.GetItemType(item) == 2: 
 | |
|             # It's a radio item; reset other items on the same level
 | |
|             for nr in range(self.GetChildrenCount(self.GetItemParent(item))):
 | |
|                 self.checked[itemIndex[:-1]+(nr,)] = False
 | |
|         self.checked[itemIndex] = True
 | |
| 
 | |
| 
 | |
| 
 | |
| class TreeNotebook(wx.Notebook):
 | |
|     def __init__(self, *args, **kwargs):
 | |
|         treemodel = kwargs.pop('treemodel')
 | |
|         log = kwargs.pop('log')
 | |
|         super(TreeNotebook, self).__init__(*args, **kwargs)
 | |
|         self.trees = []
 | |
|         for class_, title in [(VirtualTreeCtrl, 'TreeCtrl'),
 | |
|                               (VirtualTreeListCtrl, 'TreeListCtrl'),
 | |
|                               (VirtualCustomTreeCtrl, 'CustomTreeCtrl')]:
 | |
|             tree = class_(self, treemodel=treemodel, log=log)
 | |
|             self.trees.append(tree)
 | |
|             self.AddPage(tree, title)
 | |
|         self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
 | |
| 
 | |
|     def OnPageChanged(self, event):
 | |
|         oldTree = self.GetPage(event.OldSelection)
 | |
|         newTree = self.GetPage(event.Selection)
 | |
|         newTree.RefreshItems()
 | |
|         newTree.SetExpansionState(oldTree.GetExpansionState())
 | |
|         event.Skip()
 | |
| 
 | |
|     def GetIndicesOfSelectedItems(self):
 | |
|         tree = self.trees[self.GetSelection()]
 | |
|         if tree.GetSelections():
 | |
|             return [tree.GetIndexOfItem(item) for item in tree.GetSelections()]
 | |
|         else:
 | |
|             return [()]
 | |
| 
 | |
|     def RefreshItems(self):
 | |
|         tree = self.trees[self.GetSelection()]
 | |
|         tree.RefreshItems()
 | |
|         tree.UnselectAll()
 | |
| 
 | |
| 
 | |
| class TestPanel(wx.Panel):
 | |
|     def __init__(self, parent, log):
 | |
|         self.log = log
 | |
|         super(TestPanel, self).__init__(parent)
 | |
|         self.treemodel = TreeModel()
 | |
|         self.CreateControls()
 | |
|         self.LayoutControls()
 | |
| 
 | |
|     def CreateControls(self):
 | |
|         self.notebook = TreeNotebook(self, treemodel=self.treemodel, 
 | |
|                                      log=self.log)
 | |
|         self.label = wx.StaticText(self, label='Number of children: ')
 | |
|         self.childrenCountCtrl = wx.SpinCtrl(self, value='0', max=10000)
 | |
|         self.button = wx.Button(self, label='Update children')
 | |
|         self.button.Bind(wx.EVT_BUTTON, self.OnEnter)
 | |
| 
 | |
|     def LayoutControls(self):
 | |
|         hSizer = wx.BoxSizer(wx.HORIZONTAL)
 | |
|         options = dict(flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL, border=2)
 | |
|         hSizer.Add(self.label, **options)
 | |
|         hSizer.Add(self.childrenCountCtrl, 2, **options)
 | |
|         hSizer.Add(self.button, **options)
 | |
|         sizer = wx.BoxSizer(wx.VERTICAL)
 | |
|         sizer.Add(self.notebook, 1, wx.EXPAND)
 | |
|         sizer.Add(hSizer, 0, wx.EXPAND)
 | |
|         self.SetSizer(sizer)
 | |
| 
 | |
|     def OnEnter(self, event):
 | |
|         indicesList = self.notebook.GetIndicesOfSelectedItems()
 | |
|         newChildrenCount = self.childrenCountCtrl.GetValue()
 | |
|         for indices in indicesList:
 | |
|             text = self.treemodel.GetText(indices)
 | |
|             oldChildrenCount = self.treemodel.GetChildrenCount(indices)
 | |
|             self.log.write('%s %s now has %d children (was %d)'%(text, indices,
 | |
|                 newChildrenCount, oldChildrenCount))
 | |
|             self.treemodel.SetChildrenCount(indices, newChildrenCount)
 | |
|         self.notebook.RefreshItems()
 | |
| 
 | |
| 
 | |
| def runTest(frame, nb, log):
 | |
|     win = TestPanel(nb, log)
 | |
|     return win
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     import sys, os, run
 | |
|     run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
 | |
| 
 |