Browse Source

Merge branch 'release/1.10.x'

rdb 6 years ago
parent
commit
847ebf667f

+ 15 - 8
direct/src/gui/DirectOptionMenu.py

@@ -7,11 +7,13 @@ in-depth explanation and an example of how to use this class.
 __all__ = ['DirectOptionMenu']
 
 from panda3d.core import *
+from direct.showbase import ShowBaseGlobal
 from . import DirectGuiGlobals as DGG
 from .DirectButton import *
 from .DirectLabel import *
 from .DirectFrame import *
 
+
 class DirectOptionMenu(DirectButton):
     """
     DirectOptionMenu(parent) - Create a DirectButton which pops up a
@@ -72,6 +74,10 @@ class DirectOptionMenu(DirectButton):
         self.popupMenu = None
         self.selectedIndex = None
         self.highlightedIndex = None
+        if 'item_text_scale' in kw:
+            self._prevItemTextScale = kw['item_text_scale']
+        else:
+            self._prevItemTextScale = (1,1)
         # A big screen encompassing frame to catch the cancel clicks
         self.cancelFrame = self.createcomponent(
             'cancelframe', (), None,
@@ -218,27 +224,27 @@ class DirectOptionMenu(DirectButton):
         self.popupMenu.setZ(
             self, self.minZ + (self.selectedIndex + 1)*self.maxHeight)
         # Make sure the whole popup menu is visible
-        pos = self.popupMenu.getPos(render2d)
-        scale = self.popupMenu.getScale(render2d)
+        pos = self.popupMenu.getPos(ShowBaseGlobal.render2d)
+        scale = self.popupMenu.getScale(ShowBaseGlobal.render2d)
         # How are we doing relative to the right side of the screen
         maxX = pos[0] + fb[1] * scale[0]
         if maxX > 1.0:
             # Need to move menu to the left
-            self.popupMenu.setX(render2d, pos[0] + (1.0 - maxX))
+            self.popupMenu.setX(ShowBaseGlobal.render2d, pos[0] + (1.0 - maxX))
         # How about up and down?
         minZ = pos[2] + fb[2] * scale[2]
         maxZ = pos[2] + fb[3] * scale[2]
         if minZ < -1.0:
             # Menu too low, move it up
-            self.popupMenu.setZ(render2d, pos[2] + (-1.0 - minZ))
+            self.popupMenu.setZ(ShowBaseGlobal.render2d, pos[2] + (-1.0 - minZ))
         elif maxZ > 1.0:
             # Menu too high, move it down
-            self.popupMenu.setZ(render2d, pos[2] + (1.0 - maxZ))
+            self.popupMenu.setZ(ShowBaseGlobal.render2d, pos[2] + (1.0 - maxZ))
         # Also display cancel frame to catch clicks outside of the popup
         self.cancelFrame.show()
         # Position and scale cancel frame to fill entire window
-        self.cancelFrame.setPos(render2d, 0, 0, 0)
-        self.cancelFrame.setScale(render2d, 1, 1, 1)
+        self.cancelFrame.setPos(ShowBaseGlobal.render2d, 0, 0, 0)
+        self.cancelFrame.setScale(ShowBaseGlobal.render2d, 1, 1, 1)
 
     def hidePopupMenu(self, event = None):
         """ Put away popup and cancel frame """
@@ -247,6 +253,7 @@ class DirectOptionMenu(DirectButton):
 
     def _highlightItem(self, item, index):
         """ Set frame color of highlighted item, record index """
+        self._prevItemTextScale = item['text_scale']
         item['frameColor'] = self['highlightColor']
         item['frameSize'] = (self['highlightScale'][0]*self.minX, self['highlightScale'][0]*self.maxX, self['highlightScale'][1]*self.minZ, self['highlightScale'][1]*self.maxZ)
         item['text_scale'] = self['highlightScale']
@@ -256,7 +263,7 @@ class DirectOptionMenu(DirectButton):
         """ Clear frame color, clear highlightedIndex """
         item['frameColor'] = frameColor
         item['frameSize'] = (self.minX, self.maxX, self.minZ, self.maxZ)
-        item['text_scale'] = (1,1)
+        item['text_scale'] = self._prevItemTextScale
         self.highlightedIndex = None
 
     def selectHighlightedIndex(self, event = None):

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

@@ -543,6 +543,8 @@ class ShowBase(DirectObject.DirectObject):
                 del ShowBaseGlobal.base
 
         self.aspect2d.node().removeAllChildren()
+        self.render2d.node().removeAllChildren()
+        self.aspect2d.reparent_to(self.render2d)
 
         # [gjeon] restore sticky key settings
         if self.config.GetBool('disable-sticky-keys', 0):
@@ -1107,8 +1109,12 @@ class ShowBase(DirectObject.DirectObject):
         2-d objects and gui elements that are superimposed over the
         3-d geometry in the window.
         """
