Merge branch 'release/1.10.x'

This commit is contained in:
rdb 2019-11-06 10:49:05 +01:00
commit 847ebf667f
5 changed files with 99 additions and 11 deletions

View File

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

View File

@ -543,6 +543,8 @@ class ShowBase(DirectObject.DirectObject):
del ShowBaseGlobal.base del ShowBaseGlobal.base
self.aspect2d.node().removeAllChildren() self.aspect2d.node().removeAllChildren()
self.render2d.node().removeAllChildren()
self.aspect2d.reparent_to(self.render2d)
# [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):
@ -1107,8 +1109,12 @@ class ShowBase(DirectObject.DirectObject):
2-d objects and gui elements that are superimposed over the 2-d objects and gui elements that are superimposed over the
3-d geometry in the window. 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. ## 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 # Set up some overrides to turn off certain properties which
# we probably won't need for 2-d objects. # 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 ## 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 = ShowBaseGlobal.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)

View File

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

View File

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

View File

@ -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