|
|
@@ -842,14 +842,14 @@ class ShowBase(DirectObject.DirectObject):
|
|
|
self.frameRateMeter.clearWindow()
|
|
|
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(
|
|
|
self.win, mouseWatcher=self.mouseWatcher,
|
|
|
- cam=self.camera, cam2d=self.camera2d,
|
|
|
+ cam=self.camera, camNode = self.camNode, cam2d=self.camera2d,
|
|
|
mouseKeyboard = self.dataRoot.find("**/*"))
|
|
|
- self.winControls.append(winCtrl)
|
|
|
-
|
|
|
+ self.winControls.append(winCtrl)
|
|
|
|
|
|
def setupRender(self):
|
|
|
"""
|
|
|
@@ -1221,19 +1221,68 @@ class ShowBase(DirectObject.DirectObject):
|
|
|
self.dataRootNode = self.dataRoot.node()
|
|
|
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,
|
|
|
using the indicated window. If the mouse has already been set
|
|
|
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:
|
|
|
mw = bt.getParent()
|
|
|
mk = mw.getParent()
|
|
|
bt.removeNode()
|
|
|
mw.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
|
|
|
# - MouseAndKeyboard
|
|
|
# - MouseWatcher
|
|
|
@@ -1251,8 +1300,8 @@ class ShowBase(DirectObject.DirectObject):
|
|
|
# MouseWatcher, while objects that want events in all cases, like the
|
|
|
# chat interface, should be parented to the MouseAndKeyboard.
|
|
|
|
|
|
- self.buttonThrowers = []
|
|
|
- self.pointerWatcherNodes = []
|
|
|
+ buttonThrowers = []
|
|
|
+ pointerWatcherNodes = []
|
|
|
for i in range(win.getNumInputDevices()):
|
|
|
name = win.getInputDeviceName(i)
|
|
|
mk = self.dataRoot.attachNewNode(MouseAndKeyboard(win, i, name))
|
|
|
@@ -1272,48 +1321,11 @@ class ShowBase(DirectObject.DirectObject):
|
|
|
mods.addButton(KeyboardButton.alt())
|
|
|
mods.addButton(KeyboardButton.meta())
|
|
|
bt.node().setModifierButtons(mods)
|
|
|
- self.buttonThrowers.append(bt)
|
|
|
+ buttonThrowers.append(bt)
|
|
|
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):
|
|
|
"""
|
|
|
@@ -2444,10 +2456,11 @@ class ShowBase(DirectObject.DirectObject):
|
|
|
# A class to encapsulate information necessary for multiwindow support.
|
|
|
class WindowControls:
|
|
|
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):
|
|
|
self.win = win
|
|
|
self.camera = cam
|
|
|
+ self.camNode = camNode
|
|
|
self.camera2d = cam2d
|
|
|
self.mouseWatcher = mouseWatcher
|
|
|
self.mouseKeyboard = mouseKeyboard
|