seSceneGraphExplorer.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. #################################################################
  2. # seSceneGraphExplorer.py
  3. # Originally from SceneGraphExplorer.py
  4. # Altered by Yi-Hong Lin, [email protected], 2004
  5. #
  6. # we need a customized SceneGraphExplorer.
  7. #
  8. # Do forget to check the seTree.
  9. #
  10. #################################################################
  11. from direct.showbase.DirectObject import *
  12. from direct.showbase.TkGlobal import *
  13. from seTree import *
  14. # changing these strings requires changing sceneEditor.py SGE_ strs too!
  15. # This list of items will be showed on the pop out window when user right click on
  16. # any node on the graph. And, this is also the main reason we decide to copy from
  17. # the original one but not inherited from it.
  18. # Because except drawing part, we have changed a lot of things...
  19. DEFAULT_MENU_ITEMS = [
  20. 'Update Explorer',
  21. 'Separator',
  22. 'Properties',
  23. 'Separator',
  24. 'Duplicate',
  25. 'Remove',
  26. 'Add Dummy',
  27. 'Add Collision Object',
  28. 'Metadata',
  29. 'Separator',
  30. 'Set as Reparent Target',
  31. 'Reparent to Target',
  32. 'Separator',
  33. 'Animation Panel',
  34. 'Blend Animation Panel',
  35. 'MoPath Panel',
  36. 'Align Tool',
  37. 'Separator']
  38. class seSceneGraphExplorer(Pmw.MegaWidget, DirectObject):
  39. "Graphical display of a scene graph"
  40. def __init__(self, parent = None, nodePath = render, **kw):
  41. # Define the megawidget options.
  42. optiondefs = (
  43. ('menuItems', [], Pmw.INITOPT),
  44. )
  45. self.defineoptions(kw, optiondefs)
  46. # Initialise superclass
  47. Pmw.MegaWidget.__init__(self, parent)
  48. # Initialize some class variables
  49. self.nodePath = nodePath
  50. # Create the components.
  51. # Setup up container
  52. interior = self.interior()
  53. interior.configure(relief = GROOVE, borderwidth = 2)
  54. # Create a label and an entry
  55. self._scrolledCanvas = self.createcomponent(
  56. 'scrolledCanvas',
  57. (), None,
  58. Pmw.ScrolledCanvas, (interior,),
  59. hull_width = 200, hull_height = 300,
  60. usehullsize = 1)
  61. self._canvas = self._scrolledCanvas.component('canvas')
  62. self._canvas['scrollregion'] = ('0i', '0i', '2i', '4i')
  63. self._scrolledCanvas.resizescrollregion()
  64. self._scrolledCanvas.pack(padx = 3, pady = 3, expand=1, fill = BOTH)
  65. self._canvas.bind('<ButtonPress-2>', self.mouse2Down)
  66. self._canvas.bind('<B2-Motion>', self.mouse2Motion)
  67. self._canvas.bind('<Configure>',
  68. lambda e, sc = self._scrolledCanvas:
  69. sc.resizescrollregion())
  70. self.interior().bind('<Destroy>', self.onDestroy)
  71. # Create the contents
  72. self._treeItem = SceneGraphExplorerItem(self.nodePath)
  73. self._node = TreeNode(self._canvas, None, self._treeItem,
  74. DEFAULT_MENU_ITEMS + self['menuItems'])
  75. self._node.expand()
  76. self._parentFrame = Frame(interior)
  77. self._label = self.createcomponent(
  78. 'parentLabel',
  79. (), None,
  80. Label, (interior,),
  81. text = 'Active Reparent Target: ',
  82. anchor = W, justify = LEFT)
  83. self._label.pack(fill = X)
  84. # Add update parent label
  85. def updateLabel(nodePath = None, s = self):
  86. s._label['text'] = 'Active Reparent Target: ' + nodePath.getName()
  87. self.accept('DIRECT_activeParent', updateLabel)
  88. # Add update hook
  89. self.accept('SGE_Update Explorer',
  90. lambda np, s = self: s.update())
  91. # Check keywords and initialise options based on input values.
  92. self.initialiseoptions(seSceneGraphExplorer)
  93. def update(self):
  94. """ Refresh scene graph explorer """
  95. self._node.update()
  96. def mouse2Down(self, event):
  97. self._width = 1.0 * self._canvas.winfo_width()
  98. self._height = 1.0 * self._canvas.winfo_height()
  99. xview = self._canvas.xview()
  100. yview = self._canvas.yview()
  101. self._left = xview[0]
  102. self._top = yview[0]
  103. self._dxview = xview[1] - xview[0]
  104. self._dyview = yview[1] - yview[0]
  105. self._2lx = event.x
  106. self._2ly = event.y
  107. def mouse2Motion(self,event):
  108. newx = self._left - ((event.x - self._2lx)/self._width) * self._dxview
  109. self._canvas.xview_moveto(newx)
  110. newy = self._top - ((event.y - self._2ly)/self._height) * self._dyview
  111. self._canvas.yview_moveto(newy)
  112. self._2lx = event.x
  113. self._2ly = event.y
  114. self._left = self._canvas.xview()[0]
  115. self._top = self._canvas.yview()[0]
  116. def onDestroy(self, event):
  117. # Remove hooks
  118. self.ignore('DIRECT_activeParent')
  119. self.ignore('SGE_Update Explorer')
  120. def deSelectTree(self):
  121. self._node.deselecttree()
  122. def selectNodePath(self,nodePath, callBack=True):
  123. item = self._node.find(nodePath.id())
  124. if item!= None:
  125. item.select(callBack)
  126. else:
  127. print '----SGE: Error Selection'
  128. class SceneGraphExplorerItem(TreeItem):
  129. """Example TreeItem subclass -- browse the file system."""
  130. def __init__(self, nodePath):
  131. self.nodePath = nodePath
  132. def GetText(self):
  133. type = self.nodePath.node().getType().getName()
  134. name = self.nodePath.getName()
  135. return type + " " + name
  136. def GetTextForEdit(self):
  137. name = self.nodePath.getName()
  138. return name
  139. def GetKey(self):
  140. return self.nodePath.id()
  141. def IsEditable(self):
  142. # All nodes' names can be edited nowadays.
  143. return 1
  144. #return issubclass(self.nodePath.node().__class__, NamedNode)
  145. def SetText(self, text):
  146. try:
  147. messenger.send('SGE_changeName', [self.nodePath, text])
  148. except AttributeError:
  149. pass
  150. def GetIconName(self):
  151. return "sphere2" # XXX wish there was a "file" icon
  152. def IsExpandable(self):
  153. return self.nodePath.getNumChildren() != 0
  154. def GetSubList(self):
  155. sublist = []
  156. for nodePath in self.nodePath.getChildrenAsList():
  157. item = SceneGraphExplorerItem(nodePath)
  158. sublist.append(item)
  159. return sublist
  160. def OnSelect(self, callback):
  161. messenger.send('SGE_Flash', [self.nodePath])
  162. if not callback:
  163. messenger.send('SGE_madeSelection', [self.nodePath, callback])
  164. else:
  165. messenger.send('SGE_madeSelection', [self.nodePath])
  166. def MenuCommand(self, command):
  167. messenger.send('SGE_' + command, [self.nodePath])
  168. def explore(nodePath = render):
  169. tl = Toplevel()
  170. tl.title('Explore: ' + nodePath.getName())
  171. sge = seSceneGraphExplorer(parent = tl, nodePath = nodePath)
  172. sge.pack(expand = 1, fill = 'both')
  173. return sge