DirectButton.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. """Undocumented Module"""
  2. __all__ = ['DirectButton']
  3. from panda3d.core import *
  4. import DirectGuiGlobals as DGG
  5. from DirectFrame import *
  6. class DirectButton(DirectFrame):
  7. """
  8. DirectButton(parent) - Create a DirectGuiWidget which responds
  9. to mouse clicks and execute a callback function if defined
  10. """
  11. def __init__(self, parent = None, **kw):
  12. # Inherits from DirectFrame
  13. # A Direct Frame can have:
  14. # - A background texture (pass in path to image, or Texture Card)
  15. # - A midground geometry item (pass in geometry)
  16. # - A foreground text Node (pass in text string or Onscreen Text)
  17. # For a direct button:
  18. # Each button has 4 states (ready, press, rollover, disabled)
  19. # The same image/geom/text can be used for all four states or each
  20. # state can have a different text/geom/image
  21. # State transitions happen automatically based upon mouse interaction
  22. # Responds to click event and calls command if None
  23. optiondefs = (
  24. # Define type of DirectGuiWidget
  25. ('pgFunc', PGButton, None),
  26. ('numStates', 4, None),
  27. ('state', DGG.NORMAL, None),
  28. ('relief', DGG.RAISED, None),
  29. ('invertedFrames', (1,), None),
  30. # Command to be called on button click
  31. ('command', None, None),
  32. ('extraArgs', [], None),
  33. # Which mouse buttons can be used to click the button
  34. ('commandButtons', (DGG.LMB,), self.setCommandButtons),
  35. # Sounds to be used for button events
  36. ('rolloverSound', DGG.getDefaultRolloverSound(), self.setRolloverSound),
  37. ('clickSound', DGG.getDefaultClickSound(), self.setClickSound),
  38. # Can only be specified at time of widget contruction
  39. # Do the text/graphics appear to move when the button is clicked
  40. ('pressEffect', 1, DGG.INITOPT),
  41. )
  42. # Merge keyword options with default options
  43. self.defineoptions(kw, optiondefs)
  44. # Initialize superclasses
  45. DirectFrame.__init__(self, parent)
  46. # If specifed, add scaling to the pressed state to make it
  47. # look like the button is moving when you press it. We have
  48. # to set up the node first, before we call initialise options;
  49. # but we can't actually apply the scale until we have the
  50. # bounding volume (which happens during initialise options).
  51. pressEffectNP = None
  52. if self['pressEffect']:
  53. pressEffectNP = self.stateNodePath[1].attachNewNode('pressEffect', 1)
  54. self.stateNodePath[1] = pressEffectNP
  55. # Call option initialization functions
  56. self.initialiseoptions(DirectButton)
  57. # Now apply the scale.
  58. if pressEffectNP:
  59. bounds = self.getBounds()
  60. centerX = (bounds[0] + bounds[1]) / 2
  61. centerY = (bounds[2] + bounds[3]) / 2
  62. # Make a matrix that scales about the point
  63. mat = Mat4.translateMat(-centerX, 0, -centerY) * \
  64. Mat4.scaleMat(0.98) * \
  65. Mat4.translateMat(centerX, 0, centerY)
  66. pressEffectNP.setMat(mat)
  67. def setCommandButtons(self):
  68. # Attach command function to specified buttons
  69. # Left mouse button
  70. if DGG.LMB in self['commandButtons']:
  71. self.guiItem.addClickButton(MouseButton.one())
  72. self.bind(DGG.B1CLICK, self.commandFunc)
  73. else:
  74. self.unbind(DGG.B1CLICK)
  75. self.guiItem.removeClickButton(MouseButton.one())
  76. # Middle mouse button
  77. if DGG.MMB in self['commandButtons']:
  78. self.guiItem.addClickButton(MouseButton.two())
  79. self.bind(DGG.B2CLICK, self.commandFunc)
  80. else:
  81. self.unbind(DGG.B2CLICK)
  82. self.guiItem.removeClickButton(MouseButton.two())
  83. # Right mouse button
  84. if DGG.RMB in self['commandButtons']:
  85. self.guiItem.addClickButton(MouseButton.three())
  86. self.bind(DGG.B3CLICK, self.commandFunc)
  87. else:
  88. self.unbind(DGG.B3CLICK)
  89. self.guiItem.removeClickButton(MouseButton.three())
  90. def commandFunc(self, event):
  91. if self['command']:
  92. # Pass any extra args to command
  93. apply(self['command'], self['extraArgs'])
  94. def setClickSound(self):
  95. clickSound = self['clickSound']
  96. # Clear out sounds
  97. self.guiItem.clearSound(DGG.B1PRESS + self.guiId)
  98. self.guiItem.clearSound(DGG.B2PRESS + self.guiId)
  99. self.guiItem.clearSound(DGG.B3PRESS + self.guiId)
  100. if clickSound:
  101. if DGG.LMB in self['commandButtons']:
  102. self.guiItem.setSound(DGG.B1PRESS + self.guiId, clickSound)
  103. if DGG.MMB in self['commandButtons']:
  104. self.guiItem.setSound(DGG.B2PRESS + self.guiId, clickSound)
  105. if DGG.RMB in self['commandButtons']:
  106. self.guiItem.setSound(DGG.B3PRESS + self.guiId, clickSound)
  107. def setRolloverSound(self):
  108. rolloverSound = self['rolloverSound']
  109. if rolloverSound:
  110. self.guiItem.setSound(DGG.ENTER + self.guiId, rolloverSound)
  111. else:
  112. self.guiItem.clearSound(DGG.ENTER + self.guiId)