DirectFrame.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. from DirectGuiBase import *
  2. class DirectFrame(DirectGuiWidget):
  3. def __init__(self, parent = None, **kw):
  4. # Inherits from DirectGuiWidget
  5. # A Direct Frame can have:
  6. # - A background texture (pass in path to image, or Texture Card)
  7. # - A midground geometry item (pass in geometry)
  8. # - A foreground text Node (pass in text string or Onscreen Text)
  9. # Each of these has 1 or more states
  10. # The same object can be used for all states or each
  11. # state can have a different text/geom/image (for radio button
  12. # and check button indicators, for example).
  13. optiondefs = (
  14. # Define type of DirectGuiWidget
  15. ('pgFunc', PGItem, None),
  16. ('numStates', 1, None),
  17. ('state', self.inactiveInitState, None),
  18. # Frame can have:
  19. # A background texture
  20. ('image', None, self.setImage),
  21. # A midground geometry item
  22. ('geom', None, self.setGeom),
  23. # A foreground text node
  24. ('text', None, self.setText),
  25. # Change default value of text mayChange flag from 0
  26. # (OnscreenText.py) to 1
  27. ('textMayChange', 1, None),
  28. )
  29. # Merge keyword options with default options
  30. self.defineoptions(kw, optiondefs,
  31. dynamicGroups = ('text', 'geom', 'image'))
  32. # Initialize superclasses
  33. DirectGuiWidget.__init__(self, parent)
  34. # Call option initialization functions
  35. self.initialiseoptions(DirectFrame)
  36. def destroy(self):
  37. DirectGuiWidget.destroy(self)
  38. def setText(self):
  39. # Determine if user passed in single string or a sequence
  40. if self['text'] == None:
  41. textList = (None,) * self['numStates']
  42. elif isinstance(self['text'], types.StringTypes):
  43. # If just passing in a single string, make a tuple out of it
  44. textList = (self['text'],) * self['numStates']
  45. else:
  46. # Otherwise, hope that the user has passed in a tuple/list
  47. textList = self['text']
  48. # Create/destroy components
  49. for i in range(self['numStates']):
  50. component = 'text' + `i`
  51. # If fewer items specified than numStates,
  52. # just repeat last item
  53. try:
  54. text = textList[i]
  55. except IndexError:
  56. text = textList[-1]
  57. if self.hascomponent(component):
  58. if text == None:
  59. # Destroy component
  60. self.destroycomponent(component)
  61. else:
  62. self[component + '_text'] = text
  63. else:
  64. if text == None:
  65. return
  66. else:
  67. from OnscreenText import OnscreenText
  68. self.createcomponent(
  69. component, (), 'text',
  70. OnscreenText,
  71. (), parent = self.stateNodePath[i],
  72. text = text, scale = 1, mayChange = self['textMayChange'],
  73. sort = TEXT_SORT_INDEX,
  74. )
  75. def setGeom(self):
  76. # Determine argument type
  77. if self['geom'] == None:
  78. # Passed in None
  79. geomList = (None,) * self['numStates']
  80. elif isinstance(self['geom'], NodePath):
  81. # Passed in a single node path, make a tuple out of it
  82. geomList = (self['geom'],) * self['numStates']
  83. else:
  84. # Otherwise, hope that the user has passed in a tuple/list
  85. geomList = self['geom']
  86. # Create/destroy components
  87. for i in range(self['numStates']):
  88. component = 'geom' + `i`
  89. # If fewer items specified than numStates,
  90. # just repeat last item
  91. try:
  92. geom = geomList[i]
  93. except IndexError:
  94. geom = geomList[-1]
  95. if self.hascomponent(component):
  96. if geom == None:
  97. # Destroy component
  98. self.destroycomponent(component)
  99. else:
  100. self[component + '_geom'] = geom
  101. else:
  102. if geom == None:
  103. return
  104. else:
  105. self.createcomponent(
  106. component, (), 'geom',
  107. OnscreenGeom,
  108. (), parent = self.stateNodePath[i],
  109. geom = geom, scale = 1,
  110. sort = GEOM_SORT_INDEX)
  111. def setImage(self):
  112. # Determine argument type
  113. arg = self['image']
  114. if arg == None:
  115. # Passed in None
  116. imageList = (None,) * self['numStates']
  117. elif isinstance(arg, NodePath):
  118. imageList = (arg,) * self['numStates']
  119. elif isinstance(arg, types.StringTypes):
  120. # Passed in a single node path, make a tuple out of it
  121. imageList = (arg,) * self['numStates']
  122. else:
  123. # Otherwise, hope that the user has passed in a tuple/list
  124. if ((len(arg) == 2) and
  125. isinstance(arg[0], types.StringTypes) and
  126. isinstance(arg[1], types.StringTypes)):
  127. # Its a model/node pair of strings
  128. imageList = (arg,) * self['numStates']
  129. else:
  130. # Assume its a list of node paths
  131. imageList = arg
  132. # Create/destroy components
  133. for i in range(self['numStates']):
  134. component = 'image' + `i`
  135. # If fewer items specified than numStates,
  136. # just repeat last item
  137. try:
  138. image = imageList[i]
  139. except IndexError:
  140. image = imageList[-1]
  141. if self.hascomponent(component):
  142. if image == None:
  143. # Destroy component
  144. self.destroycomponent(component)
  145. else:
  146. self[component + '_image'] = image
  147. else:
  148. if image == None:
  149. return
  150. else:
  151. self.createcomponent(
  152. component, (), 'image',
  153. OnscreenImage,
  154. (), parent = self.stateNodePath[i],
  155. image = image, scale = 1,
  156. sort = IMAGE_SORT_INDEX)