Browse Source

*** empty log message ***

Joe Shochet 25 years ago
parent
commit
a747af315a

+ 1 - 0
direct/src/directtools/DirectSession.py

@@ -110,6 +110,7 @@ class DirectSession(PandaObject):
                             'mouse3', 'mouse3-up']
 
         if base.wantTk:
+            from TkGlobal import *
             self.panel = DirectSessionPanel(parent = tkroot)
 
     def enable(self):

+ 7 - 1
direct/src/extensions/NodePath-extensions.py

@@ -744,7 +744,13 @@
         else:
             return self.__lerp(functorFunc, time, blendType)
             
-
+    def place(self):
+        base.wantDIRECT = 1
+        base.wantTk = 1
+        from TkGlobal import *
+        from DirectSessionGlobal import *
+        import Placer
+        Placer.place(self)
 
 
 

+ 6 - 2
direct/src/fsm/FSM.py

@@ -49,8 +49,12 @@ class FSM(DirectObject):
         """__str__(self)
         Print out something useful about the fsm
         """
-        str = ("FSM " + self.getName() + ' in state "' +
-               self.getCurrentState().getName() + '"')
+        currentState = self.getCurrentState()
+        if currentState:
+            str = ("FSM " + self.getName() + ' in state "' +
+                   currentState.getName() + '"')
+        else:
+            str = ("FSM " + self.getName() + ' not in any state')
         return str
 
     def enterInitialState(self):

+ 5 - 8
direct/src/showbase/ShowBase.py

@@ -1,4 +1,9 @@
 
+# This module redefines the builtin import function with one
+# that prints out every import it does in a hierarchical form
+# Annoying and very noisy, but sometimes useful
+import VerboseImport
+
 from PandaModules import *
 from DirectNotifyGlobal import *
 from MessengerGlobal import *
@@ -160,7 +165,6 @@ class ShowBase:
 	self.physicsMgrAngular = 0
 
         self.createAudioManager()
-        self.createRootPanel()
         self.createStats()
 
         # Transition effects (fade, iris, etc)
@@ -220,13 +224,6 @@ class ShowBase:
         if self.wantSound:
             AudioManager.spawnUpdate()
 
-    def createRootPanel(self):
-        if self.wantTk:
-            from TkGlobal import *
-            self.tkroot = Pmw.initialise()
-        else:
-            self.tkroot = None
-
     def dataloop(self, state):
         # traverse the data graph.  This reads all the control
         # inputs (from the mouse and keyboard, for instance) and also

+ 5 - 1
direct/src/showbase/ShowBaseGlobal.py

@@ -14,7 +14,6 @@ __builtin__.camera = base.camera
 __builtin__.loader = base.loader
 __builtin__.ostream = Notify.out()
 __builtin__.run = base.run
-__builtin__.tkroot = base.tkroot
 __builtin__.taskMgr = base.taskMgr
 __builtin__.eventMgr = base.eventMgr
 __builtin__.messenger = base.messenger
@@ -24,4 +23,9 @@ __builtin__.directNotify = directNotify
 # Set direct notify categories now that we have config
 directNotify.setDconfigLevels()
 
+def inspect(anObject):
+    import Inspector
+    Inspector.inspect(anObject)
+
+__builtin__.inspect = inspect
 

+ 3 - 0
direct/src/showbase/TkGlobal.py

@@ -2,6 +2,9 @@
 from Tkinter import *
 import Pmw
 
+import __builtin__
+__builtin__.tkroot = Pmw.initialise()
+
 import Task
 
 def tkloop(self):

+ 25 - 0
direct/src/showbase/VerboseImport.py

@@ -0,0 +1,25 @@
+
+import sys
+
+# Save a pointer to the old import function
+oldimport = __import__
+
+# The current indent level, every time we import, this is incremented
+# so we can hierarchically see who imports who by the indentation
+indentLevel = 0
+
+# The new import function
+def newimport(*args, **kw):
+    global indentLevel
+    name = args[0]
+    # Only print the name if we have not imported this before
+    if not sys.modules.has_key(name):
+        print (" "*indentLevel + "import " + args[0])
+    indentLevel += 1
+    result = oldimport(*args, **kw)
+    indentLevel -= 1
+    return result
+
+# Replace the builtin import with our new import
+import __builtin__
+__builtin__.__import__ = newimport

+ 334 - 0
direct/src/tkpanels/Inspector.py

