瀏覽代碼

*** empty log message ***

Mark Mine 25 年之前
父節點
當前提交
6ef606cbc8
共有 2 個文件被更改,包括 27 次插入366 次删除
  1. 2 343
      direct/src/tkwidgets/SceneGraphExplorer.py
  2. 25 23
      direct/src/tkwidgets/Tree.py

+ 2 - 343
direct/src/tkwidgets/SceneGraphExplorer.py

@@ -4,347 +4,6 @@ from Tree import *
 import Pmw
 
 
-# Initialize icon directory
-f = Filename('icons')
-f.resolveFilename(getModelPath())
-ICONDIR = f.toOsSpecific()
-if not os.path.isdir(ICONDIR):
-    raise RuntimeError, "can't find DIRECT icon directory (%s)" % `ICONDIR`
-
-class TreeNode:
-
-    def __init__(self, canvas, parent, item, menuList = []):
-        self.canvas = canvas
-        self.parent = parent
-        self.item = item
-        self.state = 'collapsed'
-        self.selected = 0
-        self.children = {}
-        self.kidKeys = []
-        self.x = self.y = None
-        self.iconimages = {} # cache of PhotoImage instances for icons
-        self.menuList = menuList
-        self.menuVar = IntVar()
-        self.menuVar.set(0)
-        self._popupMenu = None
-        if self.menuList:
-            self._popupMenu = Menu(self.canvas, tearoff = 0)
-            for i in range(len(self.menuList)):
-                item = self.menuList[i]
-                self._popupMenu.add_radiobutton(
-                    label = item,
-                    variable = self.menuVar,
-                    value = i,
-                    indicatoron = 0,
-                    command = self.popupMenuCommand)
-
-    def destroy(self):
-        for key in self.kidKeys:
-            c = self.children[key]
-            del self.children[key]
-            c.destroy()
-        self.parent = None
-
-    def geticonimage(self, name):
-        try:
-            return self.iconimages[name]
-        except KeyError:
-            pass
-        file, ext = os.path.splitext(name)
-        ext = ext or ".gif"
-        fullname = os.path.join(ICONDIR, file + ext)
-        image = PhotoImage(master=self.canvas, file=fullname)
-        self.iconimages[name] = image
-        return image
-
-    def select(self, event=None):
-        if self.selected:
-            return
-        self.deselectall()
-        self.selected = 1
-        self.canvas.delete(self.image_id)
-        self.drawicon()
-        self.drawtext()
-        self.item.OnSelect()
-
-    def deselect(self, event=None):
-        if not self.selected:
-            return
-        self.selected = 0
-        self.canvas.delete(self.image_id)
-        self.drawicon()
-        self.drawtext()
-
-    def deselectall(self):
-        if self.parent:
-            self.parent.deselectall()
-        else:
-            self.deselecttree()
-
-    def deselecttree(self):
-        if self.selected:
-            self.deselect()
-        for key in self.kidKeys:
-            child = self.children[key]
-            child.deselecttree()
-
-    def flip(self, event=None):
-        if self.state == 'expanded':
-            self.collapse()
-        else:
-            self.expand()
-        self.item.OnDoubleClick()
-        return "break"
-
-    def selectAndPopupMenu(self, event=None):
-        self.select()
-        if self._popupMenu:
-            self._popupMenu.post(event.widget.winfo_pointerx(),
-                                 event.widget.winfo_pointery())
-            return "break"
-
-    def popupMenuCommand(self):
-        self.item.MenuCommand(self.menuList[self.menuVar.get()])
-
-    def expand(self, event=None):
-        if not self.item._IsExpandable():
-            return
-        if self.state != 'expanded':
-            self.state = 'expanded'
-            self.update()
-            self.view()
-
-    def collapse(self, event=None):
-        if self.state != 'collapsed':
-            self.state = 'collapsed'
-            self.update()
-
-    def view(self):
-        top = self.y - 2
-        bottom = self.lastvisiblechild().y + 17
-        height = bottom - top
-        visible_top = self.canvas.canvasy(0)
-        visible_height = self.canvas.winfo_height()
-        visible_bottom = self.canvas.canvasy(visible_height)
-        if visible_top <= top and bottom <= visible_bottom:
-            return
-        x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion'])
-        if top >= visible_top and height <= visible_height:
-            fraction = top + height - visible_height
-        else:
-            fraction = top
-        fraction = float(fraction) / y1
-        self.canvas.yview_moveto(fraction)
-
-    def lastvisiblechild(self):
-        if self.kidKeys and self.state == 'expanded':
-            return self.children[self.kidKeys[-1]].lastvisiblechild()
-        else:
-            return self
-
-    def update(self):
-        if self.parent:
-            self.parent.update()
-        else:
-            oldcursor = self.canvas['cursor']
-            self.canvas['cursor'] = "watch"
-            self.canvas.update()
-            self.canvas.delete(ALL)     # XXX could be more subtle
-            self.draw(7, 2)
-            x0, y0, x1, y1 = self.canvas.bbox(ALL)
-            self.canvas.configure(scrollregion=(0, 0, x1, y1))
-            self.canvas['cursor'] = oldcursor
-
-    def draw(self, x, y):
-        # XXX This hard-codes too many geometry constants!
-        self.x, self.y = x, y
-        self.drawicon()
-        self.drawtext()
-        if self.state != 'expanded':
-            return y+17
-        # draw children
-        #if not self.children:
-        #self.children = []
-        sublist = self.item._GetSubList()
-        if not sublist:
-            # _IsExpandable() was mistaken; that's allowed
-            return y+17
-        self.kidKeys = []
-        for item in sublist:
-            key = item.nodePath.id()
-            if self.children.has_key(key):
-                child = self.children[key]
-            else:
-                child = TreeNode(self.canvas, self, item, self.menuList)
-            self.children[key] = child
-        cx = x+20
-        cy = y+17
-        cylast = 0
-        for key in self.kidKeys:
-            child = self.children[key]
-            cylast = cy
-            self.canvas.create_line(x+9, cy+7, cx, cy+7, fill="gray50")
-            cy = child.draw(cx, cy)
-            if child.item._IsExpandable():
-                if child.state == 'expanded':
-                    iconname = "minusnode"
-                    callback = child.collapse
-                else:
-                    iconname = "plusnode"
-                    callback = child.expand
-                image = self.geticonimage(iconname)
-                id = self.canvas.create_image(x+9, cylast+7, image=image)
-                # XXX This leaks bindings until canvas is deleted:
-                self.canvas.tag_bind(id, "<1>", callback)
-                self.canvas.tag_bind(id, "<Double-1>", lambda x: None)
-        id = self.canvas.create_line(x+9, y+10, x+9, cylast+7,
-            ##stipple="gray50",     # XXX Seems broken in Tk 8.0.x
-            fill="gray50")
-        self.canvas.tag_lower(id) # XXX .lower(id) before Python 1.5.2
-        return cy
-
-    def drawicon(self):
-        if self.selected:
-            imagename = (self.item.GetSelectedIconName() or
-                         self.item.GetIconName() or
-                         "openfolder")
-        else:
-            imagename = self.item.GetIconName() or "folder"
-        image = self.geticonimage(imagename)
-        id = self.canvas.create_image(self.x, self.y, anchor="nw", image=image)
-        self.image_id = id
-        self.canvas.tag_bind(id, "<1>", self.select)
-        self.canvas.tag_bind(id, "<Double-1>", self.flip)
-        self.canvas.tag_bind(id, "<3>", self.selectAndPopupMenu)
-        
-    def drawtext(self):
-        textx = self.x+20-1
-        texty = self.y-1
-        labeltext = self.item.GetLabelText()
-        if labeltext:
-            id = self.canvas.create_text(textx, texty, anchor="nw",
-                                         text=labeltext)
-            self.canvas.tag_bind(id, "<1>", self.select)
-            self.canvas.tag_bind(id, "<Double-1>", self.flip)
-            self.canvas.tag_bind(id, "<3>", self.selectAndPopupMenu)
-            x0, y0, x1, y1 = self.canvas.bbox(id)
-            textx = max(x1, 200) + 10
-        text = self.item.GetText() or "<no text>"
-        try:
-            self.entry
-        except AttributeError:
-            pass
-        else:
-            self.edit_finish()
-        try:
-            label = self.label
-        except AttributeError:
-            # padding carefully selected (on Windows) to match Entry widget:
-            self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2)
-        if self.selected:
-            self.label.configure(fg="white", bg="darkblue")
-        else:
-            self.label.configure(fg="black", bg="white")
-        id = self.canvas.create_window(textx, texty,
-                                       anchor="nw", window=self.label)
-        self.label.bind("<1>", self.select_or_edit)
-        self.label.bind("<Double-1>", self.flip)
-        self.text_id = id
-
-    def select_or_edit(self, event=None):
-        if self.selected and self.item.IsEditable():
-            self.edit(event)
-        else:
-            self.select(event)
-
-    def edit(self, event=None):
-        self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0)
-        self.entry.insert(0, self.label['text'])
-        self.entry.selection_range(0, END)
-        self.entry.pack(ipadx=5)
-        self.entry.focus_set()
-        self.entry.bind("<Return>", self.edit_finish)
-        self.entry.bind("<Escape>", self.edit_cancel)
-
-    def edit_finish(self, event=None):
-        try:
-            entry = self.entry
-            del self.entry
-        except AttributeError:
-            return
-        text = entry.get()
-        entry.destroy()
-        if text and text != self.item.GetText():
-            self.item.SetText(text)
-        text = self.item.GetText()
-        self.label['text'] = text
-        self.drawtext()
-        self.canvas.focus_set()
-
-    def edit_cancel(self, event=None):
-        self.drawtext()
-        self.canvas.focus_set()
-
-
-class TreeItem:
-
-    """Abstract class representing tree items.
-
-    Methods should typically be overridden, otherwise a default action
-    is used.
-
-    """
-
-    def __init__(self):
-        """Constructor.  Do whatever you need to do."""
-
-    def GetText(self):
-        """Return text string to display."""
-
-    def GetLabelText(self):
-        """Return label text string to display in front of text (if any)."""
-
-    expandable = None
-
-    def _IsExpandable(self):
-        """Do not override!  Called by TreeNode."""
-        if self.expandable is None:
-            self.expandable = self.IsExpandable()
-        return self.expandable
-
-    def IsExpandable(self):
-        """Return whether there are subitems."""
-        return 1
-
-    def _GetSubList(self):
-        """Do not override!  Called by TreeNode."""
-        if not self.IsExpandable():
-            return []
-        sublist = self.GetSubList()
-        return sublist
-
-    def IsEditable(self):
-        """Return whether the item's text may be edited."""
-
-    def SetText(self, text):
-        """Change the item's text (if it is editable)."""
-
-    def GetIconName(self):
-        """Return name of icon to be displayed normally."""
-
-    def GetSelectedIconName(self):
-        """Return name of icon to be displayed when selected."""
-
-    def GetSubList(self):
-        """Return list of items forming sublist."""
-
-    def OnDoubleClick(self):
-        """Called on a double-click on the item."""
-
-    def OnSelect(self):
-        """Called when item selected."""
-
-
 class SceneGraphExplorer(Pmw.MegaWidget):
     "Graphical display of a scene graph"
     def __init__(self, root = render, parent = None, **kw):
