source: trunk/src/testing/dim/overlayManager.py @ 4

Revision 4, 7.5 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1############################################################################
2#
3# DIM - A Direct Interaction Manager for SAGE
4# Copyright (C) 2007 Electronic Visualization Laboratory,
5# University of Illinois at Chicago
6#
7# All rights reserved.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions are met:
11#
12#  * Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14#  * Redistributions in binary form must reproduce the above
15#    copyright notice, this list of conditions and the following disclaimer
16#    in the documentation and/or other materials provided with the distribution.
17#  * Neither the name of the University of Illinois at Chicago nor
18#    the names of its contributors may be used to endorse or promote
19#    products derived from this software without specific prior written permission.
20#
21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32#
33# Direct questions, comments etc about SAGE UI to www.evl.uic.edu/cavern/forum
34#
35# Author: Ratko Jagodic
36#       
37############################################################################
38
39
40
41from globals import *
42from threading import RLock
43import os, os.path
44
45
46
47class OverlayManager:
48    """ creates and deletes all overlays """
49
50    def __init__(self):
51        self.overlays = {}            # key=overlayId, value=overlay objects
52        self.__appOverlays = {}       # key=appId, value=list of overlayIds
53        self.evtMgr = getEvtMgr()
54        self.sageGate = getSageGate()
55        self.addOverlayLock = RLock()  # for adding one overlay at a time
56        self.addOverlayQueue = []
57
58        # load all the plugins now
59        self.__overlayPlugins = {}  # key=overlayType, value=overlayPlugin
60        self.__loadAllPlugins()
61       
62        # register for events
63        self.evtMgr.register(EVT_NEW_APP, self.__onNewApp)
64        self.evtMgr.register(EVT_APP_KILLED, self.__onAppKilled)
65        self.evtMgr.register(EVT_OBJECT_INFO, self.__onObjectInfo)
66
67        # add other overlays
68        self.__addOverlays()
69       
70        self.specialDevice = 0
71       
72    def __addOverlays(self):
73        """ you can add overlays here manually """
74        pass
75       
76       
77    def __onNewApp(self, event):
78        """ add the overlays that need to be tied to the app """
79        self.__appOverlays[event.app.getId()] = []   # create the list for keeping overlays
80        self.addOverlay(OVERLAY_APP, None, event.app)
81
82
83    def __onAppKilled(self, event):
84        """ remove the overlays tied to the app """
85        appId = event.app.getId()
86        if appId in self.__appOverlays:
87            for overlayId in self.__appOverlays[appId]:
88                self.overlays[overlayId].destroy()
89                self.removeOverlay(overlayId)
90            del self.__appOverlays[appId]
91
92 
93    def __onObjectInfo(self, event):
94        """ the overlay was successfully added by SAGE and we got the overlayId """
95        self.addOverlayLock.acquire()
96        overlayType, callback, app, displayId = self.addOverlayQueue.pop(0)
97
98        # now add a new one (if there are any)
99        if len(self.addOverlayQueue) > 0:
100            # determine the draw order
101            drawOrder = INTER_DRAW   #inter draw
102            if overlayType == OVERLAY_POINTER:
103                drawOrder = POST_DRAW
104            elif overlayType == OVERLAY_WALL:
105                drawOrder = PRE_DRAW
106            self.sageGate.addOverlay(self.addOverlayQueue[0][0],100,100,100,100, True, drawOrder, displayId)
107        self.addOverlayLock.release()
108
109        # if overlayPlugin isn't loaded yet
110        if overlayType not in self.__overlayPlugins: 
111            if not self.__loadOverlayPlugin( overlayType ):
112                return   # couldn't load the plugin
113
114        # at this point we have a plugin loaded so create an overlay object
115        if app: # is the overlay tied to the application?
116            newOverlayObj = self.__overlayPlugins[ overlayType ].makeNew(event.overlayId, app)
117            self.__appOverlays[app.getId()].append(event.overlayId)
118        else:
119            newOverlayObj = self.__overlayPlugins[ overlayType ].makeNew(event.overlayId)
120        self.overlays[ event.overlayId ] = newOverlayObj
121        if self.specialDevice == 1:
122            self.overlays[event.overlayId].setSpecialDevice(1)
123
124        # finally report back to the entity that requested the overlay
125        if callback:
126            callback(newOverlayObj)
127
128    def setSpecialDevice(self, value):
129        for i in self.overlays:
130            self.overlays[i].setSpecialDevice(value)
131        self.specialDevice = value
132
133    def removeOverlay(self, overlayId):
134        """ removes the overlay from SAGE and locally """
135        self.sageGate.removeOverlay(overlayId)
136        if overlayId in self.overlays:
137            del self.overlays[overlayId]
138
139
140    def removeAllOverlays(self):
141        for overlayId in self.overlays.keys():
142            self.removeOverlay(overlayId)
143           
144
145    def addOverlay(self, overlayType, callback=None, app=None, displayId=0):
146        """ specify an optional callback to call once the
147            overlay is successfully added by SAGE
148            Specify an app if you want the overlay to be tied to an application
149            (if so it will be deleted when the app is closed)
150        """
151        self.addOverlayLock.acquire()
152
153        # determine the draw order
154        drawOrder = INTER_DRAW   #inter draw
155        if overlayType == OVERLAY_POINTER:
156            drawOrder = POST_DRAW     
157        elif overlayType == OVERLAY_WALL:
158            drawOrder = PRE_DRAW
159           
160        # if this is the only thing to add, just do it now
161        # otherwise it will be added by the __onObjectInfo when the previous one gets added
162        self.addOverlayQueue.append((overlayType, callback, app, displayId))
163        if len(self.addOverlayQueue) == 1:
164            self.sageGate.addOverlay(overlayType,0,0,100,100, True, drawOrder, displayId)
165           
166        self.addOverlayLock.release()
167
168
169       
170    def __loadAllPlugins(self):
171        """ goes into the 'overlays' directory and loads all the plugins from there """
172
173        for entry in os.listdir("overlays"):
174            if os.path.splitext(entry)[1] == ".py" and entry != "__init__.py":
175                self.__loadOverlayPlugin( os.path.splitext(entry)[0] )
176           
177
178    def __loadOverlayPlugin(self, overlayType):
179        """ try to load the overlayPlugin for the requested overlayType """
180        try:
181            overlayPlugin = __import__("overlays."+overlayType, globals(), locals(), [overlayType])
182            self.__overlayPlugins[ overlayType ] = overlayPlugin
183            print "Overlay plugin loaded: ", overlayType
184            return True
185       
186        except ImportError:
187            return False   # failed to load the module
188
189   
Note: See TracBrowser for help on using the repository browser.