updated wxMVCTree, VTK, and the demo

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4629 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
1999-11-19 05:34:40 +00:00
parent 5008c64c32
commit e395c057a3
6 changed files with 386 additions and 238 deletions

View File

@@ -45,6 +45,15 @@ Or you can send mail directly to the list using this address:
----------------------------------------------------------------------
What's new in 2.1.12
--------------------
Updated wxMVCTree and added a demo for it.
Added a wrapper class for the Visualization ToolKit (or VTK) in the
wxPython.lib.vtk module. (http://www.kitware.com/)
What's new in 2.1.11
--------------------

View File

@@ -21,6 +21,8 @@ _useSplitter = true
_useNestedSplitter = true
_treeList = [
('New since last release', ['wxMVCTree', 'wxVTKRenderWindow']),
('Managed Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame']),
('Non-Managed Windows', ['wxGrid', 'wxSashWindow',
@@ -47,7 +49,7 @@ _treeList = [
('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
'PyShell', 'wxCalendar']),
'PyShell', 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow']),
('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),

View File

@@ -0,0 +1,61 @@
import sys, os
from wxPython.wx import *
from wxPython.lib.mvctree import *
logger = None
def selchanging(evt):
logger.write("SelChanging!\n")
def selchanged(evt):
logger.write("SelChange!\n")
logger.write(str(evt.node))
def expanded(evt):
logger.write("Expanded\n")
def closed(evt):
logger.write("Closed!\n")
def key(evt):
logger.write("Key\n")
def add(evt):
logger.write("Add\n")
def delitem(evt):
logger.write("Delete\n")
def runTest(frame, nb, log):
#f = wxFrame(frame, -1, "wxMVCTree", wxPoint(0,0), wxSize(200,500))
global logger
logger = log
p = wxMVCTree(nb, -1)
p.SetAssumeChildren(true)
p.SetModel(LateFSTreeModel(os.path.normpath(os.getcwd() + os.sep +'..')))
#Uncomment this to enable live filename editing!
# p.AddEditor(FileEditor(p))
p.SetMultiSelect(true)
EVT_MVCTREE_SEL_CHANGING(p, p.GetId(), selchanging)
EVT_MVCTREE_SEL_CHANGED(p, p.GetId(), selchanged)
EVT_MVCTREE_ITEM_EXPANDED(p, p.GetId(), expanded)
EVT_MVCTREE_ITEM_COLLAPSED(p, p.GetId(), closed)
EVT_MVCTREE_ADD_ITEM(p, p.GetId(), add)
EVT_MVCTREE_DELETE_ITEM(p, p.GetId(), delitem)
EVT_MVCTREE_KEY_DOWN(p, p.GetId(), key)
return p
overview = """\
wxMVCTree is a control which handles hierarchical data. It is constructed in model-view-controller architecture, so the display of that data, and the content of the data can be changed greatly without affecting the other parts.
Multiple selections are possible by holding down the Ctrl key.
This demo shows the wxPython directory structure. The interesting part is that the tree model is late-bound to the filesystem, so the filenames are not retrieved until the directory is expanded. In mvctree.py are models for generic data, and both the early and late-bound filesystem models.
There is also support for editing, though it's not enabled in this demo, to avoid accidentally renaming files!
"""

View File

@@ -0,0 +1,60 @@
from wxPython.wx import *
try:
from wxPython.lib import vtk
haveVTK = true
except ImportError:
haveVTK = false
#----------------------------------------------------------------------
def runTest(frame, nb, log):
if haveVTK:
win = vtk.wxVTKRenderWindow(nb, -1)
# Get the render window
renWin = win.GetRenderWindow()
# Next, do the VTK stuff
ren = vtk.vtkRenderer()
renWin.AddRenderer(ren)
cone = vtk.vtkConeSource()
cone.SetResolution(80)
coneMapper = vtk.vtkPolyDataMapper()
coneMapper.SetInput(cone.GetOutput())
coneActor = vtk.vtkActor()
coneActor.SetMapper(coneMapper)
ren.AddActor(coneActor)
coneMapper.GetLookupTable().Build()
# Create a scalar bar
scalarBar = vtk.vtkScalarBarActor()
scalarBar.SetLookupTable(coneMapper.GetLookupTable())
scalarBar.SetTitle("Temperature")
scalarBar.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport()
scalarBar.GetPositionCoordinate().SetValue(0.1, 0.01)
scalarBar.SetOrientationToHorizontal()
scalarBar.SetWidth(0.8)
scalarBar.SetHeight(0.17)
ren.AddActor2D(scalarBar)
return win
else:
wxMessageBox("Unable to import VTK, which is a required component "
"of this demo. You need to download and install the "
"Python extension module for VTK from http://www.kitware.com/",
"Import Error")
return None
#----------------------------------------------------------------------
overview = """\
wxVTKRenderWindow is a wrapper around the vtkRenderWindow from the
VTK Visualization Toolkit. The VTK Python extensions are required,
they can be obtained from http://www.kitware.com/ where you can also
find some nifty pictures and stuff.
"""

View File

@@ -2,10 +2,8 @@
wxMVCTree is a control which handles hierarchical data. It is constructed
in model-view-controller architecture, so the display of that data, and
the content of the data can be changed greatly without affecting the other parts.
This module contains the wxMVCTree class (the 'controller' of the MVC trio)
and PathfinderNode, which it uses internally to manage its info.
Pathfinder actually is even more configurable than MVC normally implies, because
wxMVCTree actually is even more configurable than MVC normally implies, because
almost every aspect of it is pluggable:
wxMVCTree - Overall controller, and the window that actually gets placed
in the GUI.
@@ -24,7 +22,7 @@ Author/Maintainer - Bryn Keller <xoltar@starship.python.net>
#------------------------------------------------------------------------
from wxPython.wx import *
import os, sys
import os, sys, traceback
#------------------------------------------------------------------------
class MVCTreeNode:
@@ -94,6 +92,8 @@ class LayoutEngine:
self.tree = tree
def layout(self, node):
raise NotImplementedError
def GetNodeList(self):
raise NotImplementedError
class Transform:
"""
@@ -110,6 +110,13 @@ class Transform:
"""
raise NotImplementedError
def GetSize(self):
"""
Returns the size of the entire tree as laid out and transformed
as a tuple
"""
raise NotImplementedError
class Painter:
"""
This is the interface that wxMVCTree expects from painters. All painters should
@@ -122,9 +129,7 @@ class Painter:
self.fgcolor = wxNamedColour("BLUE")
self.linecolor = wxNamedColour("GREY")
self.font = wxFont(9, wxDEFAULT, wxNORMAL, wxNORMAL, false)
self.knobs = []
self.rectangles = []
self.minx = self.maxx = self.miny = self.maxy = 0
self.bmp = None
def GetFont(self):
return self.font
@@ -132,8 +137,11 @@ class Painter:
def SetFont(self, font):
self.font = font
self.tree.Refresh()
def paint(self, dc, node):
def GetBuffer(self):
return self.bmp
def ClearBuffer(self):
self.bmp = None
def paint(self, dc, node, doubleBuffered=1, paintBackground=1):
raise NotImplementedError
def GetTextColour(self):
return self.textcolor
@@ -177,19 +185,20 @@ class Painter:
return self.linebrush
def OnMouse(self, evt):
if evt.LeftDClick():
x, y = self.tree.CalcUnscrolledPosition(evt.GetX(), evt.GetY())
for item in self.rectangles:
if item[1].contains((evt.GetX(), evt.GetY())):
if item[1].contains((x,y)):
self.tree.Edit(item[0].data)
self.tree.OnNodeClick(item[0], evt)
return
elif evt.ButtonDown():
#self.oldpos = (evt.GetX(), evt.GetY())
x, y = self.tree.CalcUnscrolledPosition(evt.GetX(), evt.GetY())
for item in self.rectangles:
if item[1].contains((evt.GetX(), evt.GetY())):
if item[1].contains((x, y)):
self.tree.OnNodeClick(item[0], evt)
return
for item in self.knobs:
if item[1].contains((evt.GetX(), evt.GetY())):
if item[1].contains((x, y)):
self.tree.OnKnobClick(item[0])
return
evt.Skip()
@@ -331,7 +340,8 @@ class FileEditor(Editor):
self.editcomp.SetSelection(0, len(node.fileName))
self.editcomp.SetFocus()
self.treenode = treenode
EVT_KEY_DOWN(self.editcomp, self._key)
# EVT_KEY_DOWN(self.editcomp, self._key)
EVT_KEY_UP(self.editcomp, self._key)
EVT_LEFT_DOWN(self.editcomp, self._mdown)
self.editcomp.CaptureMouse()
@@ -347,10 +357,11 @@ class FileEditor(Editor):
os.rename(node.path + os.sep + node.fileName, node.path + os.sep + self.editcomp.GetValue())
node.fileName = self.editcomp.GetValue()
except:
import traceback;traceback.print_exc()
traceback.print_exc()
self.editcomp.ReleaseMouse()
self.editcomp.Destroy()
del self.editcomp
self.tree.Refresh()
def _key(self, evt):
@@ -364,7 +375,6 @@ class FileEditor(Editor):
def _mdown(self, evt):
if evt.IsButton():
pos = evt.GetPosition()
print pos.x, pos.y
edsize = self.editcomp.GetSize()
if pos.x < 0 or pos.y < 0 or pos.x > edsize.width or pos.y > edsize.height:
self.EndEdit(false)
@@ -416,7 +426,6 @@ class LateFSTreeModel(FSTreeModel):
import string
name = string.split(path, os.sep)[-1]
pathpart = path[:-len(name)]
print pathpart
fw = FileWrapper(pathpart, name)
self._Build(path, fw)
self.SetRoot(fw)
@@ -445,11 +454,19 @@ class StrTextConverter(TextConverter):
return str(node.data)
class NullTransform(Transform):
def GetSize(self):
return tuple(self.size)
def transform(self, node, offset, rotation):
node.projx = node.x + offset[0]
node.projy = node.y + offset[1]
for kid in node.kids:
self.transform(kid, offset, rotation)
self.size = [0,0]
list = self.tree.GetLayoutEngine().GetNodeList()
for node in list:
node.projx = node.x + offset[0]
node.projy = node.y + offset[1]
if node.projx > self.size[0]:
self.size[0] = node.projx
if node.projy > self.size[1]:
self.size[1] = node.projy
class Rect:
def __init__(self, x, y, width, height):
@@ -485,17 +502,27 @@ class TreeLayout(LayoutEngine):
LayoutEngine.__init__(self, tree)
self.NODE_STEP = 20
self.NODE_HEIGHT = 20
self.nodelist = []
def layout(self, node):
self.nodelist = []
self.layoutwalk(node)
def GetNodeList(self):
return self.nodelist
def layoutwalk(self, node):
if node == self.tree.currentRoot:
node.level = 1
self.lastY = (-self.NODE_HEIGHT)
node.x = self.NODE_STEP * node.level
node.y = self.lastY + self.NODE_HEIGHT
self.lastY = node.y
self.nodelist.append(node)
if node.expanded:
for kid in node.kids:
kid.level = node.level + 1
self.layout(kid)
self.layoutwalk(kid)
class TreePainter(Painter):
"""
@@ -515,7 +542,7 @@ class TreePainter(Painter):
self.textConverter = textConverter
self.charWidths = []
def paint(self, dc, node):
def paint(self, dc, node, doubleBuffered=1, paintBackground=1):
if not self.charWidths:
self.charWidths = []
for i in range(25):
@@ -530,15 +557,41 @@ class TreePainter(Painter):
self.fgbrush = wxBrush(self.GetForegroundColour(), wxSOLID)
self.bgbrush = wxBrush(self.GetBackgroundColour(), wxSOLID)
self.linebrush = wxPen(self.GetLineColour(), 1, wxSOLID)
self.rectangles = []
self.knobs = []
treesize = self.tree.GetSize()
size = self.tree.transform.GetSize()
size = (max(treesize.width, size[0]+50), max(treesize.height, size[1]+50))
dc.BeginDrawing()
dc.SetPen(self.GetBackgroundPen())
dc.SetBrush(self.GetBackgroundBrush())
size = self.tree.GetSize()
dc.DrawRectangle(0, 0, size.width, size.height)
if node:
self.paintWalk(node, dc)
if doubleBuffered:
mem_dc = wxMemoryDC()
if not self.GetBuffer():
self.knobs = []
self.rectangles = []
self.bmp = wxEmptyBitmap(size[0], size[1])
mem_dc.SelectObject(self.GetBuffer())
mem_dc.SetPen(self.GetBackgroundPen())
mem_dc.SetBrush(self.GetBackgroundBrush())
mem_dc.DrawRectangle(0, 0, size[0], size[1])
mem_dc.SetFont(self.tree.GetFont())
self.paintWalk(node, mem_dc)
else:
mem_dc.SelectObject(self.GetBuffer())
xstart, ystart = self.tree.CalcUnscrolledPosition(0,0)
size = self.tree.GetClientSizeTuple()
dc.Blit(xstart, ystart, size[0], size[1], mem_dc, xstart, ystart)
else:
if node == self.tree.currentRoot:
self.knobs = []
self.rectangles = []
dc.SetPen(self.GetBackgroundPen())
dc.SetBrush(self.GetBackgroundBrush())
dc.SetFont(self.tree.GetFont())
if paintBackground:
dc.DrawRectangle(0, 0, size[0], size[1])
if node:
#Call with not paintBackground because if we are told not to paint the
#whole background, we have to paint in parts to undo selection coloring.
pb = paintBackground
self.paintWalk(node, dc, not pb)
dc.EndDrawing()
def GetDashPen(self):
@@ -548,60 +601,57 @@ class TreePainter(Painter):
Painter.SetLinePen(self, pen)
self.dashpen = wxPen(pen.GetColour(), 1, wxDOT)
def drawBox(self, px, py, node, dc):
if self.tree.model.IsLeaf(node.data) or ((node.expanded or not self.tree._assumeChildren) and not len(node.kids)):
return
dc.SetPen(self.linepen)
dc.SetBrush(self.bgbrush)
dc.DrawRectangle(px -4, py-4, 9, 9)
self.knobs.append(node, Rect(px -4, py -4, 9, 9))
dc.SetPen(self.textpen)
if not node.expanded:
dc.DrawLine(px, py -2, px, py + 3)
dc.DrawLine(px -2, py, px + 3, py)
def paintWalk(self, node, dc):
def paintWalk(self, node, dc, paintRects=0):
self.linePainter.paint(node.parent, node, dc)
self.nodePainter.paint(node, dc)
self.nodePainter.paint(node, dc, drawRects = paintRects)
if node.expanded:
for kid in node.kids:
if not self.paintWalk(kid, dc):
if not self.paintWalk(kid, dc, paintRects):
return false
for kid in node.kids:
px = (kid.projx - self.tree.layout.NODE_STEP) + 5
py = kid.projy + kid.height/2
self.drawBox(px, py, kid, dc)
if (not self.tree.model.IsLeaf(kid.data)) or ((kid.expanded or self.tree._assumeChildren) and len(kid.kids)):
dc.SetPen(self.linepen)
dc.SetBrush(self.bgbrush)
dc.DrawRectangle(px -4, py-4, 9, 9)
self.knobs.append(kid, Rect(px -4, py -4, 9, 9))
dc.SetPen(self.textpen)
if not kid.expanded:
dc.DrawLine(px, py -2, px, py + 3)
dc.DrawLine(px -2, py, px + 3, py)
if node == self.tree.currentRoot:
px = (node.projx - self.tree.layout.NODE_STEP) + 5
py = node.projy + node.height/2
self.drawBox(px, py, node, dc)
dc.SetPen(self.linepen)
dc.SetBrush(self.bgbrush)
dc.DrawRectangle(px -4, py-4, 9, 9)
self.knobs.append(node, Rect(px -4, py -4, 9, 9))
dc.SetPen(self.textpen)
if not node.expanded:
dc.DrawLine(px, py -2, px, py + 3)
dc.DrawLine(px -2, py, px + 3, py)
return true
def OnMouse(self, evt):
Painter.OnMouse(self, evt)
class TreeNodePainter(NodePainter):
def paint(self, node, dc, location = None):
def paint(self, node, dc, location = None, drawRects = 0):
text = self.painter.textConverter.convert(node)
extent = dc.GetTextExtent(text)
node.width = extent[0]
node.height = extent[1]
if node == self.painter.tree.currentRoot:
self.painter.minx = self.painter.maxx = self.painter.miny = self.painter.maxy = 0
if node.projx < self.painter.minx:
self.painter.minx = node.projx
elif node.projx + node.width > self.painter.maxx:
self.painter.maxx = node.projx + node.width
if node.projy < self.painter.miny:
self.painter.miny = node.projy
elif node.projy + node.height > self.painter.maxy:
self.painter.maxy = node.projy + node.height
if node.selected:
dc.SetPen(self.painter.GetLinePen())
dc.SetBrush(self.painter.GetForegroundBrush())
dc.SetTextForeground(wxNamedColour("WHITE"))
dc.DrawRectangle(node.projx -1, node.projy -1, node.width + 3, node.height + 3)
else:
if drawRects:
dc.SetBrush(self.painter.GetBackgroundBrush())
dc.SetPen(self.painter.GetBackgroundPen())
dc.DrawRectangle(node.projx -1, node.projy -1, node.width + 3, node.height + 3)
dc.SetTextForeground(self.painter.GetTextColour())
dc.DrawText(text, node.projx, node.projy)
self.painter.rectangles.append((node, Rect(node.projx, node.projy, node.width, node.height)))
@@ -612,7 +662,7 @@ class TreeLinePainter(LinePainter):
px = py = cx = cy = 0
if parent is None or child == self.painter.tree.currentRoot:
px = (child.projx - self.painter.tree.layout.NODE_STEP) + 5
py = child.projy + self.painter.tree.layout.NODE_HEIGHT/2
py = child.projy + self.painter.tree.layout.NODE_HEIGHT/2 -2
cx = child.projx
cy = py
dc.DrawLine(px, py, cx, cy)
@@ -620,7 +670,7 @@ class TreeLinePainter(LinePainter):
px = parent.projx + 5
py = parent.projy + parent.height
cx = child.projx -5
cy = child.projy + self.painter.tree.layout.NODE_HEIGHT/2
cy = child.projy + self.painter.tree.layout.NODE_HEIGHT/2 -3
dc.DrawLine(px, py, px, cy)
dc.DrawLine(px, cy, cx, cy)
@@ -671,27 +721,35 @@ class wxMVCTreeEvent(wxPyCommandEvent):
self.node = node
self.nodes = nodes
self.keyEvent = keyEvent
def GetNode(self):
return self.node
def GetNodes(self):
return self.nodes
def getKeyEvent(self):
return self.keyEvent
class wxMVCTreeNotifyEvent(wxMVCTreeEvent):
def __init__(self, type, id, node = None, nodes = None, **kwargs):
apply(wxMVCTreeEvent.__init__, (self, type, id), kwargs)
self.notify = wxNotifyEvent(type, id)
def getNotifyEvent(self):
return self.notify
class wxMVCTree(wxWindow):
class wxMVCTree(wxScrolledWindow):
"""
The main mvcTree class.
The main mvc tree class.
"""
def __init__(self, parent, id, model = None, layout = None, transform = None,
painter = None, *args, **kwargs):
apply(wxWindow.__init__, (self, parent, id), kwargs)
apply(wxScrolledWindow.__init__, (self, parent, id), kwargs)
self.nodemap = {}
self._multiselect = false
self._selections = []
self._assumeChildren = false
self._scrollx = false
self._scrolly = false
self.doubleBuffered = true
self.doubleBuffered = false
self._lastPhysicalSize = self.GetSize()
self._editors = []
if not model:
model = BasicTreeModel()
@@ -708,8 +766,22 @@ class wxMVCTree(wxWindow):
self.painter = painter
self.SetFont(wxFont(9, wxDEFAULT, wxNORMAL, wxNORMAL, false))
EVT_MOUSE_EVENTS(self, self.OnMouse)
EVT_SCROLLWIN(self, self.OnScroll)
EVT_KEY_DOWN(self, self.OnKeyDown)
self.doubleBuffered = true
def Refresh(self):
if self.doubleBuffered:
self.painter.ClearBuffer()
wxScrolledWindow.Refresh(self)
def GetPainter(self):
return self.painter
def GetLayoutEngine(self):
return self.layout
def GetTransform(self):
return self.transform
def __repr__(self):
return "<wxMVCTree instance at %s>" % str(hex(id(self)))
@@ -720,15 +792,16 @@ class wxMVCTree(wxWindow):
def NodeAdded(self, parent, child):
e = wxMVCTreeEvent(wxEVT_MVCTREE_ADD_ITEM, self.GetId(), node = child, nodes = [parent, child])
self.GetEventHandler().ProcessEvent(e)
self.painter.ClearBuffer()
def NodeInserted(self, parent, child, index):
e = wxMVCTreeEvent(wxEVT_MVCTREE_ADD_ITEM, self.GetId(), node = child, nodes = [parent, child])
self.GetEventHandler().ProcessEvent(e)
self.painter.ClearBuffer()
def NodeRemoved(self, node):
e = wxMVCTreeEvent(wxEVT_MVCTREE_DELETE_ITEM, self.GetId(), node = child, nodes = [parent, child])
self.GetEventHandler().ProcessEvent(e)
self.painter.ClearBuffer()
def OnKeyDown(self, evt):
e = wxMVCTreeEvent(wxEVT_MVCTREE_KEY_DOWN, self.GetId(), keyEvent = evt)
self.GetEventHandler().ProcessEvent(e)
@@ -738,7 +811,7 @@ class wxMVCTree(wxWindow):
dc = wxClientDC(self)
dc.SetFont(font)
self.layout.SetHeight(dc.GetTextExtent("")[1] + 18)
self.painter.ClearBuffer()
def GetFont(self):
return self.painter.GetFont()
@@ -752,11 +825,10 @@ class wxMVCTree(wxWindow):
self.painter.OnMouse(evt)
def OnNodeClick(self, node, mouseEvent):
if node.selected:
if node.selected and (self.IsMultiSelect() and mouseEvent.ControlDown()):
self.RemoveFromSelection(node.data)
else:
self.AddToSelection(node.data, mouseEvent.ControlDown())
self.Refresh()
self.AddToSelection(node.data, mouseEvent.ControlDown(), mouseEvent.ShiftDown())
def OnKnobClick(self, node):
self.SetExpanded(node.data, not node.expanded)
@@ -793,6 +865,7 @@ class wxMVCTree(wxWindow):
self.currentRoot = self.layoutRoot
self.offset = [0,0]
self.rotation = 0
self._scrollset = None
self.Refresh()
def GetCurrentRoot(self):
@@ -817,12 +890,11 @@ class wxMVCTree(wxWindow):
pass
def OnSize(self, evt):
try:
size = self.GetSizeTuple()
self.center = (size[0]/2, size[1]/2)
del self.bmp
except:
pass
size = self.GetSize()
self.center = (size.width/2, size.height/2)
if self._lastPhysicalSize.width < size.width or self._lastPhysicalSize.height < size.height:
self.painter.ClearBuffer()
self._lastPhysicalSize = size
def GetSelection(self):
"Returns a tuple of selected nodes."
@@ -909,7 +981,7 @@ class wxMVCTree(wxWindow):
def IsExpanded(self, node):
return self.nodemap[node].expanded
def AddToSelection(self, nodeOrTuple, enableMulti = true):
def AddToSelection(self, nodeOrTuple, enableMulti = true, shiftMulti = false):
nodeTuple = nodeOrTuple
if type(nodeOrTuple)!= type(()):
nodeTuple = (nodeOrTuple,)
@@ -917,38 +989,68 @@ class wxMVCTree(wxWindow):
self.GetEventHandler().ProcessEvent(e)
if not e.notify.IsAllowed():
return
if not self.IsMultiSelect() or not enableMulti:
changeparents = []
if not (self.IsMultiSelect() and (enableMulti or shiftMulti)):
for node in self._selections:
treenode = self.nodemap[node]
treenode.selected = false
changeparents.append(treenode)
node = nodeTuple[0]
self._selections = [node]
treenode = self.nodemap[node]
changeparents.append(treenode)
treenode.selected = true
else:
for node in nodeTuple:
try:
self._selections.index(node)
except ValueError:
self._selections.append(node)
if shiftMulti:
for node in nodeTuple:
treenode = self.nodemap[node]
treenode.selected = true
oldtreenode = self.nodemap[self._selections[0]]
if treenode.parent == oldtreenode.parent:
found = 0
for kid in oldtreenode.parent.kids:
if kid == treenode or kid == oldtreenode:
found = not found
kid.selected = true
self._selections.append(kid.data)
changeparents.append(kid)
elif found:
kid.selected = true
self._selections.append(kid.data)
changeparents.append(kid)
else:
for node in nodeTuple:
try:
self._selections.index(node)
except ValueError:
self._selections.append(node)
treenode = self.nodemap[node]
treenode.selected = true
changeparents.append(treenode)
e = wxMVCTreeEvent(wxEVT_MVCTREE_SEL_CHANGED, self.GetId(), nodeTuple[0], nodes = nodeTuple)
self.GetEventHandler().ProcessEvent(e)
dc = wxClientDC(self)
self.PrepareDC(dc)
for node in changeparents:
if node:
self.painter.paint(dc, node, doubleBuffered = 0, paintBackground = 0)
self.painter.ClearBuffer()
def RemoveFromSelection(self, nodeTuple):
if type(nodeTuple) != type(()):
nodeTuple = (nodeTuple,)
changeparents = []
for node in nodeTuple:
try:
self._selections.index(node)
except IndexError:
self._selections.remove(node)
treenode = self.nodemap[node]
node.selected = false
self._selections.remove(node)
treenode = self.nodemap[node]
changeparents.append(treenode)
treenode.selected = false
e = wxMVCTreeEvent(wxEVT_MVCTREE_SEL_CHANGED, self.GetId(), node, nodes = nodeTuple)
self.GetEventHandler().ProcessEvent(e)
dc = wxClientDC(self)
self.PrepareDC(dc)
for node in changeparents:
if node:
self.painter.paint(dc, node, doubleBuffered = 0, paintBackground = 0)
self.painter.ClearBuffer()
def GetBackgroundColour(self):
@@ -978,126 +1080,39 @@ class wxMVCTree(wxWindow):
def GetAssumeChildren(self):
return self._assumeChildren
def OnScroll(self, evt):
type = evt.GetEventType()
field = [self.painter.maxx - self.painter.minx, self.painter.maxy - self.painter.miny]
size = self.GetSizeTuple()
index = 1
if evt.GetOrientation() == wxHORIZONTAL:
index = 0
self._scrollx = true
else:
self._scrolly = true
index = 1
if type == wxEVT_SCROLLWIN_TOP:
self.offset[index] = 0
elif type == wxEVT_SCROLLWIN_LINEUP:
self.offset[index] = self.offset[index] + 1
elif type == wxEVT_SCROLLWIN_LINEDOWN:
self.offset[index] = self.offset[index] - 1
elif type == wxEVT_SCROLLWIN_PAGEUP:
self.offset[index] = self.offset[index] + int(20 * float(field[index])/float(size[index]))
elif type == wxEVT_SCROLLWIN_PAGEDOWN:
self.offset[index] = self.offset[index] - int(20 * float(field[index])/float(size[index]))
elif type == wxEVT_SCROLLWIN_THUMBTRACK:
self.offset[index] = -(evt.GetPosition())
elif type == wxEVT_SCROLLWIN_BOTTOM:
self.offset[index] = field[index]
self.transformed = false
self.Refresh()
def OnPaint(self, evt):
"""
Ensures that the tree has been laid out and transformed, then calls the painter
to paint the control.
"""
try:
self.EnableScrolling(false, false)
if not self.laidOut:
self.layout.layout(self.currentRoot)
self.laidOut = true
self.transformed = false
if not self.transformed:
self.transform.transform(self.currentRoot, self.offset, self.rotation)
self.transformed = true
dc = wxPaintDC(self)
dc.SetFont(self.GetFont())
if self.doubleBuffered:
size = self.GetSize()
if not hasattr(self, 'bmp'):
self.bmp = bmp =wxEmptyBitmap(size.width, size.height)
else:
bmp = self.bmp
mem_dc = wxMemoryDC()
mem_dc.SetFont(self.GetFont())
mem_dc.SelectObject(bmp)
self.painter.paint(mem_dc, self.currentRoot)
dc.Blit(0, 0, size.width, size.height, mem_dc, 0, 0);
else:
self.painter.paint(dc, self.currentRoot)
tsize = None
tsize = list(self.transform.GetSize())
tsize[0] = tsize[0] + 50
tsize[1] = tsize[1] + 50
size = self.GetSizeTuple()
if self._scrollx or self.painter.minx < 0 or self.painter.maxx > size[0]:
field = self.painter.maxx - self.painter.minx
self.SetScrollbar(wxHORIZONTAL, -self.offset[0], size[0]/field, field, true)
self._scrollx = false
if self._scrolly or self.painter.miny < 0 or self.painter.maxy > size[1]:
field = self.painter.maxy - self.painter.miny
self.SetScrollbar(wxVERTICAL, -self.offset[1], size[1]/field, field, true)
self._scrolly = false
if tsize[0] > size[0] or tsize[1] > size[1]:
if not hasattr(self, '_oldsize') or (tsize[0] > self._oldsize[0] or tsize[1] > self._oldsize[1]):
self._oldsize = tsize
oldstart = self.ViewStart()
self._lastPhysicalSize = self.GetSize()
self.SetScrollbars(10, 10, tsize[0]/10, tsize[1]/10)
self.Scroll(oldstart[0], oldstart[1])
dc = wxPaintDC(self)
self.PrepareDC(dc)
dc.SetFont(self.GetFont())
self.painter.paint(dc, self.currentRoot, self.doubleBuffered)
except:
import traceback;traceback.print_exc()
if __name__ == '__main__':
def exit(evt):
import sys;sys.exit()
block = 0
def selchanging(evt):
print "SelChanging!"
print evt.node
global block
if block:
evt.notify.Veto()
block = not block
def selchanged(evt):
print "SelChange!"
print evt.node
def expanded(evt):
print "Expanded!"
def closed(evt):
print "Closed!"
def key(evt):
print "Key"
def add(evt):
print "Add"
def delitem(evt):
print "Delete"
class MyApp(wxApp):
def OnInit(self):
f = wxFrame(NULL, -1, "wxMVCTree")
p = None
p = wxMVCTree(f, -1)
p.SetAssumeChildren(true)
if len(sys.argv) > 1:
p.SetModel(LateFSTreeModel(sys.argv[1]))
p.AddEditor(FileEditor(p))
p.SetMultiSelect(true)
f.Show(true)
EVT_CLOSE(f, exit)
EVT_MVCTREE_SEL_CHANGED(p, p.GetId(), selchanged)
EVT_MVCTREE_SEL_CHANGING(p, p.GetId(), selchanging)
EVT_MVCTREE_ITEM_EXPANDED(p, p.GetId(), expanded)
EVT_MVCTREE_ITEM_COLLAPSED(p, p.GetId(), closed)
EVT_MVCTREE_ADD_ITEM(p, p.GetId(), add)
EVT_MVCTREE_DELETE_ITEM(p, p.GetId(), delitem)
EVT_MVCTREE_KEY_DOWN(p, p.GetId(), key)
p.SetForegroundColour(wxNamedColour("GREEN"))
self.SetTopWindow(f)
return true
app = MyApp(false)
app.MainLoop()
traceback.print_exc()

View File

@@ -109,49 +109,50 @@ class wxVTKRenderWindow(wxWindow):
## testcode is now in the demo ##
if __name__ == '__main__':
class TestFrame(wxFrame):
def __init__(self, parent):
wxFrame.__init__(self, parent, -1, "VTK Test", size=(450,450))
## if __name__ == '__main__':
## class TestFrame(wxFrame):
## def __init__(self, parent):
## wxFrame.__init__(self, parent, -1, "VTK Test", size=(450,450))
rw = wxVTKRenderWindow(self, -1)
## rw = wxVTKRenderWindow(self, -1)
# Get the render window
renWin = rw.GetRenderWindow()
## # Get the render window
## renWin = rw.GetRenderWindow()
# Next, do the VTK stuff
ren = vtkRenderer()
renWin.AddRenderer(ren)
cone = vtkConeSource()
cone.SetResolution(80)
coneMapper = vtkPolyDataMapper()
coneMapper.SetInput(cone.GetOutput())
coneActor = vtkActor()
coneActor.SetMapper(coneMapper)
ren.AddActor(coneActor)
coneMapper.GetLookupTable().Build()
## # Next, do the VTK stuff
## ren = vtkRenderer()
## renWin.AddRenderer(ren)
## cone = vtkConeSource()
## cone.SetResolution(80)
## coneMapper = vtkPolyDataMapper()
## coneMapper.SetInput(cone.GetOutput())
## coneActor = vtkActor()
## coneActor.SetMapper(coneMapper)
## ren.AddActor(coneActor)
## coneMapper.GetLookupTable().Build()
# Create a scalar bar
scalarBar = vtkScalarBarActor()
scalarBar.SetLookupTable(coneMapper.GetLookupTable())
scalarBar.SetTitle("Temperature")
scalarBar.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport()
scalarBar.GetPositionCoordinate().SetValue(0.1, 0.01)
scalarBar.SetOrientationToHorizontal()
scalarBar.SetWidth(0.8)
scalarBar.SetHeight(0.17)
ren.AddActor2D(scalarBar)
## # Create a scalar bar
## scalarBar = vtkScalarBarActor()
## scalarBar.SetLookupTable(coneMapper.GetLookupTable())
## scalarBar.SetTitle("Temperature")
## scalarBar.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport()
## scalarBar.GetPositionCoordinate().SetValue(0.1, 0.01)
## scalarBar.SetOrientationToHorizontal()
## scalarBar.SetWidth(0.8)
## scalarBar.SetHeight(0.17)
## ren.AddActor2D(scalarBar)
class TestApp(wxApp):
def OnInit(self):
f = TestFrame(None)
self.SetTopWindow(f)
f.Show(true)
return true
## class TestApp(wxApp):
## def OnInit(self):
## f = TestFrame(None)
## self.SetTopWindow(f)
## f.Show(true)
## return true
app = TestApp(0)
app.MainLoop()
## app = TestApp(0)
## app.MainLoop()