@@ -386,7 +45,7 @@ class SceneGraphExplorer(Pmw.MegaWidget):
         self._treeItem = SceneGraphExplorerItem(self.root)
 
         self._node = TreeNode(self._canvas, None, self._treeItem,
-                              ['SGESelect'])
+                              ['Select Node'])
         self._node.expand()
 
         # Check keywords and initialise options based on input values.
@@ -451,7 +110,7 @@ class SceneGraphExplorerItem(TreeItem):
         return sublist
 
     def MenuCommand(self, command):
-        if (command == 'SGESelect'):
+        if (command == 'Select Node'):
             messenger.send('SGESelectNodePath', [self.nodePath])
 
 

+ 25 - 23
direct/src/tkwidgets/Tree.py

@@ -36,7 +36,8 @@ class TreeNode:
         self.item = item
         self.state = 'collapsed'
         self.selected = 0
-        self.children = []
+        self.children = {}
+        self.kidKeys = []
         self.x = self.y = None
         self.iconimages = {} # cache of PhotoImage instances for icons
         self.menuList = menuList
@@ -55,8 +56,9 @@ class TreeNode:
                     command = self.popupMenuCommand)
 
     def destroy(self):
-        for c in self.children[:]:
-            self.children.remove(c)
+        for key in self.kidKeys:
+            c = self.children[key]
+            del self.children[key]
             c.destroy()
         self.parent = None
 