+        # We've already created aspect2d in ShowBaseGlobal, for the
+        # benefit of creating DirectGui elements before ShowBase.
+        from . import ShowBaseGlobal
+
         ## This is the root of the 2-D scene graph.
-        self.render2d = NodePath('render2d')
+        self.render2d = ShowBaseGlobal.render2d
 
         # Set up some overrides to turn off certain properties which
         # we probably won't need for 2-d objects.
@@ -1139,7 +1145,6 @@ class ShowBase(DirectObject.DirectObject):
         ## aspect2d, which scales things back to the right aspect
         ## ratio along the X axis (Z is still from -1 to 1)
         self.aspect2d = ShowBaseGlobal.aspect2d
-        self.aspect2d.reparentTo(self.render2d)
 
         aspectRatio = self.getAspectRatio()
         self.aspect2d.setScale(1.0 / aspectRatio, 1.0, 1.0)

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

@@ -26,7 +26,8 @@ cvMgr = ConfigVariableManager.getGlobalPtr()
 pandaSystem = PandaSystem.getGlobalPtr()
 
 # This is defined here so GUI elements can be instantiated before ShowBase.
-aspect2d = NodePath(PGTop("aspect2d"))
+render2d = NodePath("render2d")
+aspect2d = render2d.attachNewNode(PGTop("aspect2d"))
 hidden = NodePath("hidden")
 
 # Set direct notify categories now that we have config

+ 2 - 0
panda/src/gobj/preparedGraphicsObjects.cxx

@@ -1343,6 +1343,8 @@ release_all_shader_buffers() {
        ++bci) {
 
     BufferContext *bc = (BufferContext *)(*bci);
+    ((ShaderBuffer *)bc->_object)->clear_prepared(this);
+    bc->_object = nullptr;
     _released_shader_buffers.push_back(bc);
   }
 

+ 73 - 0
tests/gui/test_DirectOptionMenu.py

@@ -0,0 +1,73 @@
+from direct.gui.DirectOptionMenu import DirectOptionMenu
+import pytest
+
+
+def test_menu_destroy():
+    menu = DirectOptionMenu(items=["item1", "item2"])
+    menu.destroy()
+
+
+def test_showPopupMenu():
+    menu = DirectOptionMenu()
+
+    # Showing an option menu without items will raise an exception
+    with pytest.raises(Exception):
+        menu.showPopupMenu()
+
+    menu["items"] = ["item1", "item2"]
+    menu.showPopupMenu()
+    assert not menu.popupMenu.isHidden()
+    assert not menu.cancelFrame.isHidden()
+
+    menu.hidePopupMenu()
+    assert menu.popupMenu.isHidden()
+    assert menu.cancelFrame.isHidden()
+
+
+def test_index():
+    menu = DirectOptionMenu(items=["item1", "item2"])
+    assert menu.index("item1") == 0
+    assert menu.index("item2") == 1
+
+
+def test_set_get():
+    menu = DirectOptionMenu(items=["item1", "item2"])
+    menu.set(1, False)
+    assert menu.selectedIndex == 1
+    assert menu.get() == "item2"
+    assert menu["text"] == "item2"
+
+
+def test_initialitem():
+    # initialitem by string
+    menuByStr = DirectOptionMenu(items=["item1", "item2"], initialitem="item2")
+    assert menuByStr.get() == "item2"
+    assert menuByStr["text"] == "item2"
+
+    # initialitem by Index
+    menuByIdx = DirectOptionMenu(items=["item1", "item2"], initialitem=1)
+    assert menuByIdx.get() == "item2"
+    assert menuByIdx["text"] == "item2"
+
+
+def test_item_text_scale():
+    highlightScale = (2, 2)
+    unhighlightScale = (0.5, 0.5)
+    menu = DirectOptionMenu(
+        items=["item1", "item2"],
+        item_text_scale=unhighlightScale,
+        highlightScale=highlightScale)
+
+    # initial scale
+    item = menu.component("item0")
+
+    item_text_scale = 0.8
+    assert item["text_scale"] == unhighlightScale
+
+    # highlight scale
+    menu._highlightItem(item, 0)
+    assert item["text_scale"] == highlightScale
+
+    # back to initial scale
+    menu._unhighlightItem(item, item["frameColor"])
+    assert item["text_scale"] == unhighlightScale