浏览代码

direct: Reduce dependence on builtins, satisfy mypy a bit more

rdb 2 年之前
父节点
当前提交
b6eee1045a

文件差异内容过多而无法显示
+ 204 - 180
direct/src/directtools/DirectManipulation.py


+ 59 - 39
direct/src/directtools/DirectSession.py

@@ -5,6 +5,7 @@ from panda3d.core import (
     ConfigVariableBool,
     ConfigVariableBool,
     ConfigVariableString,
     ConfigVariableString,
     CSDefault,
     CSDefault,
+    GraphicsWindow,
     NodePath,
     NodePath,
     Point3,
     Point3,
     TextNode,
     TextNode,
@@ -35,19 +36,33 @@ from direct.gui import OnscreenText
 from direct.interval.IntervalGlobal import Func, Sequence
 from direct.interval.IntervalGlobal import Func, Sequence
 from direct.task.TaskManagerGlobal import taskMgr
 from direct.task.TaskManagerGlobal import taskMgr
 from direct.showbase.MessengerGlobal import messenger
 from direct.showbase.MessengerGlobal import messenger
+from direct.showbase import ShowBaseGlobal
+from direct.showbase.ShowBaseGlobal import ShowBase, hidden
 
 
+import builtins
+
+base: ShowBase
 
 
 class DirectSession(DirectObject):
 class DirectSession(DirectObject):
 
 
     # post this to the bboard to make sure DIRECT doesn't turn on
     # post this to the bboard to make sure DIRECT doesn't turn on
     DIRECTdisablePost = 'disableDIRECT'
     DIRECTdisablePost = 'disableDIRECT'
 
 
+    cam: NodePath
+    camera: NodePath
+    oobeCamera: NodePath
+
     def __init__(self):
     def __init__(self):
         # Establish a global pointer to the direct object early on
         # Establish a global pointer to the direct object early on
         # so dependant classes can access it in their code
         # so dependant classes can access it in their code
-        __builtins__["direct"] = base.direct = self
+        global direct, base
+        base = ShowBaseGlobal.base
+        base.direct = self
+        setattr(builtins, 'direct', self)
+        ShowBaseGlobal.direct = self
+
         # These come early since they are used later on
         # These come early since they are used later on
-        self.group = render.attachNewNode('DIRECT')
+        self.group = base.render.attachNewNode('DIRECT')
         self.font = TextNode.getDefaultFont()
         self.font = TextNode.getDefaultFont()
         self.fEnabled = 0
         self.fEnabled = 0
         self.fEnabledLight = 0
         self.fEnabledLight = 0
@@ -57,7 +72,7 @@ class DirectSession(DirectObject):
         self.drList = DisplayRegionList()
         self.drList = DisplayRegionList()
         self.iRayList = [x.iRay for x in self.drList]
         self.iRayList = [x.iRay for x in self.drList]
         self.dr = self.drList[0]
         self.dr = self.drList[0]
-        self.win = base.win
+        self.win: GraphicsWindow = base.win
         self.camera = base.camera
         self.camera = base.camera
         self.cam = base.cam
         self.cam = base.cam
         self.camNode = base.camNode
         self.camNode = base.camNode
@@ -70,7 +85,7 @@ class DirectSession(DirectObject):
         self.useObjectHandles()
         self.useObjectHandles()
         self.grid = DirectGrid()
         self.grid = DirectGrid()
         self.grid.disable()
         self.grid.disable()
-        self.lights = DirectLights(base.direct.group)
+        self.lights = DirectLights(self.group)
         # Create some default lights
         # Create some default lights
         self.lights.createDefaultLights()
         self.lights.createDefaultLights()
         # But turn them off
         # But turn them off
@@ -308,13 +323,16 @@ class DirectSession(DirectObject):
         if base.wantTk:
         if base.wantTk:
             from direct.tkpanels import DirectSessionPanel
             from direct.tkpanels import DirectSessionPanel
             self.panel = DirectSessionPanel.DirectSessionPanel(parent = base.tkRoot)
             self.panel = DirectSessionPanel.DirectSessionPanel(parent = base.tkRoot)
-        try:
+
+        clusterMode: str
+        if hasattr(builtins, 'clusterMode'):
             # Has the clusterMode been set externally (i.e. via the
             # Has the clusterMode been set externally (i.e. via the
             # bootstrap application?
             # bootstrap application?
-            self.clusterMode = clusterMode
-        except NameError:
+            clusterMode = builtins.clusterMode
+        else:
             # Has the clusterMode been set via a config variable?
             # Has the clusterMode been set via a config variable?
-            self.clusterMode = ConfigVariableString("cluster-mode", '').value
+            clusterMode = ConfigVariableString("cluster-mode", '').value
+        self.clusterMode = clusterMode
 
 
         if self.clusterMode == 'client':
         if self.clusterMode == 'client':
             from direct.cluster.ClusterClient import createClusterClient
             from direct.cluster.ClusterClient import createClusterClient
@@ -325,7 +343,7 @@ class DirectSession(DirectObject):
         else:
         else:
             from direct.cluster.ClusterClient import DummyClusterClient
             from direct.cluster.ClusterClient import DummyClusterClient
             self.cluster = DummyClusterClient()
             self.cluster = DummyClusterClient()
-        __builtins__['cluster'] = self.cluster
+        setattr(builtins, 'cluster', self.cluster)
 
 
     def addPassThroughKey(self,key):
     def addPassThroughKey(self,key):
 
 
@@ -412,10 +430,10 @@ class DirectSession(DirectObject):
 
 
         if self.oobeMode:
         if self.oobeMode:
             # Position a target point to lerp the oobe camera to
             # Position a target point to lerp the oobe camera to
-            base.direct.cameraControl.camManipRef.setPosHpr(self.trueCamera, 0, 0, 0, 0, 0, 0)
+            self.cameraControl.camManipRef.setPosHpr(self.trueCamera, 0, 0, 0, 0, 0, 0)
             ival = self.oobeCamera.posHprInterval(
             ival = self.oobeCamera.posHprInterval(
                 2.0, pos = Point3(0), hpr = Vec3(0),
                 2.0, pos = Point3(0), hpr = Vec3(0),
-                other = base.direct.cameraControl.camManipRef,
+                other = self.cameraControl.camManipRef,
                 blendType = 'easeInOut')
                 blendType = 'easeInOut')
             ival = Sequence(ival, Func(self.endOOBE), name = 'oobeTransition')
             ival = Sequence(ival, Func(self.endOOBE), name = 'oobeTransition')
             ival.start()
             ival.start()
@@ -432,20 +450,20 @@ class DirectSession(DirectObject):
             # Put camera under new oobe camera
             # Put camera under new oobe camera
             self.cam.reparentTo(self.oobeCamera)
             self.cam.reparentTo(self.oobeCamera)
             # Position a target point to lerp the oobe camera to
             # Position a target point to lerp the oobe camera to
-            base.direct.cameraControl.camManipRef.setPos(
+            self.cameraControl.camManipRef.setPos(
                 self.trueCamera, Vec3(-2, -20, 5))
                 self.trueCamera, Vec3(-2, -20, 5))
-            base.direct.cameraControl.camManipRef.lookAt(self.trueCamera)
+            self.cameraControl.camManipRef.lookAt(self.trueCamera)
             ival = self.oobeCamera.posHprInterval(
             ival = self.oobeCamera.posHprInterval(
                 2.0, pos = Point3(0), hpr = Vec3(0),
                 2.0, pos = Point3(0), hpr = Vec3(0),
-                other = base.direct.cameraControl.camManipRef,
+                other = self.cameraControl.camManipRef,
                 blendType = 'easeInOut')
                 blendType = 'easeInOut')
             ival = Sequence(ival, Func(self.beginOOBE), name = 'oobeTransition')
             ival = Sequence(ival, Func(self.beginOOBE), name = 'oobeTransition')
             ival.start()
             ival.start()
 
 
     def beginOOBE(self):
     def beginOOBE(self):
         # Make sure we've reached our final destination
         # Make sure we've reached our final destination
-        self.oobeCamera.setPosHpr(base.direct.cameraControl.camManipRef, 0, 0, 0, 0, 0, 0)
-        base.direct.camera = self.oobeCamera
+        self.oobeCamera.setPosHpr(self.cameraControl.camManipRef, 0, 0, 0, 0, 0, 0)
+        self.camera = self.oobeCamera
         self.oobeMode = 1
         self.oobeMode = 1
 
 
     def endOOBE(self):
     def endOOBE(self):
@@ -453,7 +471,7 @@ class DirectSession(DirectObject):
         self.oobeCamera.setPosHpr(self.trueCamera, 0, 0, 0, 0, 0, 0)
         self.oobeCamera.setPosHpr(self.trueCamera, 0, 0, 0, 0, 0, 0)
         # Disable OOBE mode.
         # Disable OOBE mode.
         self.cam.reparentTo(self.trueCamera)
         self.cam.reparentTo(self.trueCamera)
-        base.direct.camera = self.trueCamera
+        self.camera = self.trueCamera
         # Get rid of ancillary node paths
         # Get rid of ancillary node paths
         self.oobeVis.reparentTo(hidden)
         self.oobeVis.reparentTo(hidden)
         self.oobeCamera.reparentTo(hidden)
         self.oobeCamera.reparentTo(hidden)
@@ -501,7 +519,7 @@ class DirectSession(DirectObject):
     def inputHandler(self, input):
     def inputHandler(self, input):
         if not hasattr(self, 'oobeMode') or self.oobeMode == 0:
         if not hasattr(self, 'oobeMode') or self.oobeMode == 0:
             # [gjeon] change current camera dr, iRay, mouseWatcher accordingly to support multiple windows
             # [gjeon] change current camera dr, iRay, mouseWatcher accordingly to support multiple windows
-            if base.direct.manipulationControl.fMultiView:
+            if self.manipulationControl.fMultiView:
                 # handling orphan events
                 # handling orphan events
                 if self.fMouse1 and 'mouse1' not in input or\
                 if self.fMouse1 and 'mouse1' not in input or\
                    self.fMouse2 and 'mouse2' not in input or\
                    self.fMouse2 and 'mouse2' not in input or\
@@ -518,7 +536,7 @@ class DirectSession(DirectObject):
                     return
                     return
 
 
                 if (self.fMouse1 or self.fMouse2 or self.fMouse3) and\
                 if (self.fMouse1 or self.fMouse2 or self.fMouse3) and\
-                   input[4:7] != base.direct.camera.getName()[:3] and\
+                   input[4:7] != self.camera.getName()[:3] and\
                    input.endswith('-up'):
                    input.endswith('-up'):
                     # to handle orphan events
                     # to handle orphan events
                     return
                     return
@@ -551,14 +569,14 @@ class DirectSession(DirectObject):
                     self.cam = NodePath(winCtrl.camNode)
                     self.cam = NodePath(winCtrl.camNode)
                     self.camNode = winCtrl.camNode
                     self.camNode = winCtrl.camNode
                     if hasattr(winCtrl, 'grid'):
                     if hasattr(winCtrl, 'grid'):
-                        base.direct.grid = winCtrl.grid
-                    base.direct.dr = base.direct.drList[base.camList.index(NodePath(winCtrl.camNode))]
-                    base.direct.iRay = base.direct.dr.iRay
+                        self.grid = winCtrl.grid
+                    self.dr = self.drList[base.camList.index(NodePath(winCtrl.camNode))]
+                    self.iRay = self.dr.iRay
                     base.mouseWatcher = winCtrl.mouseWatcher
                     base.mouseWatcher = winCtrl.mouseWatcher
                     base.mouseWatcherNode = winCtrl.mouseWatcher.node()
                     base.mouseWatcherNode = winCtrl.mouseWatcher.node()
-                    base.direct.dr.mouseUpdate()
+                    self.dr.mouseUpdate()
                     DG.LE_showInOneCam(self.selectedNPReadout, self.camera.getName())
                     DG.LE_showInOneCam(self.selectedNPReadout, self.camera.getName())
-                    base.direct.widget = base.direct.manipulationControl.widgetList[base.camList.index(NodePath(winCtrl.camNode))]
+                    self.widget = self.manipulationControl.widgetList[base.camList.index(NodePath(winCtrl.camNode))]
 
 
                 input = input[8:] # get rid of camera prefix
                 input = input[8:] # get rid of camera prefix
                 if self.fAlt and 'alt' not in input and not input.endswith('-up'):
                 if self.fAlt and 'alt' not in input and not input.endswith('-up'):
@@ -683,20 +701,18 @@ class DirectSession(DirectObject):
         if not taskMgr.hasTaskNamed('resizeObjectHandles'):
         if not taskMgr.hasTaskNamed('resizeObjectHandles'):
             dnp = self.selected.last
             dnp = self.selected.last
             if dnp:
             if dnp:
-                direct = base.direct
-
                 if self.manipulationControl.fMultiView:
                 if self.manipulationControl.fMultiView:
                     for i in range(3):
                     for i in range(3):
-                        sf = 30.0 * direct.drList[i].orthoFactor
+                        sf = 30.0 * self.drList[i].orthoFactor
                         self.manipulationControl.widgetList[i].setDirectScalingFactor(sf)
                         self.manipulationControl.widgetList[i].setDirectScalingFactor(sf)
 
 
                     nodeCamDist = Vec3(dnp.getPos(base.camList[3])).length()
                     nodeCamDist = Vec3(dnp.getPos(base.camList[3])).length()
-                    sf = 0.075 * nodeCamDist * math.tan(deg2Rad(direct.drList[3].fovV))
+                    sf = 0.075 * nodeCamDist * math.tan(deg2Rad(self.drList[3].fovV))
                     self.manipulationControl.widgetList[3].setDirectScalingFactor(sf)
                     self.manipulationControl.widgetList[3].setDirectScalingFactor(sf)
 
 
                 else:
                 else:
-                    nodeCamDist = Vec3(dnp.getPos(direct.camera)).length()
-                    sf = 0.075 * nodeCamDist * math.tan(deg2Rad(direct.drList.getCurrentDr().fovV))
+                    nodeCamDist = Vec3(dnp.getPos(self.camera)).length()
+                    sf = 0.075 * nodeCamDist * math.tan(deg2Rad(self.drList.getCurrentDr().fovV))
                     self.widget.setDirectScalingFactor(sf)
                     self.widget.setDirectScalingFactor(sf)
         return Task.cont
         return Task.cont
 
 
@@ -755,7 +771,7 @@ class DirectSession(DirectObject):
             messenger.send('DIRECT_selectedNodePath_fMulti_fTag_fLEPane', [dnp, fMultiSelect, fSelectTag, fLEPane])
             messenger.send('DIRECT_selectedNodePath_fMulti_fTag_fLEPane', [dnp, fMultiSelect, fSelectTag, fLEPane])
 
 
     def followSelectedNodePathTask(self, state):
     def followSelectedNodePathTask(self, state):
-        mCoa2Render = state.dnp.mCoa2Dnp * state.dnp.getMat(render)
+        mCoa2Render = state.dnp.mCoa2Dnp * state.dnp.getMat(base.render)
         decomposeMatrix(mCoa2Render,
         decomposeMatrix(mCoa2Render,
                         self.scale, self.hpr, self.pos,
                         self.scale, self.hpr, self.pos,
                         CSDefault)
                         CSDefault)
@@ -874,7 +890,7 @@ class DirectSession(DirectObject):
         if nodePath == 'None Given':
         if nodePath == 'None Given':
             # If nothing specified, try selected node path
             # If nothing specified, try selected node path
             nodePath = self.selected.last
             nodePath = self.selected.last
-        base.direct.select(nodePath)
+        self.select(nodePath)
 
 
         def fitTask(state, self = self):
         def fitTask(state, self = self):
             self.cameraControl.fitOnWidget()
             self.cameraControl.fitOnWidget()
@@ -1061,7 +1077,7 @@ class DirectSession(DirectObject):
 
 
     def useObjectHandles(self):
     def useObjectHandles(self):
         self.widget = self.manipulationControl.objectHandles
         self.widget = self.manipulationControl.objectHandles
-        self.widget.reparentTo(base.direct.group)
+        self.widget.reparentTo(self.group)
 
 
     def hideSelectedNPReadout(self):
     def hideSelectedNPReadout(self):
         self.selectedNPReadout.reparentTo(hidden)
         self.selectedNPReadout.reparentTo(hidden)
@@ -1167,14 +1183,14 @@ class DisplayRegionContext(DirectObject):
             self.camLens.setFov(hfov, vfov)
             self.camLens.setFov(hfov, vfov)
 
 
     def getWidth(self):
     def getWidth(self):
-        prop = base.direct.win.getProperties()
+        prop = ShowBaseGlobal.direct.win.getProperties()
         if prop.hasSize():
         if prop.hasSize():
             return prop.getXSize()
             return prop.getXSize()
         else:
         else:
             return 640
             return 640
 
 
     def getHeight(self):
     def getHeight(self):
-        prop = base.direct.win.getProperties()
+        prop = ShowBaseGlobal.direct.win.getProperties()
         if prop.hasSize():
         if prop.hasSize():
             return prop.getYSize()
             return prop.getYSize()
         else:
         else:
@@ -1208,9 +1224,10 @@ class DisplayRegionContext(DirectObject):
 
 
         # Values for this frame
         # Values for this frame
         # This ranges from -1 to 1
         # This ranges from -1 to 1
-        if base.mouseWatcherNode and base.mouseWatcherNode.hasMouse():
-            self.mouseX = base.mouseWatcherNode.getMouseX()
-            self.mouseY = base.mouseWatcherNode.getMouseY()
+        mouseWatcherNode = base.mouseWatcherNode
+        if mouseWatcherNode and mouseWatcherNode.hasMouse():
+            self.mouseX = mouseWatcherNode.getMouseX()
+            self.mouseY = mouseWatcherNode.getMouseY()
             self.mouseX = (self.mouseX-self.originX)*self.scaleX
             self.mouseX = (self.mouseX-self.originX)*self.scaleX
             self.mouseY = (self.mouseY-self.originY)*self.scaleY
             self.mouseY = (self.mouseY-self.originY)*self.scaleY
         # Delta percent of window the mouse moved
         # Delta percent of window the mouse moved
@@ -1262,6 +1279,9 @@ class DisplayRegionList(DirectObject):
     def __len__(self):
     def __len__(self):
         return len(self.displayRegionList)
         return len(self.displayRegionList)
 
 
+    def __iter__(self):
+        return iter(self.displayRegionList)
+
     def updateContext(self):
     def updateContext(self):
         self.contextTask(None)
         self.contextTask(None)
 
 
@@ -1296,7 +1316,7 @@ class DisplayRegionList(DirectObject):
 
 
     def getCurrentDr(self):
     def getCurrentDr(self):
         if not self.tryToGetCurrentDr:
         if not self.tryToGetCurrentDr:
-            return base.direct.dr
+            return ShowBaseGlobal.direct.dr
         for dr in self.displayRegionList:
         for dr in self.displayRegionList:
             if (dr.mouseX >= -1.0 and dr.mouseX <= 1.0 and
             if (dr.mouseX >= -1.0 and dr.mouseX <= 1.0 and
                 dr.mouseY >= -1.0 and dr.mouseY <= 1.0):
                 dr.mouseY >= -1.0 and dr.mouseY <= 1.0):

+ 28 - 27
direct/src/leveleditor/LevelEditorUIBase.py

@@ -7,6 +7,7 @@ from direct.wxwidgets.WxPandaShell import WxPandaShell
 from direct.wxwidgets.WxSlider import WxSlider
 from direct.wxwidgets.WxSlider import WxSlider
 from direct.directtools.DirectSelection import SelectionRay
 from direct.directtools.DirectSelection import SelectionRay
 from direct.showbase.MessengerGlobal import messenger
 from direct.showbase.MessengerGlobal import messenger
+from direct.showbase import ShowBaseGlobal
 
 
 #from ViewPort import *
 #from ViewPort import *
 from . import ObjectGlobals as OG
 from . import ObjectGlobals as OG
@@ -88,7 +89,7 @@ class PandaTextDropTarget(wx.TextDropTarget):
             np = NodePath('temp')
             np = NodePath('temp')
             np.setPos(self.view.camera, hitPt)
             np.setPos(self.view.camera, hitPt)
 
 
-            if base.direct.manipulationControl.fGridSnap:
+            if ShowBaseGlobal.direct.manipulationControl.fGridSnap:
                 snappedPos = self.view.grid.computeSnapPoint(np.getPos())
                 snappedPos = self.view.grid.computeSnapPoint(np.getPos())
                 np.setPos(snappedPos)
                 np.setPos(snappedPos)
 
 
@@ -98,10 +99,10 @@ class PandaTextDropTarget(wx.TextDropTarget):
 
 
             # transform newobj to cursor position
             # transform newobj to cursor position
             obj = self.editor.objectMgr.findObjectByNodePath(newobj)
             obj = self.editor.objectMgr.findObjectByNodePath(newobj)
-            action = ActionTransformObj(self.editor, obj[OG.OBJ_UID], Mat4(np.getMat()))
-            self.editor.actionMgr.push(action)
+            action2 = ActionTransformObj(self.editor, obj[OG.OBJ_UID], Mat4(np.getMat()))
+            self.editor.actionMgr.push(action2)
             np.remove()
             np.remove()
-            action()
+            action2()
         iRay.collisionNodePath.removeNode()
         iRay.collisionNodePath.removeNode()
         del iRay
         del iRay
 
 
@@ -250,13 +251,13 @@ class LevelEditorUIBase(WxPandaShell):
         WxPandaShell.createMenu(self)
         WxPandaShell.createMenu(self)
 
 
     def onGraphEditor(self, e):
     def onGraphEditor(self, e):
-        if base.direct.selected.last is None:
+        if ShowBaseGlobal.direct.selected.last is None:
             dlg = wx.MessageDialog(None, 'Please select a object first.', 'NOTICE', wx.OK)
             dlg = wx.MessageDialog(None, 'Please select a object first.', 'NOTICE', wx.OK)
             dlg.ShowModal()
             dlg.ShowModal()
             dlg.Destroy()
             dlg.Destroy()
             self.graphEditorMenuItem.Check(False)
             self.graphEditorMenuItem.Check(False)
         else:
         else:
-            currentObj = self.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
+            currentObj = self.editor.objectMgr.findObjectByNodePath(ShowBaseGlobal.direct.selected.last)
             self.graphEditorUI = GraphEditorUI(self, self.editor, currentObj)
             self.graphEditorUI = GraphEditorUI(self, self.editor, currentObj)
             self.graphEditorUI.Show()
             self.graphEditorUI.Show()
             self.graphEditorMenuItem.Check(True)
             self.graphEditorMenuItem.Check(True)
@@ -298,7 +299,7 @@ class LevelEditorUIBase(WxPandaShell):
                     degreeUI = CurveDegreeUI(self, -1, 'Curve Degree')
                     degreeUI = CurveDegreeUI(self, -1, 'Curve Degree')
                     degreeUI.ShowModal()
                     degreeUI.ShowModal()
                     degreeUI.Destroy()
                     degreeUI.Destroy()
-                    base.direct.manipulationControl.disableManipulation()
+                    ShowBaseGlobal.direct.manipulationControl.disableManipulation()
                     self.editCurveMenuItem.Check(False)
                     self.editCurveMenuItem.Check(False)
 
 
     def onEditCurve(self, e):
     def onEditCurve(self, e):
@@ -313,15 +314,15 @@ class LevelEditorUIBase(WxPandaShell):
                 self.createCurveMenuItem.Check(False)
                 self.createCurveMenuItem.Check(False)
                 self.onEditCurve(None)
                 self.onEditCurve(None)
             else:
             else:
-                if base.direct.selected.last is None:
+                if ShowBaseGlobal.direct.selected.last is None:
                     dlg = wx.MessageDialog(None, 'Please select a curve first.', 'NOTICE', wx.OK)
                     dlg = wx.MessageDialog(None, 'Please select a curve first.', 'NOTICE', wx.OK)
                     dlg.ShowModal()
                     dlg.ShowModal()
                     dlg.Destroy()
                     dlg.Destroy()
                     self.editCurveMenuItem.Check(False)
                     self.editCurveMenuItem.Check(False)
-                if base.direct.selected.last is not None:
-                    base.direct.manipulationControl.enableManipulation()
+                if ShowBaseGlobal.direct.selected.last is not None:
+                    ShowBaseGlobal.direct.manipulationControl.enableManipulation()
                     self.createCurveMenuItem.Check(False)
                     self.createCurveMenuItem.Check(False)
-                    self.curveObj = self.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
+                    self.curveObj = self.editor.objectMgr.findObjectByNodePath(ShowBaseGlobal.direct.selected.last)
                     if self.curveObj[OG.OBJ_DEF].name == '__Curve__':
                     if self.curveObj[OG.OBJ_DEF].name == '__Curve__':
                         self.editor.mode = self.editor.EDIT_CURVE_MODE
                         self.editor.mode = self.editor.EDIT_CURVE_MODE
                         self.editor.updateStatusReadout('Please press ENTER to end the curve editing.')
                         self.editor.updateStatusReadout('Please press ENTER to end the curve editing.')
@@ -339,8 +340,8 @@ class LevelEditorUIBase(WxPandaShell):
 
 
     def updateMenu(self):
     def updateMenu(self):
         hotKeyDict = {}
         hotKeyDict = {}
-        for hotKey in base.direct.hotKeyMap.keys():
-            desc = base.direct.hotKeyMap[hotKey]
+        for hotKey in ShowBaseGlobal.direct.hotKeyMap.keys():
+            desc = ShowBaseGlobal.direct.hotKeyMap[hotKey]
             hotKeyDict[desc[1]] = hotKey
             hotKeyDict[desc[1]] = hotKey
 
 
         for id in self.MENU_TEXTS.keys():
         for id in self.MENU_TEXTS.keys():
@@ -401,16 +402,16 @@ class LevelEditorUIBase(WxPandaShell):
         else:
         else:
             mpos = evt.GetPosition()
             mpos = evt.GetPosition()
 
 
-        base.direct.fMouse3 = 0
+        ShowBaseGlobal.direct.fMouse3 = 0
         self.PopupMenu(self.contextMenu, mpos)
         self.PopupMenu(self.contextMenu, mpos)
 
 
     def onKeyDownEvent(self, evt):
     def onKeyDownEvent(self, evt):
         if evt.GetKeyCode() == wx.WXK_ALT:
         if evt.GetKeyCode() == wx.WXK_ALT:
-            base.direct.fAlt = 1
+            ShowBaseGlobal.direct.fAlt = 1
         elif evt.GetKeyCode() == wx.WXK_CONTROL:
         elif evt.GetKeyCode() == wx.WXK_CONTROL:
-            base.direct.fControl = 1
+            ShowBaseGlobal.direct.fControl = 1
         elif evt.GetKeyCode() == wx.WXK_SHIFT:
         elif evt.GetKeyCode() == wx.WXK_SHIFT:
-            base.direct.fShift = 1
+            ShowBaseGlobal.direct.fShift = 1
         elif evt.GetKeyCode() == wx.WXK_UP:
         elif evt.GetKeyCode() == wx.WXK_UP:
             messenger.send('arrow_up')
             messenger.send('arrow_up')
         elif evt.GetKeyCode() == wx.WXK_DOWN:
         elif evt.GetKeyCode() == wx.WXK_DOWN:
@@ -428,11 +429,11 @@ class LevelEditorUIBase(WxPandaShell):
 
 
     def onKeyUpEvent(self, evt):
     def onKeyUpEvent(self, evt):
         if evt.GetKeyCode() == wx.WXK_ALT:
         if evt.GetKeyCode() == wx.WXK_ALT:
-            base.direct.fAlt = 0
+            ShowBaseGlobal.direct.fAlt = 0
         elif evt.GetKeyCode() == wx.WXK_CONTROL:
         elif evt.GetKeyCode() == wx.WXK_CONTROL:
-            base.direct.fControl = 0
+            ShowBaseGlobal.direct.fControl = 0
         elif evt.GetKeyCode() == wx.WXK_SHIFT:
         elif evt.GetKeyCode() == wx.WXK_SHIFT:
-            base.direct.fShift = 0
+            ShowBaseGlobal.direct.fShift = 0
         elif evt.GetKeyCode() == wx.WXK_UP:
         elif evt.GetKeyCode() == wx.WXK_UP:
             messenger.send('arrow_up-up')
             messenger.send('arrow_up-up')
         elif evt.GetKeyCode() == wx.WXK_DOWN:
         elif evt.GetKeyCode() == wx.WXK_DOWN:
@@ -473,8 +474,8 @@ class LevelEditorUIBase(WxPandaShell):
                 input = 'control-%s'%chr(evt.GetKeyCode())
                 input = 'control-%s'%chr(evt.GetKeyCode())
             elif evt.GetKeyCode() < 256:
             elif evt.GetKeyCode() < 256:
                 input = chr(evt.GetKeyCode())
                 input = chr(evt.GetKeyCode())
-        if input in base.direct.hotKeyMap.keys():
-            keyDesc = base.direct.hotKeyMap[input]
+        if input in ShowBaseGlobal.direct.hotKeyMap.keys():
+            keyDesc = ShowBaseGlobal.direct.hotKeyMap[input]
             messenger.send(keyDesc[1])
             messenger.send(keyDesc[1])
 
 
     def reset(self):
     def reset(self):
@@ -533,12 +534,12 @@ class LevelEditorUIBase(WxPandaShell):
 
 
     def toggleGridSnap(self, evt):
     def toggleGridSnap(self, evt):
         if self.gridSnapMenuItem.IsChecked():
         if self.gridSnapMenuItem.IsChecked():
-            base.direct.manipulationControl.fGridSnap = 1
+            ShowBaseGlobal.direct.manipulationControl.fGridSnap = 1
             for grid in [self.perspView.grid, self.topView.grid, self.frontView.grid, self.leftView.grid]:
             for grid in [self.perspView.grid, self.topView.grid, self.frontView.grid, self.leftView.grid]:
                 grid.fXyzSnap = 1
                 grid.fXyzSnap = 1
 
 
         else:
         else:
-            base.direct.manipulationControl.fGridSnap = 0
+            ShowBaseGlobal.direct.manipulationControl.fGridSnap = 0
             for grid in [self.perspView.grid, self.topView.grid, self.frontView.grid, self.leftView.grid]:
             for grid in [self.perspView.grid, self.topView.grid, self.frontView.grid, self.leftView.grid]:
                 grid.fXyzSnap = 0
                 grid.fXyzSnap = 0
 
 
@@ -589,7 +590,7 @@ class LevelEditorUIBase(WxPandaShell):
         self.contextMenu.AppendSeparator()
         self.contextMenu.AppendSeparator()
 
 
     def replaceObject(self, evt, all=False):
     def replaceObject(self, evt, all=False):
-        currObj = self.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
+        currObj = self.editor.objectMgr.findObjectByNodePath(ShowBaseGlobal.direct.selected.last)
         if currObj is None:
         if currObj is None:
             print('No valid object is selected for replacement')
             print('No valid object is selected for replacement')
             return
             return
@@ -636,13 +637,13 @@ class GridSizeUI(wx.Dialog):
         vbox.Add(okButton, 1, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 5)
         vbox.Add(okButton, 1, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 5)
 
 
         self.SetSizer(vbox)
         self.SetSizer(vbox)
-        base.le.ui.bindKeyEvents(False)
+        ShowBaseGlobal.base.le.ui.bindKeyEvents(False)
 
 
     def onApply(self, evt):
     def onApply(self, evt):
         newSize = self.gridSizeSlider.GetValue()
         newSize = self.gridSizeSlider.GetValue()
         newSpacing = self.gridSpacingSlider.GetValue()
         newSpacing = self.gridSpacingSlider.GetValue()
         self.parent.updateGrids(newSize, newSpacing)
         self.parent.updateGrids(newSize, newSpacing)
-        base.le.ui.bindKeyEvents(True)
+        ShowBaseGlobal.base.le.ui.bindKeyEvents(True)
         self.Destroy()
         self.Destroy()
 
 
 
 

+ 3 - 0
direct/src/leveleditor/LevelLoader.py

@@ -25,6 +25,9 @@ class LevelLoader(LevelLoaderBase):
 
 
     def initLoader(self):
     def initLoader(self):
         self.defaultPath = os.path.dirname(__file__)
         self.defaultPath = os.path.dirname(__file__)
+
+        from direct.showbase import ShowBaseGlobal
+        base = ShowBaseGlobal.base
         base.objectPalette = ObjectPalette()
         base.objectPalette = ObjectPalette()
         base.protoPalette = ProtoPalette()
         base.protoPalette = ProtoPalette()
         base.objectHandler = ObjectHandler(None)
         base.objectHandler = ObjectHandler(None)

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

@@ -141,7 +141,7 @@ import importlib
 from direct.showbase import ExceptionVarDump
 from direct.showbase import ExceptionVarDump
 from . import DirectObject
 from . import DirectObject
 from . import SfxPlayer
 from . import SfxPlayer
-from typing import ClassVar
+from typing import ClassVar, Optional
 if __debug__:
 if __debug__:
     from direct.showbase import GarbageReport
     from direct.showbase import GarbageReport
     from direct.directutil import DeltaProfiler
     from direct.directutil import DeltaProfiler
@@ -166,6 +166,10 @@ class ShowBase(DirectObject.DirectObject):
     notify: ClassVar[Notifier] = directNotify.newCategory("ShowBase")
     notify: ClassVar[Notifier] = directNotify.newCategory("ShowBase")
     guiItems: ClassVar[dict]
     guiItems: ClassVar[dict]
 
 
+    render2d: NodePath
+    aspect2d: NodePath
+    pixel2d: NodePath
+
     def __init__(self, fStartDirect=True, windowType=None):
     def __init__(self, fStartDirect=True, windowType=None):
         """Opens a window, sets up a 3-D and several 2-D scene graphs, and
         """Opens a window, sets up a 3-D and several 2-D scene graphs, and
         everything else needed to render the scene graph to the window.
         everything else needed to render the scene graph to the window.

+ 2 - 0
direct/src/showbase/ShowBaseGlobal.py

@@ -61,6 +61,8 @@ aspect2d = render2d.attachNewNode(PGTop("aspect2d"))
 #: A dummy scene graph that is not being rendered by anything.
 #: A dummy scene graph that is not being rendered by anything.
 hidden = NodePath("hidden")
 hidden = NodePath("hidden")
 
 
+direct: "DirectSession"
+
 # Set direct notify categories now that we have config
 # Set direct notify categories now that we have config
 directNotify.setDconfigLevels()
 directNotify.setDconfigLevels()
 
 

+ 6 - 4
direct/src/showutil/TexMemWatcher.py

@@ -22,6 +22,7 @@ from panda3d.core import (
     WindowProperties,
     WindowProperties,
 )
 )
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
+from direct.showbase import ShowBaseGlobal
 from direct.task.TaskManagerGlobal import taskMgr
 from direct.task.TaskManagerGlobal import taskMgr
 import math
 import math
 import copy
 import copy