@@ -99,7 +101,8 @@ class TreeNode:
     def deselecttree(self):
         if self.selected:
             self.deselect()
-        for child in self.children:
+        for key in self.kidKeys:
+            child = self.children[key]
             child.deselecttree()
 
     def flip(self, event=None):
@@ -121,7 +124,7 @@ class TreeNode:
         self.item.MenuCommand(self.menuList[self.menuVar.get()])
 
     def expand(self, event=None):
-        if not self.item._IsExpandable():
+        if not self.item.IsExpandable():
             return
         if self.state != 'expanded':
             self.state = 'expanded'
@@ -151,8 +154,8 @@ class TreeNode:
         self.canvas.yview_moveto(fraction)
 
     def lastvisiblechild(self):
-        if self.children and self.state == 'expanded':
-            return self.children[-1].lastvisiblechild()
+        if self.kidKeys and self.state == 'expanded':
+            return self.children[self.kidKeys[-1]].lastvisiblechild()
         else:
             return self
 
@@ -178,22 +181,29 @@ class TreeNode:
             return y+17
         # draw children
         #if not self.children:
+        #self.children = []
         sublist = self.item._GetSubList()
         if not sublist:
-            # _IsExpandable() was mistaken; that's allowed
+            # IsExpandable() was mistaken; that's allowed
             return y+17
