mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-28 15:53:55 -04:00
Merge branch 'release/1.10.x'
This commit is contained in:
commit
847ebf667f
@ -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):
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
73
tests/gui/test_DirectOptionMenu.py
Normal file
73
tests/gui/test_DirectOptionMenu.py
Normal 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
|
Loading…
x
Reference in New Issue
Block a user