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:
		| @@ -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 | What's new in 2.1.11 | ||||||
| -------------------- | -------------------- | ||||||
|   | |||||||
| @@ -21,6 +21,8 @@ _useSplitter       = true | |||||||
| _useNestedSplitter = true | _useNestedSplitter = true | ||||||
|  |  | ||||||
| _treeList = [ | _treeList = [ | ||||||
|  |     ('New since last release', ['wxMVCTree', 'wxVTKRenderWindow']), | ||||||
|  |  | ||||||
|     ('Managed Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame']), |     ('Managed Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame']), | ||||||
|  |  | ||||||
|     ('Non-Managed Windows', ['wxGrid', 'wxSashWindow', |     ('Non-Managed Windows', ['wxGrid', 'wxSashWindow', | ||||||
| @@ -47,7 +49,7 @@ _treeList = [ | |||||||
|  |  | ||||||
|     ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog', |     ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog', | ||||||
|                           'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar', |                           'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar', | ||||||
|                           'PyShell', 'wxCalendar']), |                           'PyShell', 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow']), | ||||||
|  |  | ||||||
|     ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']), |     ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']), | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										61
									
								
								utils/wxPython/demo/wxMVCTree.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								utils/wxPython/demo/wxMVCTree.py
									
									
									
									
									
										Normal 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! | ||||||
|  |  | ||||||
|  | """ | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										60
									
								
								utils/wxPython/demo/wxVTKRenderWindow.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								utils/wxPython/demo/wxVTKRenderWindow.py
									
									
									
									
									
										Normal 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. | ||||||
|  |  | ||||||
|  | """ | ||||||
| @@ -2,10 +2,8 @@ | |||||||
| wxMVCTree is a control which handles hierarchical data. It is constructed | wxMVCTree is a control which handles hierarchical data. It is constructed | ||||||
| in model-view-controller architecture, so the display of that data, and | 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. | 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: | almost every aspect of it is pluggable: | ||||||
|     wxMVCTree - Overall controller, and the window that actually gets placed |     wxMVCTree - Overall controller, and the window that actually gets placed | ||||||
|     in the GUI. |     in the GUI. | ||||||
| @@ -24,7 +22,7 @@ Author/Maintainer - Bryn Keller <xoltar@starship.python.net> | |||||||
|  |  | ||||||
| #------------------------------------------------------------------------ | #------------------------------------------------------------------------ | ||||||
| from wxPython.wx import * | from wxPython.wx import * | ||||||
| import os, sys | import os, sys, traceback | ||||||
| #------------------------------------------------------------------------ | #------------------------------------------------------------------------ | ||||||
|  |  | ||||||
| class MVCTreeNode: | class MVCTreeNode: | ||||||
| @@ -94,6 +92,8 @@ class LayoutEngine: | |||||||
|         self.tree = tree |         self.tree = tree | ||||||
|     def layout(self, node): |     def layout(self, node): | ||||||
|         raise NotImplementedError |         raise NotImplementedError | ||||||
|  |     def GetNodeList(self): | ||||||
|  |         raise NotImplementedError | ||||||
|  |  | ||||||
| class Transform: | class Transform: | ||||||
|     """ |     """ | ||||||
| @@ -110,6 +110,13 @@ class Transform: | |||||||
|         """ |         """ | ||||||
|         raise NotImplementedError |         raise NotImplementedError | ||||||
|  |  | ||||||
|  |     def GetSize(self): | ||||||
|  |         """ | ||||||
|  |         Returns the size of the entire tree as laid out and transformed | ||||||
|  |         as a tuple | ||||||
|  |         """ | ||||||
|  |         raise NotImplementedError | ||||||
|  |  | ||||||
| class Painter: | class Painter: | ||||||
|     """ |     """ | ||||||
|     This is the interface that wxMVCTree expects from painters. All painters should |     This is the interface that wxMVCTree expects from painters. All painters should | ||||||
| @@ -122,9 +129,7 @@ class Painter: | |||||||
|         self.fgcolor = wxNamedColour("BLUE") |         self.fgcolor = wxNamedColour("BLUE") | ||||||
|         self.linecolor = wxNamedColour("GREY") |         self.linecolor = wxNamedColour("GREY") | ||||||
|         self.font = wxFont(9, wxDEFAULT, wxNORMAL, wxNORMAL, false) |         self.font = wxFont(9, wxDEFAULT, wxNORMAL, wxNORMAL, false) | ||||||
|         self.knobs = [] |         self.bmp = None | ||||||
|         self.rectangles = [] |  | ||||||
|         self.minx = self.maxx = self.miny = self.maxy = 0 |  | ||||||
|  |  | ||||||
|     def GetFont(self): |     def GetFont(self): | ||||||
|         return self.font |         return self.font | ||||||
| @@ -132,8 +137,11 @@ class Painter: | |||||||
|     def SetFont(self, font): |     def SetFont(self, font): | ||||||
|         self.font = font |         self.font = font | ||||||
|         self.tree.Refresh() |         self.tree.Refresh() | ||||||
|  |     def GetBuffer(self): | ||||||
|     def paint(self, dc, node): |         return self.bmp | ||||||
|  |     def ClearBuffer(self): | ||||||
|  |         self.bmp = None | ||||||
|  |     def paint(self, dc, node, doubleBuffered=1, paintBackground=1): | ||||||
|         raise NotImplementedError |         raise NotImplementedError | ||||||
|     def GetTextColour(self): |     def GetTextColour(self): | ||||||
|         return self.textcolor |         return self.textcolor | ||||||
| @@ -177,19 +185,20 @@ class Painter: | |||||||
|         return self.linebrush |         return self.linebrush | ||||||
|     def OnMouse(self, evt): |     def OnMouse(self, evt): | ||||||
|         if evt.LeftDClick(): |         if evt.LeftDClick(): | ||||||
|  |             x, y = self.tree.CalcUnscrolledPosition(evt.GetX(), evt.GetY()) | ||||||
|             for item in self.rectangles: |             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.Edit(item[0].data) | ||||||
|                     self.tree.OnNodeClick(item[0], evt) |                     self.tree.OnNodeClick(item[0], evt) | ||||||
|                     return |                     return | ||||||
|         elif evt.ButtonDown(): |         elif evt.ButtonDown(): | ||||||
|             #self.oldpos = (evt.GetX(), evt.GetY()) |             x, y = self.tree.CalcUnscrolledPosition(evt.GetX(), evt.GetY()) | ||||||
|             for item in self.rectangles: |             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) |                     self.tree.OnNodeClick(item[0], evt) | ||||||
|                     return |                     return | ||||||
|             for item in self.knobs: |             for item in self.knobs: | ||||||
|                 if item[1].contains((evt.GetX(), evt.GetY())): |                 if item[1].contains((x, y)): | ||||||
|                     self.tree.OnKnobClick(item[0]) |                     self.tree.OnKnobClick(item[0]) | ||||||
|                     return |                     return | ||||||
|         evt.Skip() |         evt.Skip() | ||||||
| @@ -331,7 +340,8 @@ class FileEditor(Editor): | |||||||
|         self.editcomp.SetSelection(0, len(node.fileName)) |         self.editcomp.SetSelection(0, len(node.fileName)) | ||||||
|         self.editcomp.SetFocus() |         self.editcomp.SetFocus() | ||||||
|         self.treenode = treenode |         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) |         EVT_LEFT_DOWN(self.editcomp, self._mdown) | ||||||
|         self.editcomp.CaptureMouse() |         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()) |                 os.rename(node.path + os.sep + node.fileName, node.path + os.sep + self.editcomp.GetValue()) | ||||||
|                 node.fileName = self.editcomp.GetValue() |                 node.fileName = self.editcomp.GetValue() | ||||||
|             except: |             except: | ||||||
|                 import traceback;traceback.print_exc() |                 traceback.print_exc() | ||||||
|         self.editcomp.ReleaseMouse() |         self.editcomp.ReleaseMouse() | ||||||
|         self.editcomp.Destroy() |         self.editcomp.Destroy() | ||||||
|         del self.editcomp |         del self.editcomp | ||||||
|  |         self.tree.Refresh() | ||||||
|  |  | ||||||
|  |  | ||||||
|     def _key(self, evt): |     def _key(self, evt): | ||||||
| @@ -364,7 +375,6 @@ class FileEditor(Editor): | |||||||
|     def _mdown(self, evt): |     def _mdown(self, evt): | ||||||
|         if evt.IsButton(): |         if evt.IsButton(): | ||||||
|             pos = evt.GetPosition() |             pos = evt.GetPosition() | ||||||
|             print pos.x, pos.y |  | ||||||
|             edsize = self.editcomp.GetSize() |             edsize = self.editcomp.GetSize() | ||||||
|             if pos.x < 0 or pos.y < 0 or pos.x > edsize.width or pos.y > edsize.height: |             if pos.x < 0 or pos.y < 0 or pos.x > edsize.width or pos.y > edsize.height: | ||||||
|                 self.EndEdit(false) |                 self.EndEdit(false) | ||||||
| @@ -416,7 +426,6 @@ class LateFSTreeModel(FSTreeModel): | |||||||
|         import string |         import string | ||||||
|         name = string.split(path, os.sep)[-1] |         name = string.split(path, os.sep)[-1] | ||||||
|         pathpart = path[:-len(name)] |         pathpart = path[:-len(name)] | ||||||
|         print pathpart |  | ||||||
|         fw = FileWrapper(pathpart, name) |         fw = FileWrapper(pathpart, name) | ||||||
|         self._Build(path, fw) |         self._Build(path, fw) | ||||||
|         self.SetRoot(fw) |         self.SetRoot(fw) | ||||||
| @@ -445,11 +454,19 @@ class StrTextConverter(TextConverter): | |||||||
|         return str(node.data) |         return str(node.data) | ||||||
|  |  | ||||||
| class NullTransform(Transform): | class NullTransform(Transform): | ||||||
|  |     def GetSize(self): | ||||||
|  |         return tuple(self.size) | ||||||
|  |  | ||||||
|     def transform(self, node, offset, rotation): |     def transform(self, node, offset, rotation): | ||||||
|         node.projx = node.x + offset[0] |         self.size = [0,0] | ||||||
|         node.projy = node.y + offset[1] |         list = self.tree.GetLayoutEngine().GetNodeList() | ||||||
|         for kid in node.kids: |         for node in list: | ||||||
|             self.transform(kid, offset, rotation) |             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: | class Rect: | ||||||
|     def __init__(self, x, y, width, height): |     def __init__(self, x, y, width, height): | ||||||
| @@ -485,17 +502,27 @@ class TreeLayout(LayoutEngine): | |||||||
|         LayoutEngine.__init__(self, tree) |         LayoutEngine.__init__(self, tree) | ||||||
|         self.NODE_STEP = 20 |         self.NODE_STEP = 20 | ||||||
|         self.NODE_HEIGHT = 20 |         self.NODE_HEIGHT = 20 | ||||||
|  |         self.nodelist = [] | ||||||
|  |  | ||||||
|     def layout(self, node): |     def layout(self, node): | ||||||
|  |         self.nodelist = [] | ||||||
|  |         self.layoutwalk(node) | ||||||
|  |  | ||||||
|  |     def GetNodeList(self): | ||||||
|  |         return self.nodelist | ||||||
|  |  | ||||||
|  |     def layoutwalk(self, node): | ||||||
|         if node == self.tree.currentRoot: |         if node == self.tree.currentRoot: | ||||||
|             node.level = 1 |             node.level = 1 | ||||||
|             self.lastY = (-self.NODE_HEIGHT) |             self.lastY = (-self.NODE_HEIGHT) | ||||||
|         node.x = self.NODE_STEP * node.level |         node.x = self.NODE_STEP * node.level | ||||||
|         node.y = self.lastY + self.NODE_HEIGHT |         node.y = self.lastY + self.NODE_HEIGHT | ||||||
|         self.lastY = node.y |         self.lastY = node.y | ||||||
|  |         self.nodelist.append(node) | ||||||
|         if node.expanded: |         if node.expanded: | ||||||
|             for kid in node.kids: |             for kid in node.kids: | ||||||
|                 kid.level = node.level + 1 |                 kid.level = node.level + 1 | ||||||
|                 self.layout(kid) |                 self.layoutwalk(kid) | ||||||
|  |  | ||||||
| class TreePainter(Painter): | class TreePainter(Painter): | ||||||
|     """ |     """ | ||||||
| @@ -515,7 +542,7 @@ class TreePainter(Painter): | |||||||
|         self.textConverter = textConverter |         self.textConverter = textConverter | ||||||
|         self.charWidths = [] |         self.charWidths = [] | ||||||
|  |  | ||||||
|     def paint(self, dc, node): |     def paint(self, dc, node, doubleBuffered=1, paintBackground=1): | ||||||
|         if not self.charWidths: |         if not self.charWidths: | ||||||
|             self.charWidths = [] |             self.charWidths = [] | ||||||
|             for i in range(25): |             for i in range(25): | ||||||
| @@ -530,15 +557,41 @@ class TreePainter(Painter): | |||||||
|         self.fgbrush = wxBrush(self.GetForegroundColour(), wxSOLID) |         self.fgbrush = wxBrush(self.GetForegroundColour(), wxSOLID) | ||||||
|         self.bgbrush = wxBrush(self.GetBackgroundColour(), wxSOLID) |         self.bgbrush = wxBrush(self.GetBackgroundColour(), wxSOLID) | ||||||
|         self.linebrush = wxPen(self.GetLineColour(), 1, wxSOLID) |         self.linebrush = wxPen(self.GetLineColour(), 1, wxSOLID) | ||||||
|         self.rectangles = [] |         treesize = self.tree.GetSize() | ||||||
|         self.knobs = [] |         size = self.tree.transform.GetSize() | ||||||
|  |         size = (max(treesize.width, size[0]+50), max(treesize.height, size[1]+50)) | ||||||
|         dc.BeginDrawing() |         dc.BeginDrawing() | ||||||
|         dc.SetPen(self.GetBackgroundPen()) |         if doubleBuffered: | ||||||
|         dc.SetBrush(self.GetBackgroundBrush()) |             mem_dc = wxMemoryDC() | ||||||
|         size = self.tree.GetSize() |             if not self.GetBuffer(): | ||||||
|         dc.DrawRectangle(0, 0, size.width, size.height) |                 self.knobs = [] | ||||||
|         if node: |                 self.rectangles = [] | ||||||
|             self.paintWalk(node, dc) |                 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() |         dc.EndDrawing() | ||||||
|  |  | ||||||
|     def GetDashPen(self): |     def GetDashPen(self): | ||||||
| @@ -548,60 +601,57 @@ class TreePainter(Painter): | |||||||
|         Painter.SetLinePen(self, pen) |         Painter.SetLinePen(self, pen) | ||||||
|         self.dashpen = wxPen(pen.GetColour(), 1, wxDOT) |         self.dashpen = wxPen(pen.GetColour(), 1, wxDOT) | ||||||
|  |  | ||||||
|     def drawBox(self, px, py, node, dc): |     def paintWalk(self, node, dc, paintRects=0): | ||||||
|         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): |  | ||||||
|         self.linePainter.paint(node.parent, node, dc) |         self.linePainter.paint(node.parent, node, dc) | ||||||
|         self.nodePainter.paint(node, dc) |         self.nodePainter.paint(node, dc, drawRects = paintRects) | ||||||
|         if node.expanded: |         if node.expanded: | ||||||
|             for kid in node.kids: |             for kid in node.kids: | ||||||
|                 if not self.paintWalk(kid, dc): |                 if not self.paintWalk(kid, dc, paintRects): | ||||||
|                     return false |                     return false | ||||||
|             for kid in node.kids: |             for kid in node.kids: | ||||||
|                 px = (kid.projx - self.tree.layout.NODE_STEP) + 5 |                 px = (kid.projx - self.tree.layout.NODE_STEP) + 5 | ||||||
|                 py = kid.projy + kid.height/2 |                 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: |         if node == self.tree.currentRoot: | ||||||
|             px = (node.projx - self.tree.layout.NODE_STEP) + 5 |             px = (node.projx - self.tree.layout.NODE_STEP) + 5 | ||||||
|             py = node.projy + node.height/2 |             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 |         return true | ||||||
|  |  | ||||||
|     def OnMouse(self, evt): |     def OnMouse(self, evt): | ||||||
|         Painter.OnMouse(self, evt) |         Painter.OnMouse(self, evt) | ||||||
|  |  | ||||||
| class TreeNodePainter(NodePainter): | 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) |         text = self.painter.textConverter.convert(node) | ||||||
|         extent = dc.GetTextExtent(text) |         extent = dc.GetTextExtent(text) | ||||||
|         node.width = extent[0] |         node.width = extent[0] | ||||||
|         node.height = extent[1] |         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: |         if node.selected: | ||||||
|             dc.SetPen(self.painter.GetLinePen()) |             dc.SetPen(self.painter.GetLinePen()) | ||||||
|             dc.SetBrush(self.painter.GetForegroundBrush()) |             dc.SetBrush(self.painter.GetForegroundBrush()) | ||||||
|             dc.SetTextForeground(wxNamedColour("WHITE")) |             dc.SetTextForeground(wxNamedColour("WHITE")) | ||||||
|             dc.DrawRectangle(node.projx -1, node.projy -1, node.width + 3, node.height + 3) |             dc.DrawRectangle(node.projx -1, node.projy -1, node.width + 3, node.height + 3) | ||||||
|         else: |         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.SetTextForeground(self.painter.GetTextColour()) | ||||||
|         dc.DrawText(text, node.projx, node.projy) |         dc.DrawText(text, node.projx, node.projy) | ||||||
|         self.painter.rectangles.append((node, Rect(node.projx, node.projy, node.width, node.height))) |         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 |         px = py = cx = cy = 0 | ||||||
|         if parent is None or child == self.painter.tree.currentRoot: |         if parent is None or child == self.painter.tree.currentRoot: | ||||||
|             px = (child.projx - self.painter.tree.layout.NODE_STEP) + 5 |             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 |             cx = child.projx | ||||||
|             cy = py |             cy = py | ||||||
|             dc.DrawLine(px, py, cx, cy) |             dc.DrawLine(px, py, cx, cy) | ||||||
| @@ -620,7 +670,7 @@ class TreeLinePainter(LinePainter): | |||||||
|             px = parent.projx + 5 |             px = parent.projx + 5 | ||||||
|             py = parent.projy + parent.height |             py = parent.projy + parent.height | ||||||
|             cx = child.projx -5 |             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, py, px, cy) | ||||||
|             dc.DrawLine(px, cy, cx, cy) |             dc.DrawLine(px, cy, cx, cy) | ||||||
|  |  | ||||||
| @@ -671,27 +721,35 @@ class wxMVCTreeEvent(wxPyCommandEvent): | |||||||
|         self.node = node |         self.node = node | ||||||
|         self.nodes = nodes |         self.nodes = nodes | ||||||
|         self.keyEvent = keyEvent |         self.keyEvent = keyEvent | ||||||
|  |     def GetNode(self): | ||||||
|  |         return self.node | ||||||
|  |     def GetNodes(self): | ||||||
|  |         return self.nodes | ||||||
|  |     def getKeyEvent(self): | ||||||
|  |         return self.keyEvent | ||||||
|  |  | ||||||
| class wxMVCTreeNotifyEvent(wxMVCTreeEvent): | class wxMVCTreeNotifyEvent(wxMVCTreeEvent): | ||||||
|     def __init__(self, type, id, node = None, nodes = None, **kwargs): |     def __init__(self, type, id, node = None, nodes = None, **kwargs): | ||||||
|         apply(wxMVCTreeEvent.__init__, (self, type, id), kwargs) |         apply(wxMVCTreeEvent.__init__, (self, type, id), kwargs) | ||||||
|         self.notify = wxNotifyEvent(type, id) |         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, |     def __init__(self, parent, id, model = None, layout = None, transform = None, | ||||||
|                  painter = None, *args, **kwargs): |                  painter = None, *args, **kwargs): | ||||||
|         apply(wxWindow.__init__, (self, parent, id), kwargs) |         apply(wxScrolledWindow.__init__, (self, parent, id), kwargs) | ||||||
|         self.nodemap = {} |         self.nodemap = {} | ||||||
|         self._multiselect = false |         self._multiselect = false | ||||||
|         self._selections = [] |         self._selections = [] | ||||||
|         self._assumeChildren = false |         self._assumeChildren = false | ||||||
|         self._scrollx = false |         self._scrollx = false | ||||||
|         self._scrolly = false |         self._scrolly = false | ||||||
|         self.doubleBuffered = true |         self.doubleBuffered = false | ||||||
|  |         self._lastPhysicalSize = self.GetSize() | ||||||
|         self._editors = [] |         self._editors = [] | ||||||
|         if not model: |         if not model: | ||||||
|             model = BasicTreeModel() |             model = BasicTreeModel() | ||||||
| @@ -708,8 +766,22 @@ class wxMVCTree(wxWindow): | |||||||
|         self.painter = painter |         self.painter = painter | ||||||
|         self.SetFont(wxFont(9, wxDEFAULT, wxNORMAL, wxNORMAL, false)) |         self.SetFont(wxFont(9, wxDEFAULT, wxNORMAL, wxNORMAL, false)) | ||||||
|         EVT_MOUSE_EVENTS(self, self.OnMouse) |         EVT_MOUSE_EVENTS(self, self.OnMouse) | ||||||
|         EVT_SCROLLWIN(self, self.OnScroll) |  | ||||||
|         EVT_KEY_DOWN(self, self.OnKeyDown) |         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): |     def __repr__(self): | ||||||
|         return "<wxMVCTree instance at %s>" % str(hex(id(self))) |         return "<wxMVCTree instance at %s>" % str(hex(id(self))) | ||||||
| @@ -720,15 +792,16 @@ class wxMVCTree(wxWindow): | |||||||
|     def NodeAdded(self, parent, child): |     def NodeAdded(self, parent, child): | ||||||
|         e = wxMVCTreeEvent(wxEVT_MVCTREE_ADD_ITEM, self.GetId(), node = child, nodes = [parent, child]) |         e = wxMVCTreeEvent(wxEVT_MVCTREE_ADD_ITEM, self.GetId(), node = child, nodes = [parent, child]) | ||||||
|         self.GetEventHandler().ProcessEvent(e) |         self.GetEventHandler().ProcessEvent(e) | ||||||
|  |         self.painter.ClearBuffer() | ||||||
|  |  | ||||||
|     def NodeInserted(self, parent, child, index): |     def NodeInserted(self, parent, child, index): | ||||||
|         e = wxMVCTreeEvent(wxEVT_MVCTREE_ADD_ITEM, self.GetId(), node = child, nodes = [parent, child]) |         e = wxMVCTreeEvent(wxEVT_MVCTREE_ADD_ITEM, self.GetId(), node = child, nodes = [parent, child]) | ||||||
|         self.GetEventHandler().ProcessEvent(e) |         self.GetEventHandler().ProcessEvent(e) | ||||||
|  |         self.painter.ClearBuffer() | ||||||
|     def NodeRemoved(self, node): |     def NodeRemoved(self, node): | ||||||
|         e = wxMVCTreeEvent(wxEVT_MVCTREE_DELETE_ITEM, self.GetId(), node = child, nodes = [parent, child]) |         e = wxMVCTreeEvent(wxEVT_MVCTREE_DELETE_ITEM, self.GetId(), node = child, nodes = [parent, child]) | ||||||
|         self.GetEventHandler().ProcessEvent(e) |         self.GetEventHandler().ProcessEvent(e) | ||||||
|  |         self.painter.ClearBuffer() | ||||||
|     def OnKeyDown(self, evt): |     def OnKeyDown(self, evt): | ||||||
|         e = wxMVCTreeEvent(wxEVT_MVCTREE_KEY_DOWN, self.GetId(), keyEvent = evt) |         e = wxMVCTreeEvent(wxEVT_MVCTREE_KEY_DOWN, self.GetId(), keyEvent = evt) | ||||||
|         self.GetEventHandler().ProcessEvent(e) |         self.GetEventHandler().ProcessEvent(e) | ||||||
| @@ -738,7 +811,7 @@ class wxMVCTree(wxWindow): | |||||||
|         dc = wxClientDC(self) |         dc = wxClientDC(self) | ||||||
|         dc.SetFont(font) |         dc.SetFont(font) | ||||||
|         self.layout.SetHeight(dc.GetTextExtent("")[1] + 18) |         self.layout.SetHeight(dc.GetTextExtent("")[1] + 18) | ||||||
|  |         self.painter.ClearBuffer() | ||||||
|     def GetFont(self): |     def GetFont(self): | ||||||
|         return self.painter.GetFont() |         return self.painter.GetFont() | ||||||
|  |  | ||||||
| @@ -752,11 +825,10 @@ class wxMVCTree(wxWindow): | |||||||
|         self.painter.OnMouse(evt) |         self.painter.OnMouse(evt) | ||||||
|  |  | ||||||
|     def OnNodeClick(self, node, mouseEvent): |     def OnNodeClick(self, node, mouseEvent): | ||||||
|         if node.selected: |         if node.selected and (self.IsMultiSelect() and mouseEvent.ControlDown()): | ||||||
|             self.RemoveFromSelection(node.data) |             self.RemoveFromSelection(node.data) | ||||||
|         else: |         else: | ||||||
|             self.AddToSelection(node.data, mouseEvent.ControlDown()) |             self.AddToSelection(node.data, mouseEvent.ControlDown(), mouseEvent.ShiftDown()) | ||||||
|         self.Refresh() |  | ||||||
|  |  | ||||||
|     def OnKnobClick(self, node): |     def OnKnobClick(self, node): | ||||||
|         self.SetExpanded(node.data, not node.expanded) |         self.SetExpanded(node.data, not node.expanded) | ||||||
| @@ -793,6 +865,7 @@ class wxMVCTree(wxWindow): | |||||||
|         self.currentRoot = self.layoutRoot |         self.currentRoot = self.layoutRoot | ||||||
|         self.offset = [0,0] |         self.offset = [0,0] | ||||||
|         self.rotation = 0 |         self.rotation = 0 | ||||||
|  |         self._scrollset = None | ||||||
|         self.Refresh() |         self.Refresh() | ||||||
|  |  | ||||||
|     def GetCurrentRoot(self): |     def GetCurrentRoot(self): | ||||||
| @@ -817,12 +890,11 @@ class wxMVCTree(wxWindow): | |||||||
|         pass |         pass | ||||||
|  |  | ||||||
|     def OnSize(self, evt): |     def OnSize(self, evt): | ||||||
|         try: |         size = self.GetSize() | ||||||
|             size = self.GetSizeTuple() |         self.center = (size.width/2, size.height/2) | ||||||
|             self.center = (size[0]/2, size[1]/2) |         if self._lastPhysicalSize.width < size.width or self._lastPhysicalSize.height < size.height: | ||||||
|             del self.bmp |             self.painter.ClearBuffer() | ||||||
|         except: |         self._lastPhysicalSize = size | ||||||
|             pass |  | ||||||
|  |  | ||||||
|     def GetSelection(self): |     def GetSelection(self): | ||||||
|         "Returns a tuple of selected nodes." |         "Returns a tuple of selected nodes." | ||||||
| @@ -909,7 +981,7 @@ class wxMVCTree(wxWindow): | |||||||
|     def IsExpanded(self, node): |     def IsExpanded(self, node): | ||||||
|         return self.nodemap[node].expanded |         return self.nodemap[node].expanded | ||||||
|  |  | ||||||
|     def AddToSelection(self, nodeOrTuple, enableMulti = true): |     def AddToSelection(self, nodeOrTuple, enableMulti = true, shiftMulti = false): | ||||||
|         nodeTuple = nodeOrTuple |         nodeTuple = nodeOrTuple | ||||||
|         if type(nodeOrTuple)!= type(()): |         if type(nodeOrTuple)!= type(()): | ||||||
|             nodeTuple = (nodeOrTuple,) |             nodeTuple = (nodeOrTuple,) | ||||||
| @@ -917,38 +989,68 @@ class wxMVCTree(wxWindow): | |||||||
|         self.GetEventHandler().ProcessEvent(e) |         self.GetEventHandler().ProcessEvent(e) | ||||||
|         if not e.notify.IsAllowed(): |         if not e.notify.IsAllowed(): | ||||||
|             return |             return | ||||||
|         if not self.IsMultiSelect() or not enableMulti: |         changeparents = [] | ||||||
|  |         if not (self.IsMultiSelect() and (enableMulti or shiftMulti)): | ||||||
|             for node in self._selections: |             for node in self._selections: | ||||||
|                 treenode = self.nodemap[node] |                 treenode = self.nodemap[node] | ||||||
|                 treenode.selected = false |                 treenode.selected = false | ||||||
|  |                 changeparents.append(treenode) | ||||||
|             node = nodeTuple[0] |             node = nodeTuple[0] | ||||||
|             self._selections = [node] |             self._selections = [node] | ||||||
|             treenode = self.nodemap[node] |             treenode = self.nodemap[node] | ||||||
|  |             changeparents.append(treenode) | ||||||
|             treenode.selected = true |             treenode.selected = true | ||||||
|         else: |         else: | ||||||
|             for node in nodeTuple: |             if shiftMulti: | ||||||
|                 try: |                 for node in nodeTuple: | ||||||
|                     self._selections.index(node) |  | ||||||
|                 except ValueError: |  | ||||||
|                     self._selections.append(node) |  | ||||||
|                     treenode = self.nodemap[node] |                     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) |         e = wxMVCTreeEvent(wxEVT_MVCTREE_SEL_CHANGED, self.GetId(), nodeTuple[0], nodes = nodeTuple) | ||||||
|         self.GetEventHandler().ProcessEvent(e) |         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): |     def RemoveFromSelection(self, nodeTuple): | ||||||
|         if type(nodeTuple) != type(()): |         if type(nodeTuple) != type(()): | ||||||
|             nodeTuple = (nodeTuple,) |             nodeTuple = (nodeTuple,) | ||||||
|  |         changeparents = [] | ||||||
|         for node in nodeTuple: |         for node in nodeTuple: | ||||||
|             try: |             self._selections.remove(node) | ||||||
|                 self._selections.index(node) |             treenode = self.nodemap[node] | ||||||
|             except IndexError: |             changeparents.append(treenode) | ||||||
|                 self._selections.remove(node) |             treenode.selected = false | ||||||
|                 treenode = self.nodemap[node] |  | ||||||
|                 node.selected = false |  | ||||||
|         e = wxMVCTreeEvent(wxEVT_MVCTREE_SEL_CHANGED, self.GetId(), node, nodes = nodeTuple) |         e = wxMVCTreeEvent(wxEVT_MVCTREE_SEL_CHANGED, self.GetId(), node, nodes = nodeTuple) | ||||||
|         self.GetEventHandler().ProcessEvent(e) |         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): |     def GetBackgroundColour(self): | ||||||
| @@ -978,126 +1080,39 @@ class wxMVCTree(wxWindow): | |||||||
|     def GetAssumeChildren(self): |     def GetAssumeChildren(self): | ||||||
|         return self._assumeChildren |         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): |     def OnPaint(self, evt): | ||||||
|         """ |         """ | ||||||
|         Ensures that the tree has been laid out and transformed, then calls the painter |         Ensures that the tree has been laid out and transformed, then calls the painter | ||||||
|         to paint the control. |         to paint the control. | ||||||
|         """ |         """ | ||||||
|         try: |         try: | ||||||
|  |             self.EnableScrolling(false, false) | ||||||
|             if not self.laidOut: |             if not self.laidOut: | ||||||
|                 self.layout.layout(self.currentRoot) |                 self.layout.layout(self.currentRoot) | ||||||
|                 self.laidOut = true |                 self.laidOut = true | ||||||
|  |                 self.transformed = false | ||||||
|             if not self.transformed: |             if not self.transformed: | ||||||
|                 self.transform.transform(self.currentRoot, self.offset, self.rotation) |                 self.transform.transform(self.currentRoot, self.offset, self.rotation) | ||||||
|                 self.transformed = true |                 self.transformed = true | ||||||
|             dc = wxPaintDC(self) |             tsize = None | ||||||
|             dc.SetFont(self.GetFont()) |             tsize = list(self.transform.GetSize()) | ||||||
|             if self.doubleBuffered: |             tsize[0] = tsize[0] + 50 | ||||||
|                 size = self.GetSize() |             tsize[1] = tsize[1] + 50 | ||||||
|                 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) |  | ||||||
|             size = self.GetSizeTuple() |             size = self.GetSizeTuple() | ||||||
|             if self._scrollx or self.painter.minx < 0 or self.painter.maxx > size[0]: |             if tsize[0] > size[0] or tsize[1] > size[1]: | ||||||
|                 field = self.painter.maxx - self.painter.minx |                 if not hasattr(self, '_oldsize') or (tsize[0] > self._oldsize[0] or tsize[1] > self._oldsize[1]): | ||||||
|                 self.SetScrollbar(wxHORIZONTAL, -self.offset[0], size[0]/field, field, true) |                     self._oldsize = tsize | ||||||
|                 self._scrollx = false |                     oldstart = self.ViewStart() | ||||||
|             if self._scrolly or self.painter.miny < 0 or self.painter.maxy > size[1]: |                     self._lastPhysicalSize = self.GetSize() | ||||||
|                 field = self.painter.maxy - self.painter.miny |                     self.SetScrollbars(10, 10, tsize[0]/10, tsize[1]/10) | ||||||
|                 self.SetScrollbar(wxVERTICAL, -self.offset[1], size[1]/field, field, true) |                     self.Scroll(oldstart[0], oldstart[1]) | ||||||
|                 self._scrolly = false |             dc = wxPaintDC(self) | ||||||
|  |             self.PrepareDC(dc) | ||||||
|  |             dc.SetFont(self.GetFont()) | ||||||
|  |             self.painter.paint(dc, self.currentRoot, self.doubleBuffered) | ||||||
|         except: |         except: | ||||||
|             import traceback;traceback.print_exc() |             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() |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -109,49 +109,50 @@ class wxVTKRenderWindow(wxWindow): | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## testcode is now in the demo ## | ||||||
|  |  | ||||||
| if __name__ == '__main__': | ## if __name__ == '__main__': | ||||||
|     class TestFrame(wxFrame): | ##     class TestFrame(wxFrame): | ||||||
|         def __init__(self, parent): | ##         def __init__(self, parent): | ||||||
|             wxFrame.__init__(self, parent, -1, "VTK Test", size=(450,450)) | ##             wxFrame.__init__(self, parent, -1, "VTK Test", size=(450,450)) | ||||||
|  |  | ||||||
|             rw = wxVTKRenderWindow(self, -1) | ##             rw = wxVTKRenderWindow(self, -1) | ||||||
|  |  | ||||||
|             # Get the render window | ##             # Get the render window | ||||||
|             renWin = rw.GetRenderWindow() | ##             renWin = rw.GetRenderWindow() | ||||||
|  |  | ||||||
|             # Next, do the VTK stuff | ##             # Next, do the VTK stuff | ||||||
|             ren = vtkRenderer() | ##             ren = vtkRenderer() | ||||||
|             renWin.AddRenderer(ren) | ##             renWin.AddRenderer(ren) | ||||||
|             cone = vtkConeSource() | ##             cone = vtkConeSource() | ||||||
|             cone.SetResolution(80) | ##             cone.SetResolution(80) | ||||||
|             coneMapper = vtkPolyDataMapper() | ##             coneMapper = vtkPolyDataMapper() | ||||||
|             coneMapper.SetInput(cone.GetOutput()) | ##             coneMapper.SetInput(cone.GetOutput()) | ||||||
|             coneActor = vtkActor() | ##             coneActor = vtkActor() | ||||||
|             coneActor.SetMapper(coneMapper) | ##             coneActor.SetMapper(coneMapper) | ||||||
|             ren.AddActor(coneActor) | ##             ren.AddActor(coneActor) | ||||||
|             coneMapper.GetLookupTable().Build() | ##             coneMapper.GetLookupTable().Build() | ||||||
|  |  | ||||||
|             # Create a scalar bar | ##             # Create a scalar bar | ||||||
|             scalarBar = vtkScalarBarActor() | ##             scalarBar = vtkScalarBarActor() | ||||||
|             scalarBar.SetLookupTable(coneMapper.GetLookupTable()) | ##             scalarBar.SetLookupTable(coneMapper.GetLookupTable()) | ||||||
|             scalarBar.SetTitle("Temperature") | ##             scalarBar.SetTitle("Temperature") | ||||||
|             scalarBar.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport() | ##             scalarBar.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport() | ||||||
|             scalarBar.GetPositionCoordinate().SetValue(0.1, 0.01) | ##             scalarBar.GetPositionCoordinate().SetValue(0.1, 0.01) | ||||||
|             scalarBar.SetOrientationToHorizontal() | ##             scalarBar.SetOrientationToHorizontal() | ||||||
|             scalarBar.SetWidth(0.8) | ##             scalarBar.SetWidth(0.8) | ||||||
|             scalarBar.SetHeight(0.17) | ##             scalarBar.SetHeight(0.17) | ||||||
|             ren.AddActor2D(scalarBar) | ##             ren.AddActor2D(scalarBar) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     class TestApp(wxApp): | ##     class TestApp(wxApp): | ||||||
|         def OnInit(self): | ##         def OnInit(self): | ||||||
|             f = TestFrame(None) | ##             f = TestFrame(None) | ||||||
|             self.SetTopWindow(f) | ##             self.SetTopWindow(f) | ||||||
|             f.Show(true) | ##             f.Show(true) | ||||||
|             return true | ##             return true | ||||||
|  |  | ||||||
|     app = TestApp(0) | ##     app = TestApp(0) | ||||||
|     app.MainLoop() | ##     app.MainLoop() | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user