main.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #!/usr/bin/env python
  2. '''
  3. Demonstrate different mouse modes
  4. '''
  5. # from panda3d.core import loadPrcFileData
  6. #
  7. # loadPrcFileData("", "notify-level-x11display debug")
  8. # loadPrcFileData("", "notify-level-windisplay debug")
  9. #
  10. # loadPrcFileData("", "load-display p3tinydisplay")
  11. from panda3d.core import WindowProperties, TextNode
  12. from direct.task.TaskManagerGlobal import taskMgr
  13. from direct.gui.OnscreenText import OnscreenText
  14. from direct.task import Task
  15. from direct.showbase.ShowBase import ShowBase
  16. import sys
  17. class App(ShowBase):
  18. def __init__(self):
  19. ShowBase.__init__(self)
  20. self.base = self
  21. self.setup()
  22. def genLabelText(self, text, i):
  23. text = OnscreenText(text = text, pos = (-1.3, .5-.05*i), fg=(0,1,0,1),
  24. align = TextNode.ALeft, scale = .05)
  25. return text
  26. def setup(self):
  27. # Disable the camera trackball controls.
  28. self.disableMouse()
  29. # control mapping of mouse movement to box movement
  30. self.mouseMagnitude = 1
  31. self.rotateX, self.rotateY = 0, 0
  32. self.genLabelText("[0] Absolute mode, [1] Relative mode, [2] Confined mode", 0)
  33. self.base.accept('0', lambda: self.setMouseMode(WindowProperties.M_absolute))
  34. self.base.accept('1', lambda: self.setMouseMode(WindowProperties.M_relative))
  35. self.base.accept('2', lambda: self.setMouseMode(WindowProperties.M_confined))
  36. self.genLabelText("[C] Manually re-center mouse on each tick", 1)
  37. self.base.accept('C', lambda: self.toggleRecenter())
  38. self.base.accept('c', lambda: self.toggleRecenter())
  39. self.genLabelText("[S] Show mouse", 2)
  40. self.base.accept('S', lambda: self.toggleMouse())
  41. self.base.accept('s', lambda: self.toggleMouse())
  42. self.base.accept('escape', sys.exit, [0])
  43. self.mouseText = self.genLabelText("", 5)
  44. self.deltaText = self.genLabelText("", 6)
  45. self.positionText = self.genLabelText("", 8)
  46. self.lastMouseX, self.lastMouseY = None, None
  47. self.hideMouse = False
  48. self.setMouseMode(WindowProperties.M_absolute)
  49. self.manualRecenterMouse = True
  50. # make a box to move with the mouse
  51. self.model = self.loader.loadModel("box")
  52. self.model.reparentTo(self.render)
  53. self.cam.setPos(0, -5, 0)
  54. self.cam.lookAt(0, 0, 0)
  55. self.mouseTask = taskMgr.add(self.mouseTask, "Mouse Task")
  56. def setMouseMode(self, mode):
  57. print("Changing mode to %s" % mode)
  58. self.mouseMode = mode
  59. wp = WindowProperties()
  60. wp.setMouseMode(mode)
  61. self.base.win.requestProperties(wp)
  62. # these changes may require a tick to apply
  63. self.base.taskMgr.doMethodLater(0, self.resolveMouse, "Resolve mouse setting")
  64. def resolveMouse(self, t):
  65. wp = self.base.win.getProperties()
  66. actualMode = wp.getMouseMode()
  67. if self.mouseMode != actualMode:
  68. print("ACTUAL MOUSE MODE: %s" % actualMode)
  69. self.mouseMode = actualMode
  70. self.rotateX, self.rotateY = -.5, -.5
  71. self.lastMouseX, self.lastMouseY = None, None
  72. self.recenterMouse()
  73. def recenterMouse(self):
  74. self.base.win.movePointer(0,
  75. int(self.base.win.getProperties().getXSize() / 2),
  76. int(self.base.win.getProperties().getYSize() / 2))
  77. def toggleRecenter(self):
  78. print("Toggling re-center behavior")
  79. self.manualRecenterMouse = not self.manualRecenterMouse
  80. def toggleMouse(self):
  81. print("Toggling mouse visibility")
  82. self.hideMouse = not self.hideMouse
  83. wp = WindowProperties()
  84. wp.setCursorHidden(self.hideMouse)
  85. self.base.win.requestProperties(wp)
  86. def mouseTask(self, task):
  87. mw = self.base.mouseWatcherNode
  88. hasMouse = mw.hasMouse()
  89. if hasMouse:
  90. # get the window manager's idea of the mouse position
  91. x, y = mw.getMouseX(), mw.getMouseY()
  92. if self.lastMouseX is not None:
  93. # get the delta
  94. if self.manualRecenterMouse:
  95. # when recentering, the position IS the delta
  96. # since the center is reported as 0, 0
  97. dx, dy = x, y
  98. else:
  99. dx, dy = x - self.lastMouseX, y - self.lastMouseY
  100. else:
  101. # no data to compare with yet
  102. dx, dy = 0, 0
  103. self.lastMouseX, self.lastMouseY = x, y
  104. else:
  105. x, y, dx, dy = 0, 0, 0, 0
  106. if self.manualRecenterMouse:
  107. # move mouse back to center
  108. self.recenterMouse()
  109. self.lastMouseX, self.lastMouseY = 0, 0
  110. # scale position and delta to pixels for user
  111. w, h = self.win.getSize()
  112. self.mouseText.setText("Mode: {0}, Recenter: {1} | Mouse: {2}, {3} | hasMouse: {4}".format(
  113. self.mouseMode, self.manualRecenterMouse,
  114. int(x*w), int(y*h),
  115. hasMouse))
  116. self.deltaText.setText("Delta: {0}, {1}".format(
  117. int(dx*w), int(dy*h)))
  118. # rotate box by delta
  119. self.rotateX += dx * 10 * self.mouseMagnitude
  120. self.rotateY += dy * 10 * self.mouseMagnitude
  121. self.positionText.setText("Model rotation: {0}, {1}".format(
  122. int(self.rotateX*1000)/1000., int(self.rotateY*1000)/1000.))
  123. self.model.setH(self.rotateX)
  124. self.model.setP(self.rotateY)
  125. return Task.cont
  126. app = App()
  127. app.run()