Exemple #1
0
class MousePointerDisplay:
    def __init__(self, game):
        
        self.log = logging.getLogger('pano.mouseDisplay')
        
        self.game = game
        self.resources = game.getResources()
        
        self.defaultScale = 0.05
        
        self.pointer = None
        
        #the parent node of the mouse pointer
        self.pointerParentNP = None
        
        #the mouse pointer node, it can be a ModelNode if the cursor is animated and was read by an .egg file
        #or it can be a OnScreenImage if the cursor is static
        self.mousePointer = None
        
        #True if the pointer is a static image and therefore is rendered through a OnScreenImage object
        self.isImagePointer = False
        
        #True if the mouse pointer is hidden
        self.mouseHidden = True 
        
        # the name of the image used as a pointer through a call to setImageAsPointer
        self.pointerImage = None                               
        
    def initialize(self):        
        self.pointerParentNP = render2d.attachNewNode('mousePointer')
        
        # create a GUI Layer for the pointer
        CullBinManager.getGlobalPtr().addBin(PanoConstants.MOUSE_CULL_BIN_NAME, CullBinManager.BTUnsorted, PanoConstants.MOUSE_CULL_BIN_VAL)
        
        # add task that updates the location of the mouse pointer
        taskMgr.add(self.updatePointerLocationTask, PanoConstants.TASK_MOUSE_POINTER)
        
    def isShown(self):
        return not self.mouseHidden
    
    def show(self):
        self.mouseHidden = False
        self.pointerParentNP.show()
 
                
    def hide(self):
        """
        Hides the mouse pointer.
        For image based pointers, the associated OnScreenImage is destroyed with a call to the member function destroy().
        While for model based pointers the associated model node is simply removed from the scenegraph. 
        """        
        self.mouseHidden = True
        self.pointerParentNP.hide()
            
    def _destroyPointer(self):        
        if self.mousePointer is not None:
            if self.isImagePointer:
                self.mousePointer.destroy()
                self.mousePointer = None                
            else:
                self.mousePointer.removeNode()
#                self.mousePointer.detachNode() 
            
            if self.pointerParentNP is not None:
                self.pointerParentNP.node().removeAllChildren()
                
            self.isImagePointer = False
            self.pointerImage = None
            self.mousePointer = None
            self.pointer = None
            self.mouseHidden = True
    
    def getScale(self):
        return self.scale
    
    def setScale(self, scale):
        self.scale = scale
        
    def setByName(self, pointerName):
        """
        Sets and displays the specified mouse pointer. If None is passed in place
        of the pointerName parameter, then the mouse pointer is hidden.
        
        Convention: A texture file or egg file with a base name equal
        to pointerName must exist in one of the resource locations
        associated with the cursors resource type.
        
        Convention: If the pointer name corresponds to an egg file, then
        the pointer is assumed to be animated. Otherwise the pointer is
        assumed to be a static image.
        
        Returns True if the pointer was set successfully and False if otherwise.
        """        
        pointerChanged = (self.pointer is None) or (pointerName != self.pointer.getName())
        if (pointerName is None) or pointerChanged:
            self._destroyPointer()
            
        if pointerChanged:
            self.pointer = self.game.getResources().loadPointer(pointerName)
            if self.pointer is None:
                self.log.error("Could'nt find pointer: %s", pointerName)
                return False
             
            if self.pointer.getModelFile() is not None:                
                self.isImagePointer = False
                self.mousePointer = self.game.getResources().loadModel(self.pointer.getModelFile())
                self.mousePointer.setScale(self.pointer.getScale() if self.pointer.getScale() is not None else self.defaultScale)
                self.mousePointer.setTag('model', 'True')
                self.mousePointer.reparentTo(self.pointerParentNP)
                self.isImagePointer = False
                self.pointerImage = None
            else:                
                self.setImageAsPointer(self.pointer.getTexture(), self.pointer.getScale())
                
            self.mousePointer.setTransparency(TransparencyAttrib.MAlpha)            
            self.mousePointer.setBin("fixed", PanoConstants.RENDER_ORDER_MOUSE_POINTER)
            self.mousePointer.setDepthTest(False)
            self.mousePointer.setDepthWrite(False)            
            self.mouseHidden = False
            self.show()
            
        return True   
    
    def setImageAsPointer(self, image, scale = None):
        self._destroyPointer()
        self.isImagePointer = True        
        texPath = self.game.getResources().getResourceFullPath(PanoConstants.RES_TYPE_TEXTURES, image)
        if texPath is not None:
            x, y = 0, 0
            if base.mouseWatcherNode.hasMouse():
                x=base.mouseWatcherNode.getMouseX()
                y=base.mouseWatcherNode.getMouseY()
                                                         
            self.mousePointer = OnscreenImage(
                                              parent=self.pointerParentNP, 
                                              image = texPath, 
                                              pos = Point3(x, 0, y), 
                                              scale = scale if scale is not None else self.defaultScale 
                                              )
            
            self.pointerImage = image
            self.mousePointer.setTransparency(TransparencyAttrib.MAlpha)            
            self.mousePointer.setBin("fixed", PanoConstants.RENDER_ORDER_MOUSE_POINTER)
            self.mousePointer.setDepthTest(False)
            self.mousePointer.setDepthWrite(False)            
            self.mouseHidden = False
            self.show()
            return True
        else:
            return False

    def getPosition(self):
        '''
        Returns the current location of the mouse pointer.
        @return: A (x, y) tuple containing the coordinates of the pointers in the coordinate of the render node.
        '''
        if self.mousePointer is not None:
            pos = self.mousePointer.getPos(render)            
            return (pos[0], pos[2])
        else:
            return (-1, 1)
            
    def updatePointerLocationTask(self, task):   
        if base.mouseWatcherNode.hasMouse():     
            if self.mousePointer is not None and not self.mouseHidden  and base.mouseWatcherNode.hasMouse() and not self.game.isPaused():
                x=base.mouseWatcherNode.getMouseX()
                y=base.mouseWatcherNode.getMouseY()            
                self.mousePointer.setPos(Point3(x, 0, y))
            
        return Task.cont

    def persistState(self, persistence):
        ctx = persistence.createContext('mouse_pointer')
        ctx.addVar('is_image', self.isImagePointer)
        ctx.addVar('scale', self.scale)
        ctx.addVar('pointer_name', self.pointer.getName() if self.pointer is not None else '')
        ctx.addVar('image', self.pointerImage if self.pointer is None else '')
        return ctx
    
    def resumeState(self, persistence):
        pass