DirectFrame.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. """A DirectFrame is a basic DirectGUI component that acts as the base
  2. class for various other components, and can also serve as a basic
  3. container to hold other DirectGUI components.
  4. A DirectFrame can have:
  5. * A background texture (pass in path to image, or Texture Card)
  6. * A midground geometry item (pass in geometry)
  7. * A foreground text Node (pass in text string or OnscreenText)
  8. Each of these has 1 or more states. The same object can be used for
  9. all states or each state can have a different text/geom/image (for
  10. radio button and check button indicators, for example).
  11. See the :ref:`directframe` page in the programming manual for a more in-depth
  12. explanation and an example of how to use this class.
  13. """
  14. __all__ = ['DirectFrame']
  15. from panda3d.core import *
  16. from . import DirectGuiGlobals as DGG
  17. from .DirectGuiBase import *
  18. from .OnscreenImage import OnscreenImage
  19. from .OnscreenGeom import OnscreenGeom
  20. from .OnscreenText import OnscreenText
  21. class DirectFrame(DirectGuiWidget):
  22. DefDynGroups = ('text', 'geom', 'image')
  23. def __init__(self, parent=None, **kw):
  24. # Inherits from DirectGuiWidget
  25. optiondefs = (
  26. # Define type of DirectGuiWidget
  27. ('pgFunc', PGItem, None),
  28. ('numStates', 1, None),
  29. ('state', self.inactiveInitState, None),
  30. # Frame can have:
  31. # A background texture
  32. ('image', None, self.setImage),
  33. # A midground geometry item
  34. ('geom', None, self.setGeom),
  35. # A foreground text node
  36. ('text', None, self.setText),
  37. # Change default value of text mayChange flag from 0
  38. # (OnscreenText.py) to 1
  39. ('textMayChange', 1, None),
  40. )
  41. # Merge keyword options with default options
  42. self.defineoptions(kw, optiondefs,
  43. dynamicGroups=DirectFrame.DefDynGroups)
  44. # Initialize superclasses
  45. DirectGuiWidget.__init__(self, parent)
  46. # Call option initialization functions
  47. self.initialiseoptions(DirectFrame)
  48. def __reinitComponent(self, name, component_class, states, **kwargs):
  49. """Recreates the given component using the given keyword args."""
  50. assert name in ("geom", "image", "text")
  51. # constants should be local to or default arguments of constructors
  52. for c in range(self['numStates']):
  53. component_name = name + str(c)
  54. try:
  55. state = states[c]
  56. except IndexError:
  57. state = states[-1]
  58. if self.hascomponent(component_name):
  59. if state is None:
  60. self.destroycomponent(component_name)
  61. else:
  62. self[component_name + "_" + name] = state
  63. else:
  64. if state is None:
  65. return
  66. kwargs[name] = state
  67. self.createcomponent(
  68. component_name,
  69. (),
  70. name,
  71. component_class,
  72. (),
  73. parent=self.stateNodePath[c],
  74. **kwargs
  75. )
  76. def clearText(self):
  77. self['text'] = None
  78. self.setText()
  79. def setText(self, text=None):
  80. if text is not None:
  81. self["text"] = text
  82. text = self["text"]
  83. if text is None or isinstance(text, str):
  84. text_list = (text,) * self['numStates']
  85. else:
  86. text_list = text
  87. self.__reinitComponent("text", OnscreenText, text_list,
  88. scale=1,
  89. mayChange=self['textMayChange'],
  90. sort=DGG.TEXT_SORT_INDEX)
  91. def clearGeom(self):
  92. self['geom'] = None
  93. self.setGeom()
  94. def setGeom(self, geom=None):
  95. if geom is not None:
  96. self["geom"] = geom
  97. geom = self["geom"]
  98. if geom is None or \
  99. isinstance(geom, NodePath) or \
  100. isinstance(geom, str):
  101. geom_list = (geom,) * self['numStates']
  102. else:
  103. geom_list = geom
  104. self.__reinitComponent("geom", OnscreenGeom, geom_list,
  105. scale=1,
  106. sort=DGG.GEOM_SORT_INDEX)
  107. def clearImage(self):
  108. self['image'] = None
  109. self.setImage()
  110. def setImage(self, image=None):
  111. if image is not None:
  112. self["image"] = image
  113. image = self["image"]
  114. if image is None or \
  115. isinstance(image, NodePath) or \
  116. isinstance(image, Texture) or \
  117. isinstance(image, str) or \
  118. isinstance(image, Filename) or \
  119. (len(image) == 2 and \
  120. isinstance(image[0], str) and \
  121. isinstance(image[1], str)):
  122. image_list = (image,) * self['numStates']
  123. else:
  124. image_list = image
  125. self.__reinitComponent("image", OnscreenImage, image_list,
  126. scale=1,
  127. sort=DGG.IMAGE_SORT_INDEX)