DirectButton.py 5.5 KB

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