@@ -109,7 +110,7 @@ class TexMemWatcher(DirectObject):
         # This is the maximum number of bitmask rows (within
         # This is the maximum number of bitmask rows (within
         # self.limit) to allocate for packing.  This controls the
         # self.limit) to allocate for packing.  This controls the
         # value assigned to self.quantize in repack().
         # value assigned to self.quantize in repack().
-        self.maxHeight = base.config.GetInt('tex-mem-max-height', 300)
+        self.maxHeight = ConfigVariableInt('tex-mem-max-height', 300).value
 
 
         # The total number of texture bytes tracked, including overflow.
         # The total number of texture bytes tracked, including overflow.
         self.totalSize = 0
         self.totalSize = 0
@@ -122,6 +123,7 @@ class TexMemWatcher(DirectObject):
         self.placedQSize = 0
         self.placedQSize = 0
 
 
         # If no GSG is specified, use the main GSG.
         # If no GSG is specified, use the main GSG.
+        base = ShowBaseGlobal.base
         if gsg is None:
         if gsg is None:
             gsg = base.win.getGsg()
             gsg = base.win.getGsg()
         elif isinstance(gsg, GraphicsOutput):
         elif isinstance(gsg, GraphicsOutput):
@@ -150,7 +152,7 @@ class TexMemWatcher(DirectObject):
         # Set this to tinydisplay if you're running on a machine with
         # Set this to tinydisplay if you're running on a machine with
         # limited texture memory.  That way you won't compete for
         # limited texture memory.  That way you won't compete for
         # texture memory with the main scene.
         # texture memory with the main scene.