@@ -0,0 +1,334 @@
+### Inspectors allow you to visually browse through the members of various python objects.
+### To open an inspector, import this module, and execute inspector.inspect(anObject)
+### I start IDLE with this command line: idle.py -c "from inspector import inspect"
+### so that I can just type: inspect(anObject) any time.
+
+import string
+from Tkinter import *
+from TkGlobal import *
+
+
+### public API
+
+def inspect(anObject):
+    inspector = inspectorFor(anObject)
+    inspectorWindow = InspectorWindow(inspector)
+    inspectorWindow.open()
+
+### private
+
+def inspectorFor(anObject):
+    typeName = string.capitalize(type(anObject).__name__) + 'Type'
+    if _InspectorMap.has_key(typeName):
+        inspectorName = _InspectorMap[typeName]
+    else:
+        print "Can't find an inspector for " + typeName
+        inspectorName = 'Inspector'
+    inspector = eval(inspectorName + '(anObject)')
+    return inspector
+
+
+### initializing
+
+def initializeInspectorMap():
+    global _InspectorMap
+    notFinishedTypes = ['BufferType',  'EllipsisType',  'FrameType', 'TracebackType', 'XRangeType']
+
+    _InspectorMap = {
+        'Builtin_function_or_methodType' : 'FunctionInspector',
+        'BuiltinFunctionType' : 'FunctionInspector',
+        'BuiltinMethodType' : 'FunctionInspector',
+        'ClassType' : 'ClassInspector',
+        'CodeType' : 'CodeInspector',
+        'ComplexType' : 'Inspector',
+        'DictionaryType' : 'DictionaryInspector',
+        'DictType' : 'DictionaryInspector',
+        'FileType' : 'Inspector',
+        'FloatType' : 'Inspector', 
+        'FunctionType' : 'FunctionInspector',
+        'Instance methodType' : 'InstanceMethodInspector',
+        'InstanceType' : 'InstanceInspector',
+        'IntType' : 'Inspector',
+        'LambdaType' : 'Inspector',
+        'ListType' : 'SequenceInspector',
+        'LongType' : 'Inspector',
+        'MethodType' : 'FunctionInspector',
+        'ModuleType' : 'ModuleInspector',
+        'NoneType' : 'Inspector',
+        'SliceType' : 'SliceInspector',
+        'StringType' : 'SequenceInspector',
+        'TupleType' : 'SequenceInspector',
+        'TypeType' : 'Inspector',
+         'UnboundMethodType' : 'FunctionInspector'}
+
+    for each in notFinishedTypes:
+        _InspectorMap[each] = 'Inspector'
+
+    
+### Classes
+
+class Inspector:
+    def __init__(self, anObject):
+        self.object = anObject
+        self.initializePartsList()
+        self.initializePartNames()
+
+    def __str__(self):
+        return __name__ + '(' + str(self.object) + ')'
+
+    def initializePartsList(self):
+        self._partsList = []
+        keys = self.namedParts()
+        keys.sort()
+        for each in keys:
+            if not callable(eval('self.object.' + each)):
+                self._partsList.append(each)  
+
+    def initializePartNames(self):
+        self._partNames = ['self'] + map(lambda each: str(each), self._partsList)
+
+    def title(self):
+        "Subclasses may override."
+        return string.capitalize(self.objectType().__name__)
+        
+    def namedParts(self):
+        return dir(self.object)
+
+    def stringForPartNumber(self, partNumber):
+        return str(self.partNumber(partNumber))
+
+    def partNumber(self, partNumber):
+        if partNumber == 0:
+            return self.object
+        else:
+            part = self.privatePartNumber(partNumber)
+            return eval('self.object.' + part)
+
+    def inspectorFor(self, part):
+        return inspectorFor(part)
+
+    def privatePartNumber(self, partNumber):
+        return self._partsList[partNumber - 1]        
+
+    def partNames(self):
+        return self._partNames
+    
+    def objectType(self):
+        return type(self.object)
+
+###
+    
+class ModuleInspector(Inspector):
+    def namedParts(self):
+        return ['__dict__']
+
+class ClassInspector(Inspector):
+    def namedParts(self):
+        return ['__bases__',  '__dict__']
+
+    def title(self):
+        return self.object.__name__ + ' Class'
+
+class InstanceInspector(Inspector):
+    def title(self):
+        return self.object.__class__.__name__
+
+###
+    
+class FunctionInspector(Inspector):
+    def title(self):
+        return self.object.__name__ + "()"
+
+class InstanceMethodInspector(Inspector):
+    def title(self):
+        return str(self.object.im_class) + "." + self.object.__name__ + "()"
+
+class CodeInspector(Inspector):
+    def title(self):
+        return str(self.object)
+
+###
+
+class ComplexInspector(Inspector):
+    def namedParts(self):
+        return ['real', 'imag']
+
+###
+
+class DictionaryInspector(Inspector):
+
+    def initializePartsList(self):
+        Inspector.initializePartsList(self)
+        keys = self.object.keys()
+        keys.sort()
+        for each in keys:
+            self._partsList.append(each)
+
+    def partNumber(self, partNumber):
+        if partNumber == 0:
+            return self.object
+        key = self.privatePartNumber(partNumber)
+        return self.object[key]
+
+class SequenceInspector(Inspector):
+    def initializePartsList(self):
+        Inspector.initializePartsList(self)
+        for each in range(len(self.object)):
+            self._partsList.append(each)
+
+    def partNumber(self, partNumber):
+        if partNumber == 0:
+            return self.object
+        index = self.privatePartNumber(partNumber)
+        return self.object[index]
+    
+class SliceInspector(Inspector):
+    def namedParts(self):
+        return ['start', 'stop', 'step']
+
+
+### Initialization
+initializeInspectorMap()
+
+class InspectorWindow:
+    def __init__(self, inspector):
+        self.inspectors = [inspector]
+
+    def topInspector(self):
+        return self.inspectors[len(self.inspectors) - 1]
+
+    def inspectedObject(self):
+        return self.topInspector().object
+
+    def open(self):
+        self.top= Toplevel(tkroot)
+        self.createViews()
+        self.update()
+
+    #Private - view construction
+    def createViews(self):
+        self.createMenus()
+        self.createListWidget()
+        self.createTextWidget()
+        # self.top.resizable(0, 0)
+
+    def setTitle(self):
+        self.top.title('Inspecting: ' + self.topInspector().title())
+
+    def createListWidget(self):
+        frame = Frame(self.top)
+        frame.pack(side=LEFT, fill=BOTH, expand=1)
+        # frame.grid(row=0, column=0, sticky=N+W+S+E)
+        scrollbar = Scrollbar(frame, orient=VERTICAL)
+        listWidget = self.listWidget = Listbox(frame, yscrollcommand=scrollbar.set)
+        scrollbar.config(command = listWidget.yview)
+        scrollbar.pack(side=RIGHT, fill=Y)
+        listWidget.pack(side=LEFT, fill=BOTH, expand=1)
+        listWidget.bind('<ButtonRelease-1>',  self.listSelectionChanged)
+        listWidget.bind("<Double-Button-1>", self.popOrDive)
+
+    def createTextWidget(self):
+        self.textWidget = Text(self.top)
+        self.textWidget.pack(side=RIGHT, fill=BOTH, expand=1)
+        # self.textWidget.grid(row=0, column=1, columnspan=2, sticky=N+W+S+E)
+
+    def createMenus(self):
+        self.menuBar = Menu(self.top)
+        self.top.config(menu=self.menuBar)
+        inspectMenu = Menu(self.menuBar)
+        self.menuBar.add_cascade(label='Inspect', menu=inspectMenu)
+        inspectMenu.add_command(label='Pop', command=self.pop)
+        inspectMenu.add_command(label='Dive', command=self.dive)
+        inspectMenu.add_command(label='Inspect', command=self.inspect)
+        helpMenu = Menu(self.menuBar)
+        self.menuBar.add_cascade(label='Help', menu=helpMenu)
+        helpMenu.add_command(label='Instructions', command=self.showHelp)
+
+    def fillList(self):
+        self.listWidget.delete(0, END)
+        for each in self.topInspector().partNames():
+            self.listWidget.insert(END, each)
+        self.listWidget.select_clear(0)
+
+    # Event Handling
+    def listSelectionChanged(self, event):
+        partNumber = self.selectedIndex()
+        if partNumber == None:
+            #string = ''
+            partNumber = 0
+        #else:
+        string = self.topInspector().stringForPartNumber(partNumber)
+        self.textWidget.delete('1.0', END)
+        self.textWidget.insert(END, string)
+
+    def popOrDive(self, event):
+        '''The list has been double-clicked. If the selection is 'self' then pop,
+        otherwise dive into the selected part'''
+        if self.selectedIndex() == 0:
+            self.pop()
+        else:
+            self.dive()
+
+    # Menu Events
+    def inspect(self):
+        inspector = self.inspectorForSelectedPart()
+        if inspector == None:
+            return
+        InspectorWindow(inspector).open()        
+        
+    def pop(self):
+        if len(self.inspectors) > 1:
+            self.inspectors = self.inspectors[ : -1]
+            self.update()
+
+    def dive(self):
+        inspector = self.inspectorForSelectedPart()
+        if inspector == None:
+            return
+        self.inspectors.append(inspector)
+        self.update()
+
+    def update(self):
+        self.setTitle()
+        self.fillList()
+        self.listSelectionChanged(None)
+
+    def showHelp(self):
+        help = Toplevel(tkroot)
+        help.title("Inspector Help")
+        frame = Frame(help)
+        frame.pack()
+        text = Label(frame, text="Double click an instance variable to dive down\nDouble click self to pop back up")
+        text.pack()
+
+    #Private
+    def selectedIndex(self):
+        indicies = map(int, self.listWidget.curselection())
+        if len(indicies) == 0:
+            return None
+        partNumber = indicies[0]
+        return partNumber
+
+    def inspectorForSelectedPart(self):
+        partNumber = self.selectedIndex()
+        if partNumber == None:
+            return None
+        part = self.topInspector().partNumber(partNumber)
+
+        # If this is a node path, pop up a scene graph explorer
+        from PandaModules import *
+        import FSM
+        if isinstance(part, NodePath):
+            # part.place()
+            top = Toplevel(tkroot)
+            import SceneGraphExplorer
+            sge = SceneGraphExplorer.SceneGraphExplorer(top, nodePath = part,
+                                                        scrolledCanvas_hull_width = 200,
+                                                        scrolledCanvas_hull_height = 400)
+            sge.pack(fill = BOTH, expand = 0)
+        elif isinstance(part, FSM.FSM):
+            import FSMInspector
+            fsmi = FSMInspector.FSMInspector(part)
+
+        return self.topInspector().inspectorFor(part)
+