still better open/close window behavior

This commit is contained in:
David Rose 2007-04-27 21:25:39 +00:00
parent 6c5d628b08
commit c99351eb7d

View File

@ -436,7 +436,8 @@ class ShowBase(DirectObject.DirectObject):
def openWindow(self, props = None, pipe = None, gsg = None, def openWindow(self, props = None, pipe = None, gsg = None,
type = None, name = None, size = None, aspectRatio = None, type = None, name = None, size = None, aspectRatio = None,
makeCamera = 1, scene = None, stereo = None, rawmice = 0): makeCamera = 1, keepCamera = 0,
scene = None, stereo = None, rawmice = 0):
""" """
Creates a window and adds it to the list of windows that are Creates a window and adds it to the list of windows that are
to be updated every frame. to be updated every frame.
@ -452,6 +453,19 @@ class ShowBase(DirectObject.DirectObject):
# We couldn't get a pipe. # We couldn't get a pipe.
return None return None
if isinstance(gsg, GraphicsOutput):
# If the gsg is a window or buffer, it means to use the
# GSG from that buffer.
gsg = gsg.getGsg()
# If we are using DirectX, force a new GSG to be created,
# since at the moment DirectX seems to misbehave if we do
# not do this. This will cause a delay while all textures
# etc. are reloaded, so we should revisit this later if we
# can fix the underlying bug in our DirectX support.
if pipe.getType().getName().startswith('wdx'):
gsg = None
if type == None: if type == None:
type = self.windowType type = self.windowType
@ -492,19 +506,28 @@ class ShowBase(DirectObject.DirectObject):
if hasattr(win, "requestProperties"): if hasattr(win, "requestProperties"):
win.requestProperties(props) win.requestProperties(props)
mainWindow = False
if self.win == None: if self.win == None:
mainWindow = True
self.win = win self.win = win
self.winList.append(win) self.winList.append(win)
# Set up a 3-d camera for the window by default. # Set up a 3-d camera for the window by default.
if makeCamera: if keepCamera:
self.makeCamera(win, scene = scene, aspectRatio = aspectRatio, self.makeCamera(win, scene = scene, aspectRatio = aspectRatio,
stereo = stereo, keepCam = makeCamera) stereo = stereo, useCamera = base.cam)
elif makeCamera:
self.makeCamera(win, scene = scene, aspectRatio = aspectRatio,
stereo = stereo)
messenger.send('open_window', [win, mainWindow])
if mainWindow:
messenger.send('open_main_window')
return win return win
def closeWindow(self, win): def closeWindow(self, win, keepCamera = 0):
""" """
Closes the indicated window and removes it from the list of Closes the indicated window and removes it from the list of
windows. If it is the main window, clears the main window windows. If it is the main window, clears the main window
@ -519,7 +542,9 @@ class ShowBase(DirectObject.DirectObject):
dr.setCamera(NodePath()) dr.setCamera(NodePath())
if not cam.isEmpty() and cam.node().getNumDisplayRegions() == 0: if not cam.isEmpty() and \
cam.node().getNumDisplayRegions() == 0 and \
not keepCamera:
# If the camera is used by no other DisplayRegions, # If the camera is used by no other DisplayRegions,
# remove it. # remove it.
if self.camList.count(cam) != 0: if self.camList.count(cam) != 0:
@ -539,19 +564,23 @@ class ShowBase(DirectObject.DirectObject):
self.graphicsEngine.removeWindow(win) self.graphicsEngine.removeWindow(win)
self.winList.remove(win) self.winList.remove(win)
messenger.send('close_window', [win]) mainWindow = False
if win == self.win:
mainWindow = True
self.win = None
if self.frameRateMeter:
self.frameRateMeter.clearWindow()
self.frameRateMeter = None
messenger.send('close_window', [win, mainWindow])
if mainWindow:
messenger.send('close_main_window')
if not self.winList: if not self.winList:
# Give the window(s) a chance to actually close before we # Give the window(s) a chance to actually close before we
# continue. # continue.
base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame()
if win == self.win:
self.win = None
if self.frameRateMeter:
self.frameRateMeter.clearWindow()
self.frameRateMeter = None
def openDefaultWindow(self, *args, **kw): def openDefaultWindow(self, *args, **kw):
# Creates the main window for the first time, without being # Creates the main window for the first time, without being
# too particular about the kind of graphics API that is # too particular about the kind of graphics API that is
@ -567,6 +596,13 @@ class ShowBase(DirectObject.DirectObject):
startDirect = kw.get('startDirect', True) startDirect = kw.get('startDirect', True)
if 'startDirect' in kw: if 'startDirect' in kw:
del kw['startDirect'] del kw['startDirect']
if self.win:
# If we've already opened a window before, this does
# little more work than openMainWindow() alone.
self.openMainWindow(*args, **kw)
self.graphicsEngine.openWindows()
return
self.openMainWindow(*args, **kw) self.openMainWindow(*args, **kw)
@ -597,6 +633,13 @@ class ShowBase(DirectObject.DirectObject):
# error not to open a window. # error not to open a window.
raise StandardError, 'Could not open window.' raise StandardError, 'Could not open window.'
# The default is trackball mode, which is more convenient for
# ad-hoc development in Python using ShowBase. Applications
# can explicitly call base.useDrive() if they prefer a drive
# interface.
self.mouseInterface = self.trackball
self.useTrackball()
if startDirect: if startDirect:
self.__doStartDirect() self.__doStartDirect()
@ -619,6 +662,8 @@ class ShowBase(DirectObject.DirectObject):
which case base.win may be either None, or the previous, which case base.win may be either None, or the previous,
closed window). closed window).
""" """
keepCamera = kw.get('keepCamera', 0)
success = 1 success = 1
oldWin = self.win oldWin = self.win
oldLens = self.camLens oldLens = self.camLens
@ -630,8 +675,8 @@ class ShowBase(DirectObject.DirectObject):
oldClearDepthActive = self.win.getClearDepthActive() oldClearDepthActive = self.win.getClearDepthActive()
oldClearDepth = self.win.getClearDepth() oldClearDepth = self.win.getClearDepth()
oldClearStencilActive = self.win.getClearStencilActive() oldClearStencilActive = self.win.getClearStencilActive()
oldClearStencil = self.win.getClearStencil() oldClearStencil = self.win.getClearStencil()
self.closeWindow(self.win) self.closeWindow(self.win, keepCamera = keepCamera)
# Open a new window. # Open a new window.
self.openWindow(*args, **kw) self.openWindow(*args, **kw)
@ -882,7 +927,7 @@ class ShowBase(DirectObject.DirectObject):
displayRegion = (0, 1, 0, 1), stereo = None, displayRegion = (0, 1, 0, 1), stereo = None,
aspectRatio = None, clearDepth = 0, clearColor = None, aspectRatio = None, clearDepth = 0, clearColor = None,
lens = None, camName = 'cam', mask = None, lens = None, camName = 'cam', mask = None,
keepCam = None): useCamera = None):
""" """
Makes a new 3-d camera associated with the indicated window, Makes a new 3-d camera associated with the indicated window,
and creates a display region in the indicated subrectangle. and creates a display region in the indicated subrectangle.
@ -892,8 +937,9 @@ class ShowBase(DirectObject.DirectObject):
camera is created. If stereo is None or omitted, a stereo camera is created. If stereo is None or omitted, a stereo
camera is created if the window says it can render in stereo. camera is created if the window says it can render in stereo.
If keepCam is a NodePath, that is used as the camera to apply If useCamera is not None, it is a NodePath to be used as the
to the window, rather than creating a new camera. camera to apply to the window, rather than creating a new
camera.
""" """
# self.camera is the parent node of all cameras: a node that # self.camera is the parent node of all cameras: a node that
# we can move around to move all cameras as a group. # we can move around to move all cameras as a group.
@ -901,10 +947,10 @@ class ShowBase(DirectObject.DirectObject):
self.camera = self.render.attachNewNode('camera') self.camera = self.render.attachNewNode('camera')
__builtin__.camera = self.camera __builtin__.camera = self.camera
if isinstance(keepCam, NodePath): if useCamera:
# Use the existing camera node. # Use the existing camera node.
cam = keepCam cam = useCamera
camNode = keepCam.node() camNode = useCamera.node()
assert(isinstance(camNode, Camera)) assert(isinstance(camNode, Camera))
lens = camNode.getLens() lens = camNode.getLens()
cam.reparentTo(self.camera) cam.reparentTo(self.camera)
@ -1130,13 +1176,6 @@ class ShowBase(DirectObject.DirectObject):
self.mouse2cam = self.dataUnused.attachNewNode(Transform2SG('mouse2cam')) self.mouse2cam = self.dataUnused.attachNewNode(Transform2SG('mouse2cam'))
self.mouse2cam.node().setNode(self.camera.node()) self.mouse2cam.node().setNode(self.camera.node())
# The default is trackball mode, which is more convenient for
# ad-hoc development in Python using ShowBase. Applications
# can explicitly call base.useDrive() if they prefer a drive
# interface.
self.mouseInterface = self.trackball
self.useTrackball()
# A special ButtonThrower to generate keyboard events and # A special ButtonThrower to generate keyboard events and
# include the time from the OS. This is separate only to # include the time from the OS. This is separate only to
# support legacy code that did not expect a time parameter; it # support legacy code that did not expect a time parameter; it