-        #self.children = []
+        self.kidKeys = []
         for item in sublist:
-            child = TreeNode(self.canvas, self, item, self.menuList)
-            self.children.append(child)
+            key = item.nodePath.id()
+            if self.children.has_key(key):
+                child = self.children[key]
+            else:
+                child = TreeNode(self.canvas, self, item, self.menuList)
+            self.children[key] = child
+            self.kidKeys.append(key)
         cx = x+20
         cy = y+17
         cylast = 0
-        for child in self.children:
+        for key in self.kidKeys:
+            child = self.children[key]
             cylast = cy
             self.canvas.create_line(x+9, cy+7, cx, cy+7, fill="gray50")
             cy = child.draw(cx, cy)
-            if child.item._IsExpandable():
+            if child.item.IsExpandable():
                 if child.state == 'expanded':
                     iconname = "minusnode"
                     callback = child.collapse
@@ -312,14 +322,6 @@ class TreeItem:
     def GetLabelText(self):
         """Return label text string to display in front of text (if any)."""
 
-    expandable = None
-
-    def _IsExpandable(self):
-        """Do not override!  Called by TreeNode."""
-        if self.expandable is None:
-            self.expandable = self.IsExpandable()
-        return self.expandable
-
     def IsExpandable(self):
         """Return whether there are subitems."""
         return 1
@@ -329,8 +331,6 @@ class TreeItem:
         if not self.IsExpandable():
             return []
         sublist = self.GetSubList()
-        if not sublist:
-            self.expandable = 0
         return sublist
 
     def IsEditable(self):
@@ -354,3 +354,5 @@ class TreeItem:
     def OnSelect(self):
         """Called when item selected."""
 
+
+