"""A DirectFrame is a basic DirectGUI component that acts as the base
class for various other components, and can also serve as a basic
container to hold other DirectGUI components.
A DirectFrame can have:
* A background texture (pass in path to image, or Texture Card)
* A midground geometry item (pass in geometry)
* A foreground text Node (pass in text string or OnscreenText)
Each of these has 1 or more states. The same object can be used for
all states or each state can have a different text/geom/image (for
radio button and check button indicators, for example).
See the :ref:`directframe` page in the programming manual for a more in-depth
explanation and an example of how to use this class.
"""
__all__ = ['DirectFrame']
from panda3d.core import *
from . import DirectGuiGlobals as DGG
from .DirectGuiBase import *
from .OnscreenImage import OnscreenImage
from .OnscreenGeom import OnscreenGeom
from .OnscreenText import OnscreenText
[docs]class DirectFrame(DirectGuiWidget):
DefDynGroups = ('text', 'geom', 'image')
[docs] def __init__(self, parent=None, **kw):
# Inherits from DirectGuiWidget
optiondefs = (
# Define type of DirectGuiWidget
('pgFunc', PGItem, None),
('numStates', 1, None),
('state', self.inactiveInitState, None),
# Frame can have:
# A background texture
('image', None, self.setImage),
# A midground geometry item
('geom', None, self.setGeom),
# A foreground text node
('text', None, self.setText),
# Change default value of text mayChange flag from 0
# (OnscreenText.py) to 1
('textMayChange', 1, None),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs,
dynamicGroups=DirectFrame.DefDynGroups)
# Initialize superclasses
DirectGuiWidget.__init__(self, parent)
# Call option initialization functions
self.initialiseoptions(DirectFrame)
def __reinitComponent(self, name, component_class, states, **kwargs):
"""Recreates the given component using the given keyword args."""
assert name in ("geom", "image", "text")
# constants should be local to or default arguments of constructors
for c in range(self['numStates']):
component_name = name + str(c)
try:
state = states[c]
except IndexError:
state = states[-1]
if self.hascomponent(component_name):
if state is None:
self.destroycomponent(component_name)
else:
self[component_name + "_" + name] = state
else:
if state is None:
return
kwargs[name] = state
self.createcomponent(
component_name,
(),
name,
component_class,
(),
parent=self.stateNodePath[c],
**kwargs
)
[docs] def clearText(self):
self['text'] = None
self.setText()
[docs] def setText(self, text=None):
if text is not None:
self["text"] = text
text = self["text"]
if text is None or isinstance(text, str):
text_list = (text,) * self['numStates']
else:
text_list = text
self.__reinitComponent("text", OnscreenText, text_list,
scale=1,
mayChange=self['textMayChange'],
sort=DGG.TEXT_SORT_INDEX)
[docs] def clearGeom(self):
self['geom'] = None
self.setGeom()
[docs] def setGeom(self, geom=None):
if geom is not None:
self["geom"] = geom
geom = self["geom"]
if geom is None or \
isinstance(geom, NodePath) or \
isinstance(geom, str):
geom_list = (geom,) * self['numStates']
else:
geom_list = geom
self.__reinitComponent("geom", OnscreenGeom, geom_list,
scale=1,
sort=DGG.GEOM_SORT_INDEX)
[docs] def clearImage(self):
self['image'] = None
self.setImage()
[docs] def setImage(self, image=None):
if image is not None:
self["image"] = image
image = self["image"]
if image is None or \
isinstance(image, NodePath) or \
isinstance(image, Texture) or \
isinstance(image, str) or \
isinstance(image, Filename) or \
(len(image) == 2 and \
isinstance(image[0], str) and \
isinstance(image[1], str)):
image_list = (image,) * self['numStates']
else:
image_list = image
self.__reinitComponent("image", OnscreenImage, image_list,
scale=1,
sort=DGG.IMAGE_SORT_INDEX)