From 6ef606cbc8e92093588c481418be3a55332f955a Mon Sep 17 00:00:00 2001 From: Mark Mine Date: Sat, 11 Nov 2000 02:07:59 +0000 Subject: [PATCH] *** empty log message *** --- direct/src/tkwidgets/SceneGraphExplorer.py | 345 +-------------------- direct/src/tkwidgets/Tree.py | 48 +-- 2 files changed, 27 insertions(+), 366 deletions(-) diff --git a/direct/src/tkwidgets/SceneGraphExplorer.py b/direct/src/tkwidgets/SceneGraphExplorer.py index 99aebbb3cf..e23eea0296 100644 --- a/direct/src/tkwidgets/SceneGraphExplorer.py +++ b/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, "", 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, "", 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, "", 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 "" - 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("", 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("", self.edit_finish) - self.entry.bind("", 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]) diff --git a/direct/src/tkwidgets/Tree.py b/direct/src/tkwidgets/Tree.py index 738d80cfdf..83bd33cd61 100644 --- a/direct/src/tkwidgets/Tree.py +++ b/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.""" + +