Browse Source

Add sample program demonstrating the mouse modes

Ed Swartz 10 years ago
parent
commit
f6841d7fc5
1 changed files with 172 additions and 0 deletions
  1. 172 0
      samples/mouse-modes/main.py

+ 172 - 0
samples/mouse-modes/main.py

@@ -0,0 +1,172 @@
+#!/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()
+        
+        self.mouseMagnitude = 144
+
+        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.egg")
+        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",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:", 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()             
+
+        # 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.rotateY += dy * 10
+
+        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()