1 import wx
, wx
.lib
.customtreectrl
, wx
.gizmos
 
   5 class TreeModel(object): 
   6     ''' TreeModel holds the domain objects that are shown in the different 
   7     tree controls. Each domain object is simply a two-tuple consisting of 
   8     a label and a list of child tuples, i.e. (label, [list of child tuples]).  
  10     def __init__(self
, *args
, **kwargs
): 
  13         super(TreeModel
, self
).__init
__(*args
, **kwargs
) 
  15     def GetItem(self
, indices
): 
  16         text
, children 
= 'Hidden root', self
.items
 
  18             text
, children 
= children
[index
] 
  21     def GetText(self
, indices
): 
  22         return self
.GetItem(indices
)[0] 
  24     def GetChildren(self
, indices
): 
  25         return self
.GetItem(indices
)[1] 
  27     def GetChildrenCount(self
, indices
): 
  28         return len(self
.GetChildren(indices
)) 
  30     def SetChildrenCount(self
, indices
, count
): 
  31         children 
= self
.GetChildren(indices
) 
  32         while len(children
) > count
: 
  34         while len(children
) < count
: 
  35             children
.append(('item %d'%self
.itemCounter
, [])) 
  38     def MoveItem(self
, itemToMoveIndex
, newParentIndex
): 
  39         itemToMove 
= self
.GetItem(itemToMoveIndex
) 
  40         newParentChildren 
= self
.GetChildren(newParentIndex
) 
  41         newParentChildren
.append(itemToMove
) 
  42         oldParentChildren 
= self
.GetChildren(itemToMoveIndex
[:-1]) 
  43         oldParentChildren
.remove(itemToMove
) 
  46 class DemoTreeMixin(treemixin
.VirtualTree
, treemixin
.DragAndDrop
,  
  47                     treemixin
.ExpansionState
): 
  48     def __init__(self
, *args
, **kwargs
): 
  49         self
.model 
= kwargs
.pop('treemodel') 
  50         self
.log 
= kwargs
.pop('log') 
  51         super(DemoTreeMixin
, self
).__init
__(*args
, **kwargs
) 
  52         self
.CreateImageList() 
  54     def CreateImageList(self
): 
  56         self
.imageList 
= wx
.ImageList(*size
) 
  57         for art 
in wx
.ART_FOLDER
, wx
.ART_FILE_OPEN
, wx
.ART_NORMAL_FILE
: 
  58             self
.imageList
.Add(wx
.ArtProvider
.GetBitmap(art
, wx
.ART_OTHER
,  
  60         self
.AssignImageList(self
.imageList
) 
  62     def OnGetItemText(self
, indices
): 
  63         return self
.model
.GetText(indices
) 
  65     def OnGetChildrenCount(self
, indices
): 
  66         return self
.model
.GetChildrenCount(indices
) 
  68     def OnGetItemFont(self
, indices
): 
  69         # Show how to change the item font. Here we use a small font for 
  70         # items that have children and the default font otherwise. 
  71         if self
.model
.GetChildrenCount(indices
) > 0: 
  74             return super(DemoTreeMixin
, self
).OnGetItemFont(indices
) 
  76     def OnGetItemTextColour(self
, indices
): 
  77         # Show how to change the item text colour. In this case second level 
  78         # items are coloured red and third level items are blue. All other 
  79         # items have the default text colour. 
  80         if len(indices
) % 2 == 0: 
  82         elif len(indices
) % 3 == 0: 
  85             return super(DemoTreeMixin
, self
).OnGetItemTextColour(indices
) 
  87     def OnGetItemBackgroundColour(self
, indices
): 
  88         # Show how to change the item background colour. In this case the 
  89         # background colour of each third item is green. 
  93             return super(DemoTreeMixin
,  
  94                          self
).OnGetItemBackgroundColour(indices
) 
  96     def OnGetItemImage(self
, indices
, which
): 
  97         # Return the right icon depending on whether the item has children. 
  98         if which 
in [wx
.TreeItemIcon_Normal
, wx
.TreeItemIcon_Selected
]: 
  99             if self
.model
.GetChildrenCount(indices
): 
 106     def OnDrop(self
, dropTarget
, dragItem
): 
 107         dropIndex 
= self
.GetIndexOfItem(dropTarget
) 
 108         dropText 
= self
.model
.GetText(dropIndex
) 
 109         dragIndex 
= self
.GetIndexOfItem(dragItem
) 
 110         dragText 
= self
.model
.GetText(dragIndex
) 
 111         self
.log
.write('drop %s %s on %s %s'%(dragText
, dragIndex
, 
 112             dropText
, dropIndex
)) 
 113         self
.model
.MoveItem(dragIndex
, dropIndex
) 
 114         self
.GetParent().RefreshItems() 
 117 class VirtualTreeCtrl(DemoTreeMixin
, wx
.TreeCtrl
): 
 121 class VirtualTreeListCtrl(DemoTreeMixin
, wx
.gizmos
.TreeListCtrl
): 
 122     def __init__(self
, *args
, **kwargs
): 
 123         kwargs
['style'] = wx
.TR_DEFAULT_STYLE | wx
.TR_FULL_ROW_HIGHLIGHT
 
 124         super(VirtualTreeListCtrl
, self
).__init
__(*args
, **kwargs
) 
 125         self
.AddColumn('Column 0') 
 126         self
.AddColumn('Column 1') 
 127         for art 
in wx
.ART_TIP
, wx
.ART_WARNING
: 
 128             self
.imageList
.Add(wx
.ArtProvider
.GetBitmap(art
, wx
.ART_OTHER
,  
 131     def OnGetItemText(self
, indices
, column
=0): 
 132         # Return a different label depending on column. 
 133         return '%s, column %d'%\
 
 134             (super(VirtualTreeListCtrl
, self
).OnGetItemText(indices
), column
) 
 136     def OnGetItemImage(self
, indices
, which
, column
=0): 
 137         # Also change the image of the other columns when the item has  
 140             return super(VirtualTreeListCtrl
, self
).OnGetItemImage(indices
,  
 142         elif self
.OnGetChildrenCount(indices
): 
 148 class VirtualCustomTreeCtrl(DemoTreeMixin
,  
 149                             wx
.lib
.customtreectrl
.CustomTreeCtrl
): 
 150     def __init__(self
, *args
, **kwargs
): 
 152         kwargs
['style'] = wx
.TR_HIDE_ROOT | \
 
 153             wx
.TR_HAS_BUTTONS | wx
.TR_FULL_ROW_HIGHLIGHT
 
 154         super(VirtualCustomTreeCtrl
, self
).__init
__(*args
, **kwargs
) 
 155         self
.Bind(wx
.lib
.customtreectrl
.EVT_TREE_ITEM_CHECKED
, 
 158     def OnGetItemType(self
, indices
): 
 159         if len(indices
) == 1: 
 161         elif len(indices
) == 2: 
 166     def OnGetItemChecked(self
, indices
): 
 167         return self
.checked
.get(indices
, False) 
 169     def OnItemChecked(self
, event
): 
 170         item 
= event
.GetItem() 
 171         itemIndex 
= self
.GetIndexOfItem(item
) 
 172         if self
.GetItemType(item
) == 2:  
 173             # It's a radio item; reset other items on the same level 
 174             for nr 
in range(self
.GetChildrenCount(self
.GetItemParent(item
))): 
 175                 self
.checked
[itemIndex
[:-1]+(nr
,)] = False 
 176         self
.checked
[itemIndex
] = True 
 180 class TreeNotebook(wx
.Notebook
): 
 181     def __init__(self
, *args
, **kwargs
): 
 182         treemodel 
= kwargs
.pop('treemodel') 
 183         log 
= kwargs
.pop('log') 
 184         super(TreeNotebook
, self
).__init
__(*args
, **kwargs
) 
 186         for class_
, title 
in [(VirtualTreeCtrl
, 'TreeCtrl'), 
 187                               (VirtualTreeListCtrl
, 'TreeListCtrl'), 
 188                               (VirtualCustomTreeCtrl
, 'CustomTreeCtrl')]: 
 189             tree 
= class_(self
, treemodel
=treemodel
, log
=log
) 
 190             self
.trees
.append(tree
) 
 191             self
.AddPage(tree
, title
) 
 192         self
.Bind(wx
.EVT_NOTEBOOK_PAGE_CHANGED
, self
.OnPageChanged
) 
 194     def OnPageChanged(self
, event
): 
 195         oldTree 
= self
.GetPage(event
.OldSelection
) 
 196         newTree 
= self
.GetPage(event
.Selection
) 
 197         newTree
.RefreshItems() 
 198         newTree
.SetExpansionState(oldTree
.GetExpansionState()) 
 201     def GetIndicesOfSelectedItems(self
): 
 202         tree 
= self
.trees
[self
.GetSelection()] 
 203         if tree
.GetSelections(): 
 204             return [tree
.GetIndexOfItem(item
) for item 
in tree
.GetSelections()] 
 208     def RefreshItems(self
): 
 209         tree 
= self
.trees
[self
.GetSelection()] 
 214 class TestPanel(wx
.Panel
): 
 215     def __init__(self
, parent
, log
): 
 217         super(TestPanel
, self
).__init
__(parent
) 
 218         self
.treemodel 
= TreeModel() 
 219         self
.CreateControls() 
 220         self
.LayoutControls() 
 222     def CreateControls(self
): 
 223         self
.notebook 
= TreeNotebook(self
, treemodel
=self
.treemodel
,  
 225         self
.label 
= wx
.StaticText(self
, label
='Number of children: ') 
 226         self
.childrenCountCtrl 
= wx
.SpinCtrl(self
, value
='0', max=10000) 
 227         self
.button 
= wx
.Button(self
, label
='Update children') 
 228         self
.button
.Bind(wx
.EVT_BUTTON
, self
.OnEnter
) 
 230     def LayoutControls(self
): 
 231         hSizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 232         options 
= dict(flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALL
, border
=2) 
 233         hSizer
.Add(self
.label
, **options
) 
 234         hSizer
.Add(self
.childrenCountCtrl
, 2, **options
) 
 235         hSizer
.Add(self
.button
, **options
) 
 236         sizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 237         sizer
.Add(self
.notebook
, 1, wx
.EXPAND
) 
 238         sizer
.Add(hSizer
, 0, wx
.EXPAND
) 
 241     def OnEnter(self
, event
): 
 242         indicesList 
= self
.notebook
.GetIndicesOfSelectedItems() 
 243         newChildrenCount 
= self
.childrenCountCtrl
.GetValue() 
 244         for indices 
in indicesList
: 
 245             text 
= self
.treemodel
.GetText(indices
) 
 246             oldChildrenCount 
= self
.treemodel
.GetChildrenCount(indices
) 
 247             self
.log
.write('%s %s now has %d children (was %d)'%(text
, indices
, 
 248                 newChildrenCount
, oldChildrenCount
)) 
 249             self
.treemodel
.SetChildrenCount(indices
, newChildrenCount
) 
 250         self
.notebook
.RefreshItems() 
 253 def runTest(frame
, nb
, log
): 
 254     win 
= TestPanel(nb
, log
) 
 258 if __name__ 
== '__main__': 
 260     run
.main(['', os
.path
.basename(sys
.argv
[0])] + sys
.argv
[1:])