-        moduleName = base.config.GetString('tex-mem-pipe', '')
+        moduleName = ConfigVariableString('tex-mem-pipe', '').value
         if moduleName:
         if moduleName:
             self.pipe = base.makeModulePipe(moduleName)
             self.pipe = base.makeModulePipe(moduleName)
 
 
@@ -202,7 +204,7 @@ class TexMemWatcher(DirectObject):
 
 
         # How frequently should the texture memory window check for
         # How frequently should the texture memory window check for
         # state changes?
         # state changes?
-        updateInterval = base.config.GetDouble("tex-mem-update-interval", 0.5)
+        updateInterval = ConfigVariableDouble("tex-mem-update-interval", 0.5).value
         self.task = taskMgr.doMethodLater(updateInterval, self.updateTextures, 'TexMemWatcher')
         self.task = taskMgr.doMethodLater(updateInterval, self.updateTextures, 'TexMemWatcher')
 
 
         self.setLimit(limit)
         self.setLimit(limit)
@@ -380,7 +382,7 @@ class TexMemWatcher(DirectObject):
             self.cleanedUp = True
             self.cleanedUp = True
 
 
             # Remove the window.
             # Remove the window.
-            base.graphicsEngine.removeWindow(self.win)
+            self.win.engine.removeWindow(self.win)
             self.win = None
             self.win = None
             self.gsg = None
             self.gsg = None
             self.pipe = None
             self.pipe = None

