Browse Source

Added support for multiple windows

Gyedo Jeon 16 years ago
parent
commit
2ea87673aa
1 changed files with 63 additions and 50 deletions
  1. 63 50
      direct/src/showbase/ShowBase.py

+ 63 - 50
direct/src/showbase/ShowBase.py

@@ -842,14 +842,14 @@ class ShowBase(DirectObject.DirectObject):
                 self.frameRateMeter.clearWindow()
                 self.frameRateMeter.clearWindow()
                 self.frameRateMeter = None
                 self.frameRateMeter = None
 
 
-    def setupWindowControls(self):
-        if not self.winControls:
+    # [gjeon] now you can add more winControls after creating a showbase instance
+    def setupWindowControls(self, winCtrl=None):
+        if winCtrl is None:
             winCtrl = WindowControls(
             winCtrl = WindowControls(
                 self.win, mouseWatcher=self.mouseWatcher,
                 self.win, mouseWatcher=self.mouseWatcher,
-                cam=self.camera, cam2d=self.camera2d,
+                cam=self.camera, camNode = self.camNode, cam2d=self.camera2d,
                 mouseKeyboard = self.dataRoot.find("**/*"))
                 mouseKeyboard = self.dataRoot.find("**/*"))
-            self.winControls.append(winCtrl)
-
+        self.winControls.append(winCtrl)
 
 
     def setupRender(self):
     def setupRender(self):
         """
         """
@@ -1221,19 +1221,68 @@ class ShowBase(DirectObject.DirectObject):
         self.dataRootNode = self.dataRoot.node()
         self.dataRootNode = self.dataRoot.node()
         self.dataUnused = NodePath('dataUnused')
         self.dataUnused = NodePath('dataUnused')
 
 
-    def setupMouse(self, win):
+    # [gjeon] now you can create multiple mouse watchers to support multiple windows
+    def setupMouse(self, win, fMultiWin=False):
         """
         """
         Creates the structures necessary to monitor the mouse input,
         Creates the structures necessary to monitor the mouse input,
         using the indicated window.  If the mouse has already been set
         using the indicated window.  If the mouse has already been set
         up for a different window, those structures are deleted first.
         up for a different window, those structures are deleted first.
         """
         """
-        if self.buttonThrowers != None:
+        if not fMultiWin and self.buttonThrowers != None:
             for bt in self.buttonThrowers:
             for bt in self.buttonThrowers:
                 mw = bt.getParent()
                 mw = bt.getParent()
                 mk = mw.getParent()
                 mk = mw.getParent()
                 bt.removeNode()
                 bt.removeNode()
                 mw.removeNode()
                 mw.removeNode()
                 mk.removeNode()
                 mk.removeNode()
+
+        bts, pws = self.setupMouseCB(win)
+
+        if fMultiWin:
+            return bts[0]
+        
+        self.buttonThrowers = bts[:]
+        self.pointerWatcherNodes = pws[:]
+
+        self.mouseWatcher = self.buttonThrowers[0].getParent()
+        self.mouseWatcherNode = self.mouseWatcher.node()  
+
+        if self.recorder:
+            # If we have a recorder, the mouseWatcher belongs under a
+            # special MouseRecorder node, which may intercept the
+            # mouse activity.
+            mw = self.buttonThrowers[0].getParent()
+            mouseRecorder = MouseRecorder('mouse')
+            self.recorder.addRecorder(
+                'mouse', mouseRecorder.upcastToRecorderBase())
+            np = mw.getParent().attachNewNode(mouseRecorder)
+            mw.reparentTo(np)
+
+        # Now we have the main trackball & drive interfaces.
+        # useTrackball() and useDrive() switch these in and out; only
+        # one is in use at a given time.
+        self.trackball = self.dataUnused.attachNewNode(Trackball('trackball'))
+        self.drive = self.dataUnused.attachNewNode(DriveInterface('drive'))
+        self.mouse2cam = self.dataUnused.attachNewNode(Transform2SG('mouse2cam'))
+        self.mouse2cam.node().setNode(self.camera.node())
+
+        # A special ButtonThrower to generate keyboard events and
+        # include the time from the OS.  This is separate only to
+        # support legacy code that did not expect a time parameter; it
+        # will eventually be folded into the normal ButtonThrower,
+        # above.
+        mw = self.buttonThrowers[0].getParent()
+        self.timeButtonThrower = mw.attachNewNode(ButtonThrower('timeButtons'))
+        self.timeButtonThrower.node().setPrefix('time-')
+        self.timeButtonThrower.node().setTimeFlag(1)
+
+        # Tell the gui system about our new mouse watcher.
+        self.aspect2d.node().setMouseWatcher(mw.node())
+        self.aspect2dp.node().setMouseWatcher(mw.node())
+        mw.node().addRegion(PGMouseWatcherBackground())
+
+    # [gjeon] this function is seperated from setupMouse to allow multiple mouse watchers
+    def setupMouseCB(self, win):
         # For each mouse/keyboard device, we create
         # For each mouse/keyboard device, we create
         #  - MouseAndKeyboard
         #  - MouseAndKeyboard
         #  - MouseWatcher
         #  - MouseWatcher
