175 lines
5.4 KiB
Python
175 lines
5.4 KiB
Python
|
#!/usr/bin/env python
|
||
|
'''
|
||
|
Demonstrate different mouse modes
|
||
|
'''
|
||
|
|
||
|
# from panda3d.core import loadPrcFileData
|
||
|
#
|
||
|
# loadPrcFileData("", "notify-level-x11display debug")
|
||
|
# loadPrcFileData("", "notify-level-windisplay debug")
|
||
|
#
|
||
|
# loadPrcFileData("", "load-display p3tinydisplay")
|
||
|
|
||
|
from panda3d.core import WindowProperties, TextNode
|
||
|
from direct.task.TaskManagerGlobal import taskMgr
|
||
|
from direct.gui.OnscreenText import OnscreenText
|
||
|
from direct.task import Task
|
||
|
from direct.showbase.ShowBase import ShowBase
|
||
|
|
||
|
import sys
|
||
|
|
||
|
class App(ShowBase):
|
||
|
def __init__(self):
|
||
|
ShowBase.__init__(self)
|
||
|
self.base = self
|
||
|
self.setup()
|
||
|
|
||
|
def genLabelText(self, text, i):
|
||
|
text = OnscreenText(text = text, pos = (-1.3, .5-.05*i), fg=(0,1,0,1),
|
||
|
align = TextNode.ALeft, scale = .05)
|
||
|
return text
|
||
|
|
||
|
|
||
|
def setup(self):
|
||
|
# Disable the camera trackball controls.
|
||
|
self.disableMouse()
|
||
|
|
||
|
# control mapping of mouse movement to box movement
|
||
|
self.mouseMagnitude = 1
|
||
|
|
||
|
self.rotateX, self.rotateY = 0, 0
|
||
|
|
||
|
self.genLabelText("[0] Absolute mode, [1] Relative mode, [2] Confined mode", 0)
|
||
|
|
||
|
self.base.accept('0', lambda: self.setMouseMode(WindowProperties.M_absolute))
|
||
|
self.base.accept('1', lambda: self.setMouseMode(WindowProperties.M_relative))
|
||
|
self.base.accept('2', lambda: self.setMouseMode(WindowProperties.M_confined))
|
||
|
|
||
|
self.genLabelText("[C] Manually re-center mouse on each tick", 1)
|
||
|
self.base.accept('C', lambda: self.toggleRecenter())
|
||
|
self.base.accept('c', lambda: self.toggleRecenter())
|
||
|
|
||
|
self.genLabelText("[S] Show mouse", 2)
|
||
|
self.base.accept('S', lambda: self.toggleMouse())
|
||
|
self.base.accept('s', lambda: self.toggleMouse())
|
||
|
|
||
|
self.base.accept('escape', sys.exit, [0])
|
||
|
|
||
|
self.mouseText = self.genLabelText("", 5)
|
||
|
self.deltaText = self.genLabelText("", 6)
|
||
|
self.positionText = self.genLabelText("", 8)
|
||
|
|
||
|
self.lastMouseX, self.lastMouseY = None, None
|
||
|
|
||
|
self.hideMouse = False
|
||
|
|
||
|
self.setMouseMode(WindowProperties.M_absolute)
|
||
|
self.manualRecenterMouse = True
|
||
|
|
||
|
# make a box to move with the mouse
|
||
|
self.model = self.loader.loadModel("box")
|
||
|
self.model.reparentTo(self.render)
|
||
|
|
||
|
self.cam.setPos(0, -5, 0)
|
||
|
self.cam.lookAt(0, 0, 0)
|
||
|
|
||
|
self.mouseTask = taskMgr.add(self.mouseTask, "Mouse Task")
|
||
|
|
||
|
def setMouseMode(self, mode):
|
||
|
print("Changing mode to %s" % mode)
|
||
|
|
||
|
self.mouseMode = mode
|
||
|
|
||
|
wp = WindowProperties()
|
||
|
wp.setMouseMode(mode)
|
||
|
self.base.win.requestProperties(wp)
|
||
|
|
||
|
# these changes may require a tick to apply
|
||
|
self.base.taskMgr.doMethodLater(0, self.resolveMouse, "Resolve mouse setting")
|
||
|
|
||
|
def resolveMouse(self, t):
|
||
|
wp = self.base.win.getProperties()
|
||
|
|
||
|
actualMode = wp.getMouseMode()
|
||
|
if self.mouseMode != actualMode:
|
||
|
print("ACTUAL MOUSE MODE: %s" % actualMode)
|
||
|
|
||
|
self.mouseMode = actualMode
|
||
|
|
||
|
self.rotateX, self.rotateY = -.5, -.5
|
||
|
self.lastMouseX, self.lastMouseY = None, None
|
||
|
self.recenterMouse()
|
||
|
|
||
|
def recenterMouse(self):
|
||
|
self.base.win.movePointer(0,
|
||
|
int(self.base.win.getProperties().getXSize() / 2),
|
||
|
int(self.base.win.getProperties().getYSize() / 2))
|
||
|
|
||
|
|
||
|
def toggleRecenter(self):
|
||
|
print("Toggling re-center behavior")
|
||
|
self.manualRecenterMouse = not self.manualRecenterMouse
|
||
|
|
||
|
def toggleMouse(self):
|
||
|
print("Toggling mouse visibility")
|
||
|
|
||
|
self.hideMouse = not self.hideMouse
|
||
|
|
||
|
wp = WindowProperties()
|
||
|
wp.setCursorHidden(self.hideMouse)
|
||
|
self.base.win.requestProperties(wp)
|
||
|
|
||
|
def mouseTask(self, task):
|
||
|
mw = self.base.mouseWatcherNode
|
||
|
|
||
|
hasMouse = mw.hasMouse()
|
||
|
if hasMouse:
|
||
|
# get the window manager's idea of the mouse position
|
||
|
x, y = mw.getMouseX(), mw.getMouseY()
|
||
|
|
||
|
if self.lastMouseX is not None:
|
||
|
# get the delta
|
||
|
if self.manualRecenterMouse:
|
||
|
# when recentering, the position IS the delta
|
||
|
# since the center is reported as 0, 0
|
||
|
dx, dy = x, y
|
||
|
else:
|
||
|
dx, dy = x - self.lastMouseX, y - self.lastMouseY
|
||
|
else:
|
||
|
# no data to compare with yet
|
||
|
dx, dy = 0, 0
|
||
|
|
||
|
self.lastMouseX, self.lastMouseY = x, y
|
||
|
|
||
|
else:
|
||
|
x, y, dx, dy = 0, 0, 0, 0
|
||
|
|
||
|
if self.manualRecenterMouse:
|
||
|
# move mouse back to center
|
||
|
self.recenterMouse()
|
||
|
self.lastMouseX, self.lastMouseY = 0, 0
|
||
|
|
||
|
# scale position and delta to pixels for user
|
||
|
w, h = self.win.getSize()
|
||
|
|
||
|
self.mouseText.setText("Mode: {0}, Recenter: {1} | Mouse: {2}, {3} | hasMouse: {4}".format(
|
||
|
self.mouseMode, self.manualRecenterMouse,
|
||
|
int(x*w), int(y*h),
|
||
|
hasMouse))
|
||
|
self.deltaText.setText("Delta: {0}, {1}".format(
|
||
|
int(dx*w), int(dy*h)))
|
||
|
|
||
|
# rotate box by delta
|
||
|
self.rotateX += dx * 10 * self.mouseMagnitude
|
||
|
self.rotateY += dy * 10 * self.mouseMagnitude
|
||
|
|
||
|
self.positionText.setText("Model rotation: {0}, {1}".format(
|
||
|
int(self.rotateX*1000)/1000., int(self.rotateY*1000)/1000.))
|
||
|
|
||
|
self.model.setH(self.rotateX)
|
||
|
self.model.setP(self.rotateY)
|
||
|
return Task.cont
|
||
|
|
||
|
app = App()
|
||
|
app.run()
|