DirectButton.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. from DirectFrame import *
  2. class DirectButton(DirectFrame):
  3. """
  4. DirectButton(parent) - Create a DirectGuiWidget which responds
  5. to mouse clicks and execute a callback function if defined
  6. """
  7. def __init__(self, parent = guiTop, **kw):
  8. # Inherits from DirectFrame
  9. # A Direct Frame can have:
  10. # - A background texture (pass in path to image, or Texture Card)
  11. # - A midground geometry item (pass in geometry)
  12. # - A foreground text Node (pass in text string or Onscreen Text)
  13. # For a direct button:
  14. # Each button has 4 states (ready, press, rollover, disabled)
  15. # The same image/geom/text can be used for all four states or each
  16. # state can have a different text/geom/image
  17. # State transitions happen automatically based upon mouse interaction
  18. # Responds to click event and calls command if None
  19. optiondefs = (
  20. # Define type of DirectGuiWidget
  21. ('pgFunc', PGButton, None),
  22. ('numStates', 4, None),
  23. ('invertedFrames', (1,), None),
  24. # Command to be called on button click
  25. ('command', None, None),
  26. ('extraArgs', [], None),
  27. # Which mouse buttons can be used to click the button
  28. ('commandButtons', (LMB,), self.setCommandButtons),
  29. # Sounds to be used for button events
  30. ('rolloverSound', None, self.setRolloverSound),
  31. ('clickSound', None, self.setClickSound),
  32. # Can only be specified at time of widget contruction
  33. # Do the text/graphics appear to move when the button is clicked
  34. ('pressEffect', 1, INITOPT),
  35. )
  36. # Merge keyword options with default options
  37. self.defineoptions(kw, optiondefs)
  38. # Initialize superclasses
  39. DirectFrame.__init__(self, parent)
  40. # If specifed, add scaling to the pressed state to make it look
  41. # like the button is moving when you press it
  42. if self['pressEffect']:
  43. np = self.stateNodePath[1].attachNewNode('pressEffect')
  44. np.setScale(0.98)
  45. self.stateNodePath[1] = np
  46. # Call option initialization functions
  47. self.initialiseoptions(DirectButton)
  48. def setCommandButtons(self):
  49. # Attach command function to specified buttons
  50. # Left mouse button
  51. if LMB in self['commandButtons']:
  52. self.guiItem.addClickButton(MouseButton.one())
  53. self.bind(B1CLICK, self.commandFunc)
  54. else:
  55. self.unbind(B1CLICK)
  56. self.guiItem.removeClickButton(MouseButton.one())
  57. # Middle mouse button
  58. if MMB in self['commandButtons']:
  59. self.guiItem.addClickButton(MouseButton.two())
  60. self.bind(B2CLICK, self.commandFunc)
  61. else:
  62. self.unbind(B2CLICK)
  63. self.guiItem.removeClickButton(MouseButton.two())
  64. # Right mouse button
  65. if RMB in self['commandButtons']:
  66. self.guiItem.addClickButton(MouseButton.three())
  67. self.bind(B3CLICK, self.commandFunc)
  68. else:
  69. self.unbind(B3CLICK)
  70. self.guiItem.removeClickButton(MouseButton.three())
  71. def commandFunc(self, event):
  72. if self['command']:
  73. # Pass any extra args to command
  74. apply(self['command'], self['extraArgs'])
  75. def setClickSound(self):
  76. if base.wantSfx:
  77. clickSound = self['clickSound']
  78. # Clear out sounds
  79. self.guiItem.clearSound(B1PRESS + self.guiId)
  80. self.guiItem.clearSound(B2PRESS + self.guiId)
  81. self.guiItem.clearSound(B3PRESS + self.guiId)
  82. if clickSound:
  83. if LMB in self['commandButtons']:
  84. self.guiItem.setSound(B1PRESS + self.guiId, clickSound)
  85. if MMB in self['commandButtons']:
  86. self.guiItem.setSound(B2PRESS + self.guiId, clickSound)
  87. if RMB in self['commandButtons']:
  88. self.guiItem.setSound(B3PRESS + self.guiId, clickSound)
  89. def setRolloverSound(self):
  90. if base.wantSfx:
  91. rolloverSound = self['rolloverSound']
  92. if rolloverSound:
  93. self.guiItem.setSound(ENTER + self.guiId, rolloverSound)
  94. else:
  95. self.guiItem.clearSound(ENTER + self.guiId)