@@ -1251,8 +1300,8 @@ class ShowBase(DirectObject.DirectObject):
         # MouseWatcher, while objects that want events in all cases, like the
         # MouseWatcher, while objects that want events in all cases, like the
         # chat interface, should be parented to the MouseAndKeyboard.
         # chat interface, should be parented to the MouseAndKeyboard.
 
 
-        self.buttonThrowers = []
-        self.pointerWatcherNodes = []
+        buttonThrowers = []
+        pointerWatcherNodes = []
         for i in range(win.getNumInputDevices()):
         for i in range(win.getNumInputDevices()):
             name = win.getInputDeviceName(i)
             name = win.getInputDeviceName(i)
             mk = self.dataRoot.attachNewNode(MouseAndKeyboard(win, i, name))
             mk = self.dataRoot.attachNewNode(MouseAndKeyboard(win, i, name))
@@ -1272,48 +1321,11 @@ class ShowBase(DirectObject.DirectObject):
             mods.addButton(KeyboardButton.alt())
             mods.addButton(KeyboardButton.alt())
             mods.addButton(KeyboardButton.meta())
             mods.addButton(KeyboardButton.meta())
             bt.node().setModifierButtons(mods)
             bt.node().setModifierButtons(mods)
-            self.buttonThrowers.append(bt)
+            buttonThrowers.append(bt)
             if (win.hasPointer(i)):
             if (win.hasPointer(i)):
-                self.pointerWatcherNodes.append(mw.node())
-
-        self.mouseWatcher = self.buttonThrowers[0].getParent()
-        self.mouseWatcherNode = self.mouseWatcher.node()
-        # print "ButtonThrowers = ", self.buttonThrowers
-        # print "PointerWatcherNodes = ", self.pointerWatcherNodes
-
-        if self.recorder:
-            # If we have a recorder, the mouseWatcher belongs under a
-            # special MouseRecorder node, which may intercept the
-            # mouse activity.
-            mw = self.buttonThrowers[0].getParent()
-            mouseRecorder = MouseRecorder('mouse')
-            self.recorder.addRecorder(
-                'mouse', mouseRecorder.upcastToRecorderBase())
-            np = mw.getParent().attachNewNode(mouseRecorder)
-            mw.reparentTo(np)
-
-        # Now we have the main trackball & drive interfaces.
-        # useTrackball() and useDrive() switch these in and out; only
-        # one is in use at a given time.
-        self.trackball = self.dataUnused.attachNewNode(Trackball('trackball'))
-        self.drive = self.dataUnused.attachNewNode(DriveInterface('drive'))
-        self.mouse2cam = self.dataUnused.attachNewNode(Transform2SG('mouse2cam'))
-        self.mouse2cam.node().setNode(self.camera.node())
+                pointerWatcherNodes.append(mw.node())
 
 
-        # A special ButtonThrower to generate keyboard events and
-        # include the time from the OS.  This is separate only to
-        # support legacy code that did not expect a time parameter; it
-        # will eventually be folded into the normal ButtonThrower,
-        # above.
-        mw = self.buttonThrowers[0].getParent()
-        self.timeButtonThrower = mw.attachNewNode(ButtonThrower('timeButtons'))
-        self.timeButtonThrower.node().setPrefix('time-')
-        self.timeButtonThrower.node().setTimeFlag(1)
-
-        # Tell the gui system about our new mouse watcher.
-        self.aspect2d.node().setMouseWatcher(mw.node())
-        self.aspect2dp.node().setMouseWatcher(mw.node())
-        mw.node().addRegion(PGMouseWatcherBackground())
+        return buttonThrowers, pointerWatcherNodes
 
 
     def enableSoftwareMousePointer(self):
     def enableSoftwareMousePointer(self):
         """
         """
@@ -2444,10 +2456,11 @@ class ShowBase(DirectObject.DirectObject):
 # A class to encapsulate information necessary for multiwindow support.
 # A class to encapsulate information necessary for multiwindow support.
 class WindowControls:
 class WindowControls:
     def __init__(
     def __init__(
-            self, win, cam=None, cam2d=None, mouseWatcher=None,
+            self, win, cam=None, camNode=None, cam2d=None, mouseWatcher=None,
             mouseKeyboard=None, closeCmd=lambda: 0):
             mouseKeyboard=None, closeCmd=lambda: 0):
         self.win = win
         self.win = win
         self.camera = cam
         self.camera = cam
+        self.camNode = camNode
         self.camera2d = cam2d
         self.camera2d = cam2d
         self.mouseWatcher = mouseWatcher
         self.mouseWatcher = mouseWatcher
         self.mouseKeyboard = mouseKeyboard
         self.mouseKeyboard = mouseKeyboard