+ 90 - 89
direct/src/tkpanels/DirectSessionPanel.py

@@ -20,6 +20,7 @@ from direct.tkwidgets import VectorWidgets
 from direct.tkwidgets import SceneGraphExplorer
 from direct.tkwidgets import SceneGraphExplorer
 from direct.tkwidgets import MemoryExplorer
 from direct.tkwidgets import MemoryExplorer
 from direct.task.TaskManagerGlobal import taskMgr
 from direct.task.TaskManagerGlobal import taskMgr
+from direct.showbase import ShowBaseGlobal
 from .TaskManagerPanel import TaskManagerWidget
 from .TaskManagerPanel import TaskManagerWidget
 import Pmw
 import Pmw
 import tkinter as tk
 import tkinter as tk
@@ -44,8 +45,8 @@ class DirectSessionPanel(AppShell):
         AppShell.__init__(self, parent)
         AppShell.__init__(self, parent)
 
 
         # Active light
         # Active light
-        if len(base.direct.lights) > 0:
-            name = base.direct.lights.getNameList()[0]
+        if len(ShowBaseGlobal.direct.lights) > 0:
+            name = ShowBaseGlobal.direct.lights.getNameList()[0]
             self.lightMenu.selectitem(name)
             self.lightMenu.selectitem(name)
             self.selectLightNamed(name)
             self.selectLightNamed(name)
         else:
         else:
@@ -62,14 +63,14 @@ class DirectSessionPanel(AppShell):
         # Initialize state
         # Initialize state
         # Dictionary keeping track of all node paths selected so far
         # Dictionary keeping track of all node paths selected so far
         self.nodePathDict = {}
         self.nodePathDict = {}
-        self.nodePathDict['widget'] = base.direct.widget
+        self.nodePathDict['widget'] = ShowBaseGlobal.direct.widget
         self.nodePathNames = ['widget']
         self.nodePathNames = ['widget']
 
 
         # Dictionary keeping track of all jb node paths selected so far
         # Dictionary keeping track of all jb node paths selected so far
         self.jbNodePathDict = {}
         self.jbNodePathDict = {}
         self.jbNodePathDict['none'] = 'No Node Path'
         self.jbNodePathDict['none'] = 'No Node Path'
-        self.jbNodePathDict['widget'] = base.direct.widget
-        self.jbNodePathDict['camera'] = base.direct.camera
+        self.jbNodePathDict['widget'] = ShowBaseGlobal.direct.widget
+        self.jbNodePathDict['camera'] = ShowBaseGlobal.direct.camera
         self.jbNodePathNames = ['camera', 'selected', 'none']
         self.jbNodePathNames = ['camera', 'selected', 'none']
 
 
         # Set up event hooks
         # Set up event hooks
@@ -93,7 +94,7 @@ class DirectSessionPanel(AppShell):
         self.menuBar.addmenu('DIRECT', 'Direct Session Panel Operations')
         self.menuBar.addmenu('DIRECT', 'Direct Session Panel Operations')
 
 
         self.directEnabled = tk.BooleanVar()
         self.directEnabled = tk.BooleanVar()
-        self.directEnabled.set(1)
+        self.directEnabled.set(True)
         self.menuBar.addmenuitem('DIRECT', 'checkbutton',
         self.menuBar.addmenuitem('DIRECT', 'checkbutton',
                                  'DIRECT Enabled',
                                  'DIRECT Enabled',
                                  label = 'Enable',
                                  label = 'Enable',
@@ -101,7 +102,7 @@ class DirectSessionPanel(AppShell):
                                  command = self.toggleDirect)
                                  command = self.toggleDirect)
 
 
         self.directGridEnabled = tk.BooleanVar()
         self.directGridEnabled = tk.BooleanVar()
