Browse Source

showbase: allow DirectGui elements to be created before ShowBase

This is done by precreating aspect2d inside ShowBaseGlobal.
rdb 7 years ago
parent
commit
e6c2d3b609

+ 22 - 23
direct/src/gui/DirectGuiBase.py

@@ -80,7 +80,8 @@ __all__ = ['DirectGuiBase', 'DirectGuiWidget']
 
 
 
 
 from panda3d.core import *
 from panda3d.core import *
-from panda3d.direct import get_config_showbase
+from direct.showbase import ShowBaseGlobal
+from direct.showbase.ShowBase import ShowBase
 from . import DirectGuiGlobals as DGG
 from . import DirectGuiGlobals as DGG
 from .OnscreenText import *
 from .OnscreenText import *
 from .OnscreenGeom import *
 from .OnscreenGeom import *
@@ -633,7 +634,7 @@ class DirectGuiBase(DirectObject.DirectObject):
         """
         """
         # Need to tack on gui item specific id
         # Need to tack on gui item specific id
         gEvent = event + self.guiId
         gEvent = event + self.guiId
-        if get_config_showbase().GetBool('debug-directgui-msgs', False):
+        if ShowBase.config.GetBool('debug-directgui-msgs', False):
             from direct.showbase.PythonUtil import StackTrace
             from direct.showbase.PythonUtil import StackTrace
             print(gEvent)
             print(gEvent)
             print(StackTrace())
             print(StackTrace())
@@ -662,7 +663,7 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
     # Determine the default initial state for inactive (or
     # Determine the default initial state for inactive (or
     # unclickable) components.  If we are in edit mode, these are
     # unclickable) components.  If we are in edit mode, these are
     # actually clickable by default.
     # actually clickable by default.
-    guiEdit = get_config_showbase().GetBool('direct-gui-edit', 0)
+    guiEdit = ShowBase.config.GetBool('direct-gui-edit', False)
     if guiEdit:
     if guiEdit:
         inactiveInitState = DGG.NORMAL
         inactiveInitState = DGG.NORMAL
     else:
     else:
@@ -723,21 +724,24 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
         if self['guiId']:
         if self['guiId']:
             self.guiItem.setId(self['guiId'])
             self.guiItem.setId(self['guiId'])
         self.guiId = self.guiItem.getId()
         self.guiId = self.guiItem.getId()
-        if __dev__:
+
+        if ShowBaseGlobal.__dev__:
             guiObjectCollector.addLevel(1)
             guiObjectCollector.addLevel(1)
             guiObjectCollector.flushLevel()
             guiObjectCollector.flushLevel()
             # track gui items by guiId for tracking down leaks
             # track gui items by guiId for tracking down leaks
-            if hasattr(base, 'guiItems'):
-                if self.guiId in base.guiItems:
-                    base.notify.warning('duplicate guiId: %s (%s stomping %s)' %
-                                        (self.guiId, self,
-                                         base.guiItems[self.guiId]))
-                base.guiItems[self.guiId] = self
-                if hasattr(base, 'printGuiCreates'):
-                    printStack()
+            if ShowBase.config.GetBool('track-gui-items', True):
+                if not hasattr(ShowBase, 'guiItems'):
+                    ShowBase.guiItems = {}
+                if self.guiId in ShowBase.guiItems:
+                    ShowBase.notify.warning('duplicate guiId: %s (%s stomping %s)' %
+                                            (self.guiId, self,
+                                             ShowBase.guiItems[self.guiId]))
+                ShowBase.guiItems[self.guiId] = self
+
         # Attach button to parent and make that self
         # Attach button to parent and make that self
-        if (parent == None):
-            parent = aspect2d
+        if parent is None:
+            parent = ShowBaseGlobal.aspect2d
+
         self.assign(parent.attachNewNode(self.guiItem, self['sortOrder']))
         self.assign(parent.attachNewNode(self.guiItem, self['sortOrder']))
         # Update pose to initial values
         # Update pose to initial values
         if self['pos']:
         if self['pos']:
@@ -1024,17 +1028,12 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
 
 
     def destroy(self):
     def destroy(self):
         if hasattr(self, "frameStyle"):
         if hasattr(self, "frameStyle"):
-            if __dev__:
+            if ShowBaseGlobal.__dev__:
                 guiObjectCollector.subLevel(1)
                 guiObjectCollector.subLevel(1)
                 guiObjectCollector.flushLevel()
                 guiObjectCollector.flushLevel()
-                if hasattr(base, 'guiItems'):
-                    if self.guiId in base.guiItems:
-                        del base.guiItems[self.guiId]
-                    else:
-                        base.notify.warning(
-                            'DirectGuiWidget.destroy(): '
-                            'gui item %s not in base.guiItems' %
-                            self.guiId)
+                if hasattr(ShowBase, 'guiItems'):
+                    ShowBase.guiItems.pop(self.guiId, None)
+
             # Destroy children
             # Destroy children
             for child in self.getChildren():
             for child in self.getChildren():
                 childGui = self.guiDict.get(child.getName())
                 childGui = self.guiDict.get(child.getName())

