mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2025-07-21 04:31:09 +02:00
Replaced a TreeListCtrl to wx.gizmos, and updated and uncommented the associated code (also changed AppendColumn to AddColumn). Note, this code does not work as is with wx.dataview.TreeListCtrl.
270 lines
9.6 KiB
Python
270 lines
9.6 KiB
Python
#!/usr/bin/env python
|
|
|
|
import wx
|
|
import wx.gizmos as gizmos
|
|
import wx.lib.agw.customtreectrl
|
|
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 are black
|
|
if len(indices) % 2 == 0:
|
|
return wx.RED
|
|
elif len(indices) % 3 == 0:
|
|
return wx.BLUE
|
|
else:
|
|
return wx.BLACK
|
|
|
|
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, 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.agw.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.agw.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:])
|
|
|