-        self.directGridEnabled.set(base.direct.grid.isEnabled())
+        self.directGridEnabled.set(ShowBaseGlobal.direct.grid.isEnabled())
         self.menuBar.addmenuitem('DIRECT', 'checkbutton',
         self.menuBar.addmenuitem('DIRECT', 'checkbutton',
                                  'DIRECT Grid Enabled',
                                  'DIRECT Grid Enabled',
                                  label = 'Enable Grid',
                                  label = 'Enable Grid',
@@ -111,16 +112,16 @@ class DirectSessionPanel(AppShell):
         self.menuBar.addmenuitem('DIRECT', 'command',
         self.menuBar.addmenuitem('DIRECT', 'command',
                                  'Toggle Object Handles Visability',
                                  'Toggle Object Handles Visability',
                                  label = 'Toggle Widget Viz',
                                  label = 'Toggle Widget Viz',
-                                 command = base.direct.toggleWidgetVis)
+                                 command = ShowBaseGlobal.direct.toggleWidgetVis)
 
 
         self.menuBar.addmenuitem(
         self.menuBar.addmenuitem(
             'DIRECT', 'command',
             'DIRECT', 'command',
             'Toggle Widget Move/COA Mode',
             'Toggle Widget Move/COA Mode',
             label = 'Toggle Widget Mode',
             label = 'Toggle Widget Mode',
-            command = base.direct.manipulationControl.toggleObjectHandlesMode)
+            command = ShowBaseGlobal.direct.manipulationControl.toggleObjectHandlesMode)
 
 
         self.directWidgetOnTop = tk.BooleanVar()
         self.directWidgetOnTop = tk.BooleanVar()
-        self.directWidgetOnTop.set(0)
+        self.directWidgetOnTop.set(False)
         self.menuBar.addmenuitem('DIRECT', 'checkbutton',
         self.menuBar.addmenuitem('DIRECT', 'checkbutton',
                                  'DIRECT Widget On Top',
                                  'DIRECT Widget On Top',
                                  label = 'Widget On Top',
                                  label = 'Widget On Top',
@@ -130,7 +131,7 @@ class DirectSessionPanel(AppShell):
         self.menuBar.addmenuitem('DIRECT', 'command',
         self.menuBar.addmenuitem('DIRECT', 'command',
                                  'Deselect All',
                                  'Deselect All',
                                  label = 'Deselect All',
                                  label = 'Deselect All',
-                                 command = base.direct.deselectAll)
+                                 command = ShowBaseGlobal.direct.deselectAll)
 
 
         # Get a handle to the menu frame
         # Get a handle to the menu frame
         menuFrame = self.menuFrame
         menuFrame = self.menuFrame
@@ -150,8 +151,8 @@ class DirectSessionPanel(AppShell):
         self.bind(self.nodePathMenu, 'Select node path to manipulate')
         self.bind(self.nodePathMenu, 'Select node path to manipulate')
 
 
         self.undoButton = tk.Button(menuFrame, text = 'Undo',
         self.undoButton = tk.Button(menuFrame, text = 'Undo',
-                                    command = base.direct.undo)
-        if base.direct.undoList:
+                                    command = ShowBaseGlobal.direct.undo)
+        if ShowBaseGlobal.direct.undoList:
             self.undoButton['state'] = 'normal'
             self.undoButton['state'] = 'normal'
         else:
         else:
             self.undoButton['state'] = 'disabled'
             self.undoButton['state'] = 'disabled'
@@ -159,8 +160,8 @@ class DirectSessionPanel(AppShell):
         self.bind(self.undoButton, 'Undo last operation')
         self.bind(self.undoButton, 'Undo last operation')
 
 
         self.redoButton = tk.Button(menuFrame, text = 'Redo',
         self.redoButton = tk.Button(menuFrame, text = 'Redo',
-                                    command = base.direct.redo)
-        if base.direct.redoList:
+                                    command = ShowBaseGlobal.direct.redo)
+        if ShowBaseGlobal.direct.redoList:
             self.redoButton['state'] = 'normal'
             self.redoButton['state'] = 'normal'
         else:
         else:
             self.redoButton['state'] = 'disabled'
             self.redoButton['state'] = 'disabled'
@@ -177,7 +178,7 @@ class DirectSessionPanel(AppShell):
 
 
         # Scene Graph Explorer
         # Scene Graph Explorer
         self.SGE = SceneGraphExplorer.SceneGraphExplorer(
         self.SGE = SceneGraphExplorer.SceneGraphExplorer(
-            sgeFrame, nodePath = render,
+            sgeFrame, nodePath = ShowBaseGlobal.base.render,
             scrolledCanvas_hull_width = 250,
             scrolledCanvas_hull_width = 250,
             scrolledCanvas_hull_height = 300)
             scrolledCanvas_hull_height = 300)
         self.SGE.pack(fill = tk.BOTH, expand = 1)
         self.SGE.pack(fill = tk.BOTH, expand = 1)
@@ -218,7 +219,7 @@ class DirectSessionPanel(AppShell):
         tk.Label(drFrame, text = 'Display Region',
         tk.Label(drFrame, text = 'Display Region',
                  font=('MSSansSerif', 14, 'bold')).pack(expand = 0)
                  font=('MSSansSerif', 14, 'bold')).pack(expand = 0)
 
 
-        nameList = ['Display Region ' + repr(x) for x in range(len(base.direct.drList))]
+        nameList = ['Display Region ' + repr(x) for x in range(len(ShowBaseGlobal.direct.drList))]
         self.drMenu = Pmw.ComboBox(
         self.drMenu = Pmw.ComboBox(
             drFrame, labelpos = tk.W, label_text = 'Display Region:',
             drFrame, labelpos = tk.W, label_text = 'Display Region:',
             entry_width = 20,
             entry_width = 20,
@@ -264,7 +265,7 @@ class DirectSessionPanel(AppShell):
 
 
         frame = tk.Frame(fovFrame)
         frame = tk.Frame(fovFrame)
         self.lockedFov = tk.BooleanVar()
         self.lockedFov = tk.BooleanVar()
-        self.lockedFov.set(1)
+        self.lockedFov.set(True)
         self.lockedFovButton = tk.Checkbutton(
         self.lockedFovButton = tk.Checkbutton(
             frame,
             frame,
             text = 'Locked',
             text = 'Locked',
@@ -289,25 +290,25 @@ class DirectSessionPanel(AppShell):
         self.toggleBackfaceButton = tk.Button(
         self.toggleBackfaceButton = tk.Button(
             toggleFrame,
             toggleFrame,
             text = 'Backface',
             text = 'Backface',
-            command = base.toggleBackface)
+            command = ShowBaseGlobal.base.toggleBackface)
         self.toggleBackfaceButton.pack(side = tk.LEFT, fill = tk.X, expand = 1)
         self.toggleBackfaceButton.pack(side = tk.LEFT, fill = tk.X, expand = 1)
 
 
         self.toggleLightsButton = tk.Button(
         self.toggleLightsButton = tk.Button(
             toggleFrame,
             toggleFrame,
             text = 'Lights',
             text = 'Lights',
-            command = base.direct.lights.toggle)
+            command = ShowBaseGlobal.direct.lights.toggle)
         self.toggleLightsButton.pack(side = tk.LEFT, fill = tk.X, expand = 1)
         self.toggleLightsButton.pack(side = tk.LEFT, fill = tk.X, expand = 1)
 
 
         self.toggleTextureButton = tk.Button(
         self.toggleTextureButton = tk.Button(
             toggleFrame,
             toggleFrame,
             text = 'Texture',
             text = 'Texture',
-            command = base.toggleTexture)
+            command = ShowBaseGlobal.base.toggleTexture)
         self.toggleTextureButton.pack(side = tk.LEFT, fill = tk.X, expand = 1)
         self.toggleTextureButton.pack(side = tk.LEFT, fill = tk.X, expand = 1)
 
 
         self.toggleWireframeButton = tk.Button(
         self.toggleWireframeButton = tk.Button(
             toggleFrame,
             toggleFrame,
             text = 'Wireframe',
             text = 'Wireframe',
-            command = base.toggleWireframe)
+            command = ShowBaseGlobal.base.toggleWireframe)
         self.toggleWireframeButton.pack(fill = tk.X, expand = 1)
         self.toggleWireframeButton.pack(fill = tk.X, expand = 1)
         toggleFrame.pack(side = tk.LEFT, fill = tk.X, expand = 1)
         toggleFrame.pack(side = tk.LEFT, fill = tk.X, expand = 1)
 
 
@@ -354,7 +355,7 @@ class DirectSessionPanel(AppShell):
         mainSwitchFrame.pack(fill = tk.X, expand = 0)
         mainSwitchFrame.pack(fill = tk.X, expand = 0)
 
 
         # Widget to select a light to configure
         # Widget to select a light to configure
-        nameList = base.direct.lights.getNameList()
+        nameList = ShowBaseGlobal.direct.lights.getNameList()
         lightMenuFrame = tk.Frame(lightFrame)
         lightMenuFrame = tk.Frame(lightFrame)
 
 
         self.lightMenu = Pmw.ComboBox(
         self.lightMenu = Pmw.ComboBox(
@@ -510,36 +511,36 @@ class DirectSessionPanel(AppShell):
             gridPage,
             gridPage,
             text = 'Grid Spacing',
             text = 'Grid Spacing',
             min = 0.1,
             min = 0.1,
-            value = base.direct.grid.getGridSpacing())
-        self.gridSpacing['command'] = base.direct.grid.setGridSpacing
+            value = ShowBaseGlobal.direct.grid.getGridSpacing())
+        self.gridSpacing['command'] = ShowBaseGlobal.direct.grid.setGridSpacing
         self.gridSpacing.pack(fill = tk.X, expand = 0)
         self.gridSpacing.pack(fill = tk.X, expand = 0)
 
 
         self.gridSize = Floater.Floater(
         self.gridSize = Floater.Floater(
             gridPage,
             gridPage,
             text = 'Grid Size',
             text = 'Grid Size',
             min = 1.0,
             min = 1.0,
-            value = base.direct.grid.getGridSize())
-        self.gridSize['command'] = base.direct.grid.setGridSize
+            value = ShowBaseGlobal.direct.grid.getGridSize())
+        self.gridSize['command'] = ShowBaseGlobal.direct.grid.setGridSize
         self.gridSize.pack(fill = tk.X, expand = 0)
         self.gridSize.pack(fill = tk.X, expand = 0)
 
 
         self.gridSnapAngle = Dial.AngleDial(
         self.gridSnapAngle = Dial.AngleDial(
             gridPage,
             gridPage,
             text = 'Snap Angle',
             text = 'Snap Angle',
             style = 'mini',
             style = 'mini',
-            value = base.direct.grid.getSnapAngle())
-        self.gridSnapAngle['command'] = base.direct.grid.setSnapAngle
+            value = ShowBaseGlobal.direct.grid.getSnapAngle())
+        self.gridSnapAngle['command'] = ShowBaseGlobal.direct.grid.setSnapAngle
         self.gridSnapAngle.pack(fill = tk.X, expand = 0)
         self.gridSnapAngle.pack(fill = tk.X, expand = 0)
 
 
     def createDevicePage(self, devicePage):
     def createDevicePage(self, devicePage):
         tk.Label(devicePage, text = 'DEVICES',
         tk.Label(devicePage, text = 'DEVICES',
               font=('MSSansSerif', 14, 'bold')).pack(expand = 0)
               font=('MSSansSerif', 14, 'bold')).pack(expand = 0)
 
 
-        if base.direct.joybox is not None:
+        if ShowBaseGlobal.direct.joybox is not None:
             joyboxFrame = tk.Frame(devicePage, borderwidth = 2, relief = 'sunken')
             joyboxFrame = tk.Frame(devicePage, borderwidth = 2, relief = 'sunken')
             tk.Label(joyboxFrame, text = 'Joybox',
             tk.Label(joyboxFrame, text = 'Joybox',
                      font=('MSSansSerif', 14, 'bold')).pack(expand = 0)
                      font=('MSSansSerif', 14, 'bold')).pack(expand = 0)
             self.enableJoybox = tk.BooleanVar()
             self.enableJoybox = tk.BooleanVar()
-            self.enableJoybox.set(1)
+            self.enableJoybox.set(True)
             self.enableJoyboxButton = tk.Checkbutton(
             self.enableJoyboxButton = tk.Checkbutton(
                 joyboxFrame,
                 joyboxFrame,
                 text = 'Enabled/Disabled',
                 text = 'Enabled/Disabled',
@@ -581,7 +582,7 @@ class DirectSessionPanel(AppShell):
                 hull_relief = tk.RIDGE, hull_borderwidth = 2,
                 hull_relief = tk.RIDGE, hull_borderwidth = 2,
                 min = 1.0, max = 100.0)
                 min = 1.0, max = 100.0)
             self.jbXyzSF['command'] = (
             self.jbXyzSF['command'] = (
-                lambda v: base.direct.joybox.setXyzMultiplier(v))
+                lambda v: ShowBaseGlobal.direct.joybox.setXyzMultiplier(v))
             self.jbXyzSF.pack(fill = tk.X, expand = 0)
             self.jbXyzSF.pack(fill = tk.X, expand = 0)
             self.bind(self.jbXyzSF, 'Set joybox XYZ speed multiplier')
             self.bind(self.jbXyzSF, 'Set joybox XYZ speed multiplier')
 
 
@@ -592,7 +593,7 @@ class DirectSessionPanel(AppShell):
                 hull_relief = tk.RIDGE, hull_borderwidth = 2,
                 hull_relief = tk.RIDGE, hull_borderwidth = 2,
                 min = 1.0, max = 100.0)
                 min = 1.0, max = 100.0)
             self.jbHprSF['command'] = (
             self.jbHprSF['command'] = (
-                lambda v: base.direct.joybox.setHprMultiplier(v))
+                lambda v: ShowBaseGlobal.direct.joybox.setHprMultiplier(v))
             self.jbHprSF.pack(fill = tk.X, expand = 0)
             self.jbHprSF.pack(fill = tk.X, expand = 0)
             self.bind(self.jbHprSF, 'Set joybox HPR speed multiplier')
             self.bind(self.jbHprSF, 'Set joybox HPR speed multiplier')
 
 
@@ -604,30 +605,30 @@ class DirectSessionPanel(AppShell):
 
 
     def createMemPage(self, memPage):
     def createMemPage(self, memPage):
         self.MemExp = MemoryExplorer.MemoryExplorer(
         self.MemExp = MemoryExplorer.MemoryExplorer(
-            memPage, nodePath = render,
+            memPage, nodePath = ShowBaseGlobal.base.render,
             scrolledCanvas_hull_width = 250,
             scrolledCanvas_hull_width = 250,
             scrolledCanvas_hull_height = 250)
             scrolledCanvas_hull_height = 250)
         self.MemExp.pack(fill = tk.BOTH, expand = 1)
         self.MemExp.pack(fill = tk.BOTH, expand = 1)
 
 
     def toggleDirect(self):
     def toggleDirect(self):
         if self.directEnabled.get():
         if self.directEnabled.get():
-            base.direct.enable()
+            ShowBaseGlobal.direct.enable()
         else:
         else:
-            base.direct.disable()
+            ShowBaseGlobal.direct.disable()
 
 
     def toggleDirectGrid(self):
     def toggleDirectGrid(self):
         if self.directGridEnabled.get():
         if self.directGridEnabled.get():
-            base.direct.grid.enable()
+            ShowBaseGlobal.direct.grid.enable()
         else:
         else:
-            base.direct.grid.disable()
+            ShowBaseGlobal.direct.grid.disable()
 
 
     def toggleWidgetOnTop(self):
     def toggleWidgetOnTop(self):
         if self.directWidgetOnTop.get():
         if self.directWidgetOnTop.get():
-            base.direct.widget.setBin('gui-popup', 0)
-            base.direct.widget.setDepthTest(0)
+            ShowBaseGlobal.direct.widget.setBin('gui-popup', 0)
+            ShowBaseGlobal.direct.widget.setDepthTest(0)
         else:
         else:
-            base.direct.widget.clearBin()
-            base.direct.widget.setDepthTest(1)
+            ShowBaseGlobal.direct.widget.clearBin()
+            ShowBaseGlobal.direct.widget.setDepthTest(1)
 
 
     def selectedNodePathHook(self, nodePath):
     def selectedNodePathHook(self, nodePath):
         # Make sure node path is in nodePathDict
         # Make sure node path is in nodePathDict
@@ -657,7 +658,7 @@ class DirectSessionPanel(AppShell):
         # Did we finally get something?
         # Did we finally get something?
         if nodePath is not None:
         if nodePath is not None:
             # Yes, select it!
             # Yes, select it!
-            base.direct.select(nodePath)
+            ShowBaseGlobal.direct.select(nodePath)
 
 
     def addNodePath(self, nodePath):
     def addNodePath(self, nodePath):
         self.addNodePathToDict(nodePath, self.nodePathNames,
         self.addNodePathToDict(nodePath, self.nodePathNames,
@@ -665,25 +666,25 @@ class DirectSessionPanel(AppShell):
 
 
     def selectJBModeNamed(self, name):
     def selectJBModeNamed(self, name):
         if name == 'Joe Mode':
         if name == 'Joe Mode':
-            base.direct.joybox.joeMode()
+            ShowBaseGlobal.direct.joybox.joeMode()
         elif name == 'Drive Mode':
         elif name == 'Drive Mode':
-            base.direct.joybox.driveMode()
+            ShowBaseGlobal.direct.joybox.driveMode()
         elif name == 'Orbit Mode':
         elif name == 'Orbit Mode':
-            base.direct.joybox.orbitMode()
+            ShowBaseGlobal.direct.joybox.orbitMode()
         elif name == 'Look At Mode':
         elif name == 'Look At Mode':
-            base.direct.joybox.lookAtMode()
+            ShowBaseGlobal.direct.joybox.lookAtMode()
         elif name == 'Look Around Mode':
         elif name == 'Look Around Mode':
-            base.direct.joybox.lookAroundMode()
+            ShowBaseGlobal.direct.joybox.lookAroundMode()
         elif name == 'Walkthru Mode':
         elif name == 'Walkthru Mode':
-            base.direct.joybox.walkthruMode()
+            ShowBaseGlobal.direct.joybox.walkthruMode()
         elif name == 'Demo Mode':
         elif name == 'Demo Mode':
-            base.direct.joybox.demoMode()
+            ShowBaseGlobal.direct.joybox.demoMode()
         elif name == 'HPRXYZ Mode':
         elif name == 'HPRXYZ Mode':
-            base.direct.joybox.hprXyzMode()
+            ShowBaseGlobal.direct.joybox.hprXyzMode()
 
 
     def selectJBNodePathNamed(self, name):
     def selectJBNodePathNamed(self, name):
         if name == 'selected':
         if name == 'selected':
-            nodePath = base.direct.selected.last
+            nodePath = ShowBaseGlobal.direct.selected.last
             # Add Combo box entry for this selected object
             # Add Combo box entry for this selected object
             self.addJBNodePath(nodePath)
             self.addJBNodePath(nodePath)
         else:
         else:
@@ -708,9 +709,9 @@ class DirectSessionPanel(AppShell):
         if nodePath is not None:
         if nodePath is not None:
             # Yes, select it!
             # Yes, select it!
             if nodePath == 'No Node Path':
             if nodePath == 'No Node Path':
-                base.direct.joybox.setNodePath(None)
+                ShowBaseGlobal.direct.joybox.setNodePath(None)
             else:
             else:
-                base.direct.joybox.setNodePath(nodePath)
+                ShowBaseGlobal.direct.joybox.setNodePath(nodePath)
 
 
     def addJBNodePath(self, nodePath):
     def addJBNodePath(self, nodePath):
         self.addNodePathToDict(nodePath, self.jbNodePathNames,
         self.addNodePathToDict(nodePath, self.jbNodePathNames,
@@ -741,14 +742,13 @@ class DirectSessionPanel(AppShell):
         self.setBackgroundColorVec((r, g, b))
         self.setBackgroundColorVec((r, g, b))
 
 
     def setBackgroundColorVec(self, color):
     def setBackgroundColorVec(self, color):
-        base.setBackgroundColor(color[0]/255.0,
-                                color[1]/255.0,
-                                color[2]/255.0)
+        ShowBaseGlobal.base.setBackgroundColor(
+            color[0] / 255.0, color[1] / 255.0, color[2] / 255.0)
 
 
     def selectDisplayRegionNamed(self, name):
     def selectDisplayRegionNamed(self, name):
         if name.find('Display Region ') >= 0:
         if name.find('Display Region ') >= 0:
             drIndex = int(name[-1:])
             drIndex = int(name[-1:])
-            self.activeDisplayRegion = base.direct.drList[drIndex]
+            self.activeDisplayRegion = ShowBaseGlobal.direct.drList[drIndex]
         else:
         else:
             self.activeDisplayRegion = None
             self.activeDisplayRegion = None
         # Make sure info is current
         # Make sure info is current
@@ -758,13 +758,13 @@ class DirectSessionPanel(AppShell):
         dr = self.activeDisplayRegion
         dr = self.activeDisplayRegion
         if dr:
         if dr:
             dr.camLens.setNear(near)
             dr.camLens.setNear(near)
-            cluster('base.camLens.setNear(%f)' % near, 0)
+            ShowBaseGlobal.direct.cluster('base.camLens.setNear(%f)' % near, 0)
 
 
     def setFar(self, far):
     def setFar(self, far):
         dr = self.activeDisplayRegion
         dr = self.activeDisplayRegion
         if dr:
         if dr:
             dr.camLens.setFar(far)
             dr.camLens.setFar(far)
-            cluster('base.camLens.setFar(%f)' % far, 0)
+            ShowBaseGlobal.direct.cluster('base.camLens.setFar(%f)' % far, 0)
 
 
     def setHFov(self, hFov):
     def setHFov(self, hFov):
         dr = self.activeDisplayRegion
         dr = self.activeDisplayRegion
@@ -802,10 +802,10 @@ class DirectSessionPanel(AppShell):
     # Lights #
     # Lights #
     def selectLightNamed(self, name):
     def selectLightNamed(self, name):
         # See if light exists
         # See if light exists
-        self.activeLight = base.direct.lights[name]
+        self.activeLight = ShowBaseGlobal.direct.lights[name]
         # If not...create new one
         # If not...create new one
         if self.activeLight is None:
         if self.activeLight is None:
-            self.activeLight = base.direct.lights.create(name)
+            self.activeLight = ShowBaseGlobal.direct.lights.create(name)
         # Do we have a valid light at this point?
         # Do we have a valid light at this point?
         if self.activeLight:
         if self.activeLight:
             light = self.activeLight.getLight()
             light = self.activeLight.getLight()
@@ -820,28 +820,28 @@ class DirectSessionPanel(AppShell):
         else:
         else:
             # Restore valid data
             # Restore valid data
             listbox = self.lightMenu.component('scrolledlist')
             listbox = self.lightMenu.component('scrolledlist')
-            listbox.setlist(base.direct.lights.getNameList())
-            if len(base.direct.lights) > 0:
-                self.lightMenu.selectitem(base.direct.lights.getNameList()[0])
+            listbox.setlist(ShowBaseGlobal.direct.lights.getNameList())
+            if len(ShowBaseGlobal.direct.lights) > 0:
+                self.lightMenu.selectitem(ShowBaseGlobal.direct.lights.getNameList()[0])
         # Make sure info is current
         # Make sure info is current
         self.updateLightInfo()
         self.updateLightInfo()
 
 
     def addAmbient(self):
     def addAmbient(self):
-        return base.direct.lights.create('ambient')
+        return ShowBaseGlobal.direct.lights.create('ambient')
 
 
     def addDirectional(self):
     def addDirectional(self):
-        return base.direct.lights.create('directional')
+        return ShowBaseGlobal.direct.lights.create('directional')
 
 
     def addPoint(self):
     def addPoint(self):
-        return base.direct.lights.create('point')
+        return ShowBaseGlobal.direct.lights.create('point')
 
 
     def addSpot(self):
     def addSpot(self):
-        return base.direct.lights.create('spot')
+        return ShowBaseGlobal.direct.lights.create('spot')
 
 
     def addLight(self, light):
     def addLight(self, light):
         # Make list reflect current list of lights
         # Make list reflect current list of lights
         listbox = self.lightMenu.component('scrolledlist')
         listbox = self.lightMenu.component('scrolledlist')
-        listbox.setlist(base.direct.lights.getNameList())
+        listbox.setlist(ShowBaseGlobal.direct.lights.getNameList())
         # Select the newly added light
         # Select the newly added light
         self.lightMenu.selectitem(light.getName())
         self.lightMenu.selectitem(light.getName())
         # And show corresponding page
         # And show corresponding page
@@ -849,16 +849,16 @@ class DirectSessionPanel(AppShell):
 
 
     def toggleLights(self):
     def toggleLights(self):
         if self.enableLights.get():
         if self.enableLights.get():
-            base.direct.lights.allOn()
+            ShowBaseGlobal.direct.lights.allOn()
         else:
         else:
-            base.direct.lights.allOff()
+            ShowBaseGlobal.direct.lights.allOff()
 
 
     def toggleActiveLight(self):
     def toggleActiveLight(self):
         if self.activeLight:
         if self.activeLight:
             if self.lightActive.get():
             if self.lightActive.get():
-                base.direct.lights.setOn(self.activeLight)
+                ShowBaseGlobal.direct.lights.setOn(self.activeLight)
             else:
             else:
-                base.direct.lights.setOff(self.activeLight)
+                ShowBaseGlobal.direct.lights.setOff(self.activeLight)
 
 
     def setLightColor(self, color):
     def setLightColor(self, color):
         if self.activeLight:
         if self.activeLight:
@@ -893,22 +893,22 @@ class DirectSessionPanel(AppShell):
     ## GRID CONTROLS ##
     ## GRID CONTROLS ##
     def toggleGrid(self):
     def toggleGrid(self):
         if self.enableGrid.get():
         if self.enableGrid.get():
-            base.direct.grid.enable()
+            ShowBaseGlobal.direct.grid.enable()
         else:
         else:
-            base.direct.grid.disable()
+            ShowBaseGlobal.direct.grid.disable()
 
 
     def toggleXyzSnap(self):
     def toggleXyzSnap(self):
-        base.direct.grid.setXyzSnap(self.xyzSnap.get())
+        ShowBaseGlobal.direct.grid.setXyzSnap(self.xyzSnap.get())
 
 
     def toggleHprSnap(self):
     def toggleHprSnap(self):
-        base.direct.grid.setHprSnap(self.hprSnap.get())
+        ShowBaseGlobal.direct.grid.setHprSnap(self.hprSnap.get())
 
 
     ## DEVICE CONTROLS
     ## DEVICE CONTROLS
     def toggleJoybox(self):
     def toggleJoybox(self):
         if self.enableJoybox.get():
         if self.enableJoybox.get():
-            base.direct.joybox.enable()
+            ShowBaseGlobal.direct.joybox.enable()
         else:
         else:
-            base.direct.joybox.disable()
+            ShowBaseGlobal.direct.joybox.disable()
 
 
     ## UPDATE INFO ##
     ## UPDATE INFO ##
     def updateInfo(self, page = 'Environment'):
     def updateInfo(self, page = 'Environment'):
@@ -920,7 +920,7 @@ class DirectSessionPanel(AppShell):
             self.updateGridInfo()
             self.updateGridInfo()
 
 
     def updateEnvironmentInfo(self):
     def updateEnvironmentInfo(self):
-        bkgrdColor = base.getBackgroundColor() * 255.0
+        bkgrdColor = ShowBaseGlobal.base.getBackgroundColor() * 255.0
         self.backgroundColor.set([bkgrdColor[0],
         self.backgroundColor.set([bkgrdColor[0],
                                   bkgrdColor[1],
                                   bkgrdColor[1],
                                   bkgrdColor[2],
                                   bkgrdColor[2],
@@ -936,6 +936,7 @@ class DirectSessionPanel(AppShell):
 
 
     def updateLightInfo(self, page = None):
     def updateLightInfo(self, page = None):
         # Set main lighting button
         # Set main lighting button
+        render = ShowBaseGlobal.base.render
         self.enableLights.set(
         self.enableLights.set(
             render.node().hasAttrib(LightAttrib.getClassType()))
             render.node().hasAttrib(LightAttrib.getClassType()))
 
 
@@ -974,16 +975,16 @@ class DirectSessionPanel(AppShell):
                 self.pQuadraticAttenuation.set(att[2], 0)
                 self.pQuadraticAttenuation.set(att[2], 0)
 
 
     def updateGridInfo(self):
     def updateGridInfo(self):
-        self.enableGrid.set(base.direct.grid.isEnabled())
-        self.xyzSnap.set(base.direct.grid.getXyzSnap())
-        self.hprSnap.set(base.direct.grid.getHprSnap())
-        self.gridSpacing.set(base.direct.grid.getGridSpacing(), 0)
-        self.gridSize.set(base.direct.grid.getGridSize(), 0)
-        self.gridSnapAngle.set(base.direct.grid.getSnapAngle(), 0)
+        self.enableGrid.set(ShowBaseGlobal.direct.grid.isEnabled())
+        self.xyzSnap.set(ShowBaseGlobal.direct.grid.getXyzSnap())
+        self.hprSnap.set(ShowBaseGlobal.direct.grid.getHprSnap())
+        self.gridSpacing.set(ShowBaseGlobal.direct.grid.getGridSpacing(), 0)
+        self.gridSize.set(ShowBaseGlobal.direct.grid.getGridSize(), 0)
+        self.gridSnapAngle.set(ShowBaseGlobal.direct.grid.getSnapAngle(), 0)
 
 
     # UNDO/REDO
     # UNDO/REDO
     def pushUndo(self, fResetRedo = 1):
     def pushUndo(self, fResetRedo = 1):
-        base.direct.pushUndo([self['nodePath']])
+        ShowBaseGlobal.direct.pushUndo([self['nodePath']])
 
 
     def undoHook(self, nodePathList = []):
     def undoHook(self, nodePathList = []):
         pass
         pass
@@ -997,7 +998,7 @@ class DirectSessionPanel(AppShell):
         self.undoButton.configure(state = 'disabled')
         self.undoButton.configure(state = 'disabled')
 
 
     def pushRedo(self):
     def pushRedo(self):
-        base.direct.pushRedo([self['nodePath']])
+        ShowBaseGlobal.direct.pushRedo([self['nodePath']])
 
 
     def redoHook(self, nodePathList = []):
     def redoHook(self, nodePathList = []):
         pass
         pass

+ 4 - 1
direct/src/tkpanels/Inspector.py

@@ -31,6 +31,8 @@ def inspect(anObject):
 
 
 ### private
 ### private
 
 
+_InspectorMap: dict[str, str]
+
 
 
 def inspectorFor(anObject):
 def inspectorFor(anObject):
     typeName = type(anObject).__name__.capitalize() + 'Type'
     typeName = type(anObject).__name__.capitalize() + 'Type'
@@ -396,7 +398,8 @@ class InspectorWindow:
         self.listWidget.component('listbox').focus_set()
         self.listWidget.component('listbox').focus_set()
 
 
     def showHelp(self):
     def showHelp(self):
-        help = tk.Toplevel(base.tkRoot)
+        from direct.showbase import ShowBaseGlobal
+        help = tk.Toplevel(ShowBaseGlobal.base.tkRoot)
         help.title("Inspector Help")
         help.title("Inspector Help")
         frame = tk.Frame(help)
         frame = tk.Frame(help)
         frame.pack()
         frame.pack()

+ 26 - 25
direct/src/tkpanels/Placer.py

@@ -9,6 +9,7 @@ from direct.tkwidgets import Dial
 from direct.tkwidgets import Floater
 from direct.tkwidgets import Floater
 from direct.directtools.DirectGlobals import ZERO_VEC, UNIT_VEC
 from direct.directtools.DirectGlobals import ZERO_VEC, UNIT_VEC
 from direct.showbase.MessengerGlobal import messenger
 from direct.showbase.MessengerGlobal import messenger
+from direct.showbase import ShowBaseGlobal
 from direct.task.TaskManagerGlobal import taskMgr
 from direct.task.TaskManagerGlobal import taskMgr
 import Pmw
 import Pmw
 import tkinter as tk
 import tkinter as tk
@@ -28,7 +29,7 @@ class Placer(AppShell):
         INITOPT = Pmw.INITOPT
         INITOPT = Pmw.INITOPT
         optiondefs = (
         optiondefs = (
             ('title',       self.appname,       None),
             ('title',       self.appname,       None),
-            ('nodePath',    base.direct.camera,      None),
+            ('nodePath',    ShowBaseGlobal.direct.camera,      None),
         )
         )
         self.defineoptions(kw, optiondefs)
         self.defineoptions(kw, optiondefs)
 
 
@@ -39,23 +40,23 @@ class Placer(AppShell):
 
 
     def appInit(self):
     def appInit(self):
         # Initialize state
         # Initialize state
-        self.tempCS = base.direct.group.attachNewNode('placerTempCS')
-        self.orbitFromCS = base.direct.group.attachNewNode(
+        self.tempCS = ShowBaseGlobal.direct.group.attachNewNode('placerTempCS')
+        self.orbitFromCS = ShowBaseGlobal.direct.group.attachNewNode(
             'placerOrbitFromCS')
             'placerOrbitFromCS')
-        self.orbitToCS = base.direct.group.attachNewNode('placerOrbitToCS')
+        self.orbitToCS = ShowBaseGlobal.direct.group.attachNewNode('placerOrbitToCS')
         self.refCS = self.tempCS
         self.refCS = self.tempCS
 
 
         # Dictionary keeping track of all node paths manipulated so far
         # Dictionary keeping track of all node paths manipulated so far
         self.nodePathDict = {}
         self.nodePathDict = {}
-        self.nodePathDict['camera'] = base.direct.camera
-        self.nodePathDict['widget'] = base.direct.widget
+        self.nodePathDict['camera'] = ShowBaseGlobal.direct.camera
+        self.nodePathDict['widget'] = ShowBaseGlobal.direct.widget
         self.nodePathNames = ['camera', 'widget', 'selected']
         self.nodePathNames = ['camera', 'widget', 'selected']
 
 
         self.refNodePathDict = {}
         self.refNodePathDict = {}
         self.refNodePathDict['parent'] = self['nodePath'].getParent()
         self.refNodePathDict['parent'] = self['nodePath'].getParent()
         self.refNodePathDict['render'] = render
         self.refNodePathDict['render'] = render
-        self.refNodePathDict['camera'] = base.direct.camera
-        self.refNodePathDict['widget'] = base.direct.widget
+        self.refNodePathDict['camera'] = ShowBaseGlobal.direct.camera
+        self.refNodePathDict['widget'] = ShowBaseGlobal.direct.widget
         self.refNodePathNames = ['parent', 'self', 'render',
         self.refNodePathNames = ['parent', 'self', 'render',
                                  'camera', 'widget', 'selected']
                                  'camera', 'widget', 'selected']
 
 
@@ -103,12 +104,12 @@ class Placer(AppShell):
             'Placer', 'command',
             'Placer', 'command',
             'Toggle widget visability',
             'Toggle widget visability',
             label = 'Toggle Widget Vis',
             label = 'Toggle Widget Vis',
-            command = base.direct.toggleWidgetVis)
+            command = ShowBaseGlobal.direct.toggleWidgetVis)
         self.menuBar.addmenuitem(
         self.menuBar.addmenuitem(
             'Placer', 'command',
             'Placer', 'command',
             'Toggle widget manipulation mode',
             'Toggle widget manipulation mode',
             label = 'Toggle Widget Mode',
             label = 'Toggle Widget Mode',
-            command = base.direct.manipulationControl.toggleObjectHandlesMode)
+            command = ShowBaseGlobal.direct.manipulationControl.toggleObjectHandlesMode)
 
 
         # Get a handle to the menu frame
         # Get a handle to the menu frame
         menuFrame = self.menuFrame
         menuFrame = self.menuFrame
@@ -145,8 +146,8 @@ class Placer(AppShell):
         self.bind(self.refNodePathMenu, 'Select relative node path')
         self.bind(self.refNodePathMenu, 'Select relative node path')
 
 
         self.undoButton = tk.Button(menuFrame, text = 'Undo',
         self.undoButton = tk.Button(menuFrame, text = 'Undo',
-                                    command = base.direct.undo)
-        if base.direct.undoList:
+                                    command = ShowBaseGlobal.direct.undo)
+        if ShowBaseGlobal.direct.undoList:
             self.undoButton['state'] = 'normal'
             self.undoButton['state'] = 'normal'
         else:
         else:
             self.undoButton['state'] = 'disabled'
             self.undoButton['state'] = 'disabled'
@@ -154,8 +155,8 @@ class Placer(AppShell):
         self.bind(self.undoButton, 'Undo last operation')
         self.bind(self.undoButton, 'Undo last operation')
 
 
         self.redoButton = tk.Button(menuFrame, text = 'Redo',
         self.redoButton = tk.Button(menuFrame, text = 'Redo',
-                                    command = base.direct.redo)
-        if base.direct.redoList:
+                                    command = ShowBaseGlobal.direct.redo)
+        if ShowBaseGlobal.direct.redoList:
             self.redoButton['state'] = 'normal'
             self.redoButton['state'] = 'normal'
         else:
         else:
             self.redoButton['state'] = 'disabled'
             self.redoButton['state'] = 'disabled'
@@ -394,7 +395,7 @@ class Placer(AppShell):
             # Add Combo box entry for the initial node path
             # Add Combo box entry for the initial node path
             self.addNodePath(nodePath)
             self.addNodePath(nodePath)
         elif name == 'selected':
         elif name == 'selected':
-            nodePath = base.direct.selected.last
+            nodePath = ShowBaseGlobal.direct.selected.last
             # Add Combo box entry for this selected object
             # Add Combo box entry for this selected object
             self.addNodePath(nodePath)
             self.addNodePath(nodePath)
         else:
         else:
@@ -417,7 +418,7 @@ class Placer(AppShell):
             else:
             else:
                 if name == 'widget':
                 if name == 'widget':
                     # Record relationship between selected nodes and widget
                     # Record relationship between selected nodes and widget
-                    base.direct.selected.getWrtAll()
+                    ShowBaseGlobal.direct.selected.getWrtAll()
         # Update active node path
         # Update active node path
         self.setActiveNodePath(nodePath)
         self.setActiveNodePath(nodePath)
 
 
@@ -449,7 +450,7 @@ class Placer(AppShell):
         if name == 'self':
         if name == 'self':
             nodePath = self.tempCS
             nodePath = self.tempCS
         elif name == 'selected':
         elif name == 'selected':
-            nodePath = base.direct.selected.last
+            nodePath = ShowBaseGlobal.direct.selected.last
             # Add Combo box entry for this selected object
             # Add Combo box entry for this selected object
             self.addRefNodePath(nodePath)
             self.addRefNodePath(nodePath)
         elif name == 'parent':
         elif name == 'parent':
@@ -560,13 +561,13 @@ class Placer(AppShell):
         elif self.movementMode == 'Orbit:':
         elif self.movementMode == 'Orbit:':
             self.xformOrbit(value, axis)
             self.xformOrbit(value, axis)
         if self.nodePathMenu.get() == 'widget':
         if self.nodePathMenu.get() == 'widget':
-            if base.direct.manipulationControl.fSetCoa:
+            if ShowBaseGlobal.direct.manipulationControl.fSetCoa:
                 # Update coa based on current widget position
                 # Update coa based on current widget position
-                base.direct.selected.last.mCoa2Dnp.assign(
-                    base.direct.widget.getMat(base.direct.selected.last))
+                ShowBaseGlobal.direct.selected.last.mCoa2Dnp.assign(
+                    ShowBaseGlobal.direct.widget.getMat(ShowBaseGlobal.direct.selected.last))
             else:
             else:
                 # Move the objects with the widget
                 # Move the objects with the widget
-                base.direct.selected.moveWrtWidgetAll()
+                ShowBaseGlobal.direct.selected.moveWrtWidgetAll()
 
 
     def xformStart(self, data):
     def xformStart(self, data):
         # Record undo point
         # Record undo point
@@ -575,7 +576,7 @@ class Placer(AppShell):
         if self.nodePathMenu.get() == 'widget':
         if self.nodePathMenu.get() == 'widget':
             taskMgr.remove('followSelectedNodePath')
             taskMgr.remove('followSelectedNodePath')
             # Record relationship between selected nodes and widget
             # Record relationship between selected nodes and widget
-            base.direct.selected.getWrtAll()
+            ShowBaseGlobal.direct.selected.getWrtAll()
         # Record initial state
         # Record initial state
         self.deltaHpr = self['nodePath'].getHpr(self.refCS)
         self.deltaHpr = self['nodePath'].getHpr(self.refCS)
         # Update placer to reflect new state
         # Update placer to reflect new state
@@ -590,7 +591,7 @@ class Placer(AppShell):
         # If moving widget restart follow task
         # If moving widget restart follow task
         if self.nodePathMenu.get() == 'widget':
         if self.nodePathMenu.get() == 'widget':
             # Restart followSelectedNodePath task
             # Restart followSelectedNodePath task
-            base.direct.manipulationControl.spawnFollowSelectedNodePathTask()
+            ShowBaseGlobal.direct.manipulationControl.spawnFollowSelectedNodePathTask()
 
 
     def xformRelative(self, value, axis):
     def xformRelative(self, value, axis):
         nodePath = self['nodePath']
         nodePath = self['nodePath']
@@ -729,7 +730,7 @@ class Placer(AppShell):
             self.xformStop(None)
             self.xformStop(None)
 
 
     def pushUndo(self, fResetRedo = 1):
     def pushUndo(self, fResetRedo = 1):
-        base.direct.pushUndo([self['nodePath']])
+        ShowBaseGlobal.direct.pushUndo([self['nodePath']])
 
 
     def undoHook(self, nodePathList = []):
     def undoHook(self, nodePathList = []):
         # Reflect new changes
         # Reflect new changes
@@ -744,7 +745,7 @@ class Placer(AppShell):
         self.undoButton.configure(state = 'disabled')
         self.undoButton.configure(state = 'disabled')
 
 
     def pushRedo(self):
     def pushRedo(self):
-        base.direct.pushRedo([self['nodePath']])
+        ShowBaseGlobal.direct.pushRedo([self['nodePath']])
 
 
     def redoHook(self, nodePathList = []):
     def redoHook(self, nodePathList = []):
         # Reflect new changes
         # Reflect new changes

+ 47 - 43
direct/src/wxwidgets/WxPandaShell.py

@@ -9,6 +9,8 @@ from direct.task.TaskManagerGlobal import taskMgr
 from .WxAppShell import WxAppShell
 from .WxAppShell import WxAppShell
 from .ViewPort import Viewport, ViewportManager
 from .ViewPort import Viewport, ViewportManager
 
 
+from typing import Optional
+
 ID_FOUR_VIEW = 401
 ID_FOUR_VIEW = 401
 ID_TOP_VIEW = 402
 ID_TOP_VIEW = 402
 ID_FRONT_VIEW = 403
 ID_FRONT_VIEW = 403
@@ -25,7 +27,7 @@ class WxPandaShell(WxAppShell):
     copyright       = ('Copyright 2010 Disney Online Studios.' +
     copyright       = ('Copyright 2010 Disney Online Studios.' +
                        '\nAll Rights Reserved.')
                        '\nAll Rights Reserved.')
 
 
-    MENU_TEXTS = {
+    MENU_TEXTS: dict[int, tuple[str, Optional[str]]] = {
         ID_FOUR_VIEW: ("Four Views", None),
         ID_FOUR_VIEW: ("Four Views", None),
         ID_TOP_VIEW: ("Top View", None),
         ID_TOP_VIEW: ("Top View", None),
         ID_FRONT_VIEW: ("Front View", None),
         ID_FRONT_VIEW: ("Front View", None),
@@ -114,6 +116,7 @@ class WxPandaShell(WxAppShell):
         self.wxStep()
         self.wxStep()
         ViewportManager.initializeAll()
         ViewportManager.initializeAll()
         # Position the camera
         # Position the camera
+        base = ShowBaseGlobal.base
         if base.trackball is not None:
         if base.trackball is not None:
             base.trackball.node().setPos(0, 30, 0)
             base.trackball.node().setPos(0, 30, 0)
             base.trackball.node().setHpr(0, 15, 0)
             base.trackball.node().setHpr(0, 15, 0)
@@ -125,33 +128,34 @@ class WxPandaShell(WxAppShell):
         # initializing direct
         # initializing direct
         if self.fStartDirect:
         if self.fStartDirect:
             base.startDirect(fWantTk = 0, fWantWx = 0)
             base.startDirect(fWantTk = 0, fWantWx = 0)
-
-            base.direct.disableMouseEvents()
-            newMouseEvents = ["_le_per_%s"%x for x in base.direct.mouseEvents] +\
-                             ["_le_fro_%s"%x for x in base.direct.mouseEvents] +\
-                             ["_le_lef_%s"%x for x in base.direct.mouseEvents] +\
-                             ["_le_top_%s"%x for x in base.direct.mouseEvents]
-            base.direct.mouseEvents = newMouseEvents
-            base.direct.enableMouseEvents()
-
-            base.direct.disableKeyEvents()
-            keyEvents = ["_le_per_%s"%x for x in base.direct.keyEvents] +\
-                             ["_le_fro_%s"%x for x in base.direct.keyEvents] +\
-                             ["_le_lef_%s"%x for x in base.direct.keyEvents] +\
-                             ["_le_top_%s"%x for x in base.direct.keyEvents]
-            base.direct.keyEvents = keyEvents
-            base.direct.enableKeyEvents()
-
-            base.direct.disableModifierEvents()
-            modifierEvents = ["_le_per_%s"%x for x in base.direct.modifierEvents] +\
-                             ["_le_fro_%s"%x for x in base.direct.modifierEvents] +\
-                             ["_le_lef_%s"%x for x in base.direct.modifierEvents] +\
-                             ["_le_top_%s"%x for x in base.direct.modifierEvents]
-            base.direct.modifierEvents = modifierEvents
-            base.direct.enableModifierEvents()
-
-            base.direct.cameraControl.lockRoll = True
-            base.direct.setFScaleWidgetByCam(1)
+            direct = ShowBaseGlobal.direct
+
+            direct.disableMouseEvents()
+            newMouseEvents = ["_le_per_%s"%x for x in direct.mouseEvents] +\
+                             ["_le_fro_%s"%x for x in direct.mouseEvents] +\
+                             ["_le_lef_%s"%x for x in direct.mouseEvents] +\
+                             ["_le_top_%s"%x for x in direct.mouseEvents]
+            direct.mouseEvents = newMouseEvents
+            direct.enableMouseEvents()
+
+            direct.disableKeyEvents()
+            keyEvents = ["_le_per_%s"%x for x in direct.keyEvents] +\
+                             ["_le_fro_%s"%x for x in direct.keyEvents] +\
+                             ["_le_lef_%s"%x for x in direct.keyEvents] +\
+                             ["_le_top_%s"%x for x in direct.keyEvents]
+            direct.keyEvents = keyEvents
+            direct.enableKeyEvents()
+
+            direct.disableModifierEvents()
+            modifierEvents = ["_le_per_%s"%x for x in direct.modifierEvents] +\
+                             ["_le_fro_%s"%x for x in direct.modifierEvents] +\
+                             ["_le_lef_%s"%x for x in direct.modifierEvents] +\
+                             ["_le_top_%s"%x for x in direct.modifierEvents]
+            direct.modifierEvents = modifierEvents
+            direct.enableModifierEvents()
+
+            direct.cameraControl.lockRoll = True
+            direct.setFScaleWidgetByCam(1)
 
 
             unpickables = [
             unpickables = [
                 "z-guide",
                 "z-guide",
@@ -172,31 +176,31 @@ class WxPandaShell(WxAppShell):
                 "Sphere",]
                 "Sphere",]
 
 
             for unpickable in unpickables:
             for unpickable in unpickables:
-                base.direct.addUnpickable(unpickable)
+                direct.addUnpickable(unpickable)
 
 
-            base.direct.manipulationControl.optionalSkipFlags |= SKIP_UNPICKABLE
-            base.direct.manipulationControl.fAllowMarquee = 1
-            base.direct.manipulationControl.supportMultiView()
-            base.direct.cameraControl.useMayaCamControls = 1
-            base.direct.cameraControl.perspCollPlane = self.perspView.collPlane
-            base.direct.cameraControl.perspCollPlane2 = self.perspView.collPlane2
+            direct.manipulationControl.optionalSkipFlags |= SKIP_UNPICKABLE
+            direct.manipulationControl.fAllowMarquee = 1
+            direct.manipulationControl.supportMultiView()
+            direct.cameraControl.useMayaCamControls = 1
+            direct.cameraControl.perspCollPlane = self.perspView.collPlane
+            direct.cameraControl.perspCollPlane2 = self.perspView.collPlane2
 
 
-            for widget in base.direct.manipulationControl.widgetList:
+            for widget in direct.manipulationControl.widgetList:
                 widget.setBin('gui-popup', 0)
                 widget.setBin('gui-popup', 0)
                 widget.setDepthTest(0)
                 widget.setDepthTest(0)
 
 
             # [gjeon] to intercept messages here
             # [gjeon] to intercept messages here
-            base.direct.ignore('DIRECT-delete')
-            base.direct.ignore('DIRECT-select')
-            base.direct.ignore('DIRECT-preDeselectAll')
-            base.direct.ignore('DIRECT-toggleWidgetVis')
-            base.direct.fIgnoreDirectOnlyKeyMap = 1
+            direct.ignore('DIRECT-delete')
+            direct.ignore('DIRECT-select')
+            direct.ignore('DIRECT-preDeselectAll')
+            direct.ignore('DIRECT-toggleWidgetVis')
+            direct.fIgnoreDirectOnlyKeyMap = 1
 
 
             # [gjeon] do not use the old way of finding current DR
             # [gjeon] do not use the old way of finding current DR
-            base.direct.drList.tryToGetCurrentDr = False
+            direct.drList.tryToGetCurrentDr = False
 
 
         else:
         else:
-            base.direct=None
+            base.direct = None
         #base.closeWindow(base.win)
         #base.closeWindow(base.win)
         base.win = base.winList[3]
         base.win = base.winList[3]
 
 

部分文件因为文件数量过多而无法显示