+ 10 - 2
direct/src/showbase/ShowBase.py

@@ -400,7 +400,8 @@ class ShowBase(DirectObject.DirectObject):
         if self.__dev__ or self.config.GetBool('want-e3-hacks', False):
         if self.__dev__ or self.config.GetBool('want-e3-hacks', False):
             if self.config.GetBool('track-gui-items', True):
             if self.config.GetBool('track-gui-items', True):
                 # dict of guiId to gui item, for tracking down leaks
                 # dict of guiId to gui item, for tracking down leaks
-                self.guiItems = {}
+                if not hasattr(ShowBase, 'guiItems'):
+                    ShowBase.guiItems = {}
 
 
         # optionally restore the default gui sounds from 1.7.2 and earlier
         # optionally restore the default gui sounds from 1.7.2 and earlier
         if ConfigVariableBool('orig-gui-sounds', False).getValue():
         if ConfigVariableBool('orig-gui-sounds', False).getValue():
@@ -520,6 +521,8 @@ class ShowBase(DirectObject.DirectObject):
             if ShowBaseGlobal:
             if ShowBaseGlobal:
                 del ShowBaseGlobal.base
                 del ShowBaseGlobal.base
 
 
+        self.aspect2d.node().removeAllChildren()
+
         # [gjeon] restore sticky key settings
         # [gjeon] restore sticky key settings
         if self.config.GetBool('disable-sticky-keys', 0):
         if self.config.GetBool('disable-sticky-keys', 0):
             allowAccessibilityShortcutKeys(True)
             allowAccessibilityShortcutKeys(True)
@@ -1102,13 +1105,18 @@ class ShowBase(DirectObject.DirectObject):
         self.render2d.setMaterialOff(1)
         self.render2d.setMaterialOff(1)
         self.render2d.setTwoSided(1)
         self.render2d.setTwoSided(1)
 
 
+        # We've already created aspect2d in ShowBaseGlobal, for the
+        # benefit of creating DirectGui elements before ShowBase.
+        from . import ShowBaseGlobal
+
         ## The normal 2-d DisplayRegion has an aspect ratio that
         ## The normal 2-d DisplayRegion has an aspect ratio that
         ## matches the window, but its coordinate system is square.
         ## matches the window, but its coordinate system is square.
         ## This means anything we parent to render2d gets stretched.
         ## This means anything we parent to render2d gets stretched.
         ## For things where that makes a difference, we set up
         ## For things where that makes a difference, we set up
         ## aspect2d, which scales things back to the right aspect
         ## aspect2d, which scales things back to the right aspect
         ## ratio along the X axis (Z is still from -1 to 1)
         ## ratio along the X axis (Z is still from -1 to 1)
-        self.aspect2d = self.render2d.attachNewNode(PGTop("aspect2d"))
+        self.aspect2d = ShowBaseGlobal.aspect2d
+        self.aspect2d.reparentTo(self.render2d)
 
 
         aspectRatio = self.getAspectRatio()
         aspectRatio = self.getAspectRatio()
         self.aspect2d.setScale(1.0 / aspectRatio, 1.0, 1.0)
         self.aspect2d.setScale(1.0 / aspectRatio, 1.0, 1.0)

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

@@ -11,6 +11,7 @@ from .ShowBase import ShowBase, WindowControls
 from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify
 from panda3d.core import VirtualFileSystem, Notify, ClockObject, PandaSystem
 from panda3d.core import VirtualFileSystem, Notify, ClockObject, PandaSystem
 from panda3d.core import ConfigPageManager, ConfigVariableManager
 from panda3d.core import ConfigPageManager, ConfigVariableManager
+from panda3d.core import NodePath, PGTop
 from panda3d.direct import get_config_showbase
 from panda3d.direct import get_config_showbase
 
 
 config = get_config_showbase()
 config = get_config_showbase()
@@ -23,6 +24,9 @@ cpMgr = ConfigPageManager.getGlobalPtr()
 cvMgr = ConfigVariableManager.getGlobalPtr()
 cvMgr = ConfigVariableManager.getGlobalPtr()
 pandaSystem = PandaSystem.getGlobalPtr()
 pandaSystem = PandaSystem.getGlobalPtr()
 
 
+# This is defined here so GUI elements can be instantiated before ShowBase.
+aspect2d = NodePath(PGTop("aspect2d"))
+
 # Set direct notify categories now that we have config
 # Set direct notify categories now that we have config
 directNotify.setDconfigLevels()
 directNotify.setDconfigLevels()