leveleditor works on Mac too

This commit is contained in:
David Rose 2012-01-09 21:55:54 +00:00
parent 00a012ef13
commit 5e4ca78c07
9 changed files with 130 additions and 68 deletions

View File

@ -102,6 +102,8 @@ class ShowBase(DirectObject.DirectObject):
self.sfxManagerIsValidList = []
self.wantStats = self.config.GetBool('want-pstats', 0)
self.wantTk = False
self.wantWx = False
# Fill this in with a function to invoke when the user "exits"
# the program by closing the main window.
@ -341,7 +343,10 @@ class ShowBase(DirectObject.DirectObject):
__builtin__.aspect2dp = self.aspect2dp
__builtin__.pixel2dp = self.pixel2dp
ShowBase.notify.info('__dev__ == %s' % __dev__)
if not __dev__:
ShowBase.notify.debug('__dev__ == %s' % __dev__)
else:
ShowBase.notify.info('__dev__ == %s' % __dev__)
# set up recording of Functor creation stacks in __dev__
PythonUtil.recordFunctorCreationStacks()
@ -366,8 +371,9 @@ class ShowBase(DirectObject.DirectObject):
import Transitions
self.transitions = Transitions.Transitions(self.loader)
# Setup the window controls - handy for multiwindow applications
self.setupWindowControls()
if self.win:
# Setup the window controls - handy for multiwindow applications
self.setupWindowControls()
# Client sleep
sleepTime = self.config.GetFloat('client-sleep', 0.0)
@ -2643,20 +2649,21 @@ class ShowBase(DirectObject.DirectObject):
sys.exit()
# [gjeon] start wxPyhton
def startWx(self, fWantWx = 1):
self.wantWx = fWantWx
if self.wantWx:
initAppForGui()
from direct.showbase import WxGlobal
taskMgr.remove('wxLoop')
WxGlobal.spawnWxLoop()
def startWx(self, fWantWx = True):
fWantWx = bool(fWantWx)
if self.wantWx != fWantWx:
self.wantWx = fWantWx
if self.wantWx:
initAppForGui()
from direct.showbase import WxGlobal
WxGlobal.spawnWxLoop()
def startTk(self, fWantTk = 1):
self.wantTk = fWantTk
if self.wantTk:
def startTk(self, fWantTk = True):
fWantTk = bool(fWantTk)
if self.wantTk != fWantTk:
self.wantTk = fWantTk
initAppForGui()
from direct.showbase import TkGlobal
taskMgr.remove('tkLoop')
TkGlobal.spawnTkLoop()
def startDirect(self, fWantDirect = 1, fWantTk = 1, fWantWx = 0):

View File

@ -27,7 +27,7 @@ def tkLoop(self):
def spawnTkLoop():
# Spawn this task
taskMgr.remove('tkLoop')
taskMgr.add(tkLoop, "tkLoop")
taskMgr.remove('tkLoop')
spawnTkLoop()

View File

@ -18,4 +18,5 @@ def spawnWxLoop():
base.wxApp = wx.PySimpleApp(redirect = False)
# Spawn this task
taskMgr.remove('wxLoop')
taskMgr.add(wxLoop, "wxLoop")

View File

@ -12,6 +12,7 @@ from direct.showbase.DirectObject import DirectObject
from direct.directtools.DirectGrid import DirectGrid
from direct.showbase.ShowBase import WindowControls
from direct.directtools.DirectGlobals import *
from WxPandaWindow import WxPandaWindow
from pandac.PandaModules import WindowProperties, OrthographicLens, Point3, Plane, CollisionPlane, CollisionNode, NodePath
import wx
@ -46,7 +47,7 @@ class ViewportManager:
for v in ViewportManager.viewports:
v.Layout(*args, **kwargs)
class Viewport(wx.Panel, DirectObject):
class Viewport(WxPandaWindow, DirectObject):
"""Class representing a 3D Viewport."""
CREATENEW = CREATENEW
VPLEFT = VPLEFT
@ -56,10 +57,14 @@ class Viewport(wx.Panel, DirectObject):
def __init__(self, name, *args, **kwargs):
self.name = name
DirectObject.__init__(self)
wx.Panel.__init__(self, *args, **kwargs)
kwargs['gsg'] = ViewportManager.gsg
WxPandaWindow.__init__(self, *args, **kwargs)
ViewportManager.viewports.append(self)
self.win = None
if ViewportManager.gsg == None:
ViewportManager.gsg = self.win.getGsg()
self.camera = None
self.lens = None
self.camPos = None
@ -70,23 +75,10 @@ class Viewport(wx.Panel, DirectObject):
def initialize(self):
self.Update()
wp = WindowProperties()
wp.setOrigin(0, 0)
wp.setSize(self.ClientSize.GetWidth(), self.ClientSize.GetHeight())
assert self.GetHandle() != 0
wp.setParentWindow(self.GetHandle())
# initializing panda window
base.windowType = "onscreen"
props = WindowProperties.getDefault()
props.addProperties(wp)
self.win = base.openWindow(props = props, gsg = ViewportManager.gsg)
if self.win:
self.cam2d = base.makeCamera2d(self.win)
self.cam2d.node().setCameraMask(LE_CAM_MASKS[self.name])
if ViewportManager.gsg == None:
ViewportManager.gsg = self.win.getGsg()
self.cam = base.camList[-1]
self.camera = render.attachNewNode(self.name)
#self.camera.setName(self.name)
@ -135,18 +127,16 @@ class Viewport(wx.Panel, DirectObject):
"""Closes the viewport."""
if self.initialized:
wx.Window.Close(self)
base.closeWindow(self.win)
#base.closeWindow(self.win)
ViewportManager.viewports.remove(self)
def onSize(self, evt):
"""Invoked when the viewport is resized."""
WxPandaWindow.onSize(self, evt)
if self.win != None:
wp = WindowProperties()
wp.setOrigin(0, 0)
newWidth = self.ClientSize.GetWidth()
newHeight = self.ClientSize.GetHeight()
wp.setSize(newWidth, newHeight)
self.win.requestProperties(wp)
if hasattr(base, "direct") and base.direct:
for dr in base.direct.drList:

View File

@ -9,7 +9,7 @@ from direct.directtools.DirectGlobals import *
try:
base
except NameError:
base = ShowBase(False)
base = ShowBase(False, windowType = 'none')
from WxAppShell import *
from ViewPort import *
@ -196,7 +196,7 @@ class WxPandaShell(WxAppShell):
else:
base.direct=None
base.closeWindow(base.win)
#base.closeWindow(base.win)
base.win = base.winList[3]
def wxStep(self, task = None):

View File

@ -17,33 +17,60 @@ from panda3d.core import *
__all__ = ['WxPandaWindow']
if platform.system() != 'Darwin':
class EmbeddedPandaWindow(wx.Window):
""" This class implements a Panda3D window that is directly
embedded within the frame. It is fully supported on Windows,
partially supported on Linux, and not at all on OSX. """
class EmbeddedPandaWindow(wx.Window):
""" This class implements a Panda3D window that is directly
embedded within the frame. It is fully supported on Windows,
partially supported on Linux, and not at all on OSX. """
def __init__(self, *args, **kw):
wx.Window.__init__(self, *args, **kw)
def __init__(self, *args, **kw):
gsg = None
if 'gsg' in kw:
gsg = kw['gsg']
del kw['gsg']
wp = WindowProperties.getDefault()
base.startWx()
wx.Window.__init__(self, *args, **kw)
wp = WindowProperties.getDefault()
if platform.system() != 'Darwin':
wp.setParentWindow(self.GetHandle())
if base.win:
self.win = base.openWindow(props = wp)
else:
base.openDefaultWindow(props = wp)
self.win = base.win
if base.win:
self.win = base.openWindow(props = wp, gsg = gsg, type = 'onscreen')
else:
base.openDefaultWindow(props = wp, gsg = gsg, type = 'onscreen')
self.win = base.win
self.Bind(wx.EVT_SIZE, self.__resized)
self.Bind(wx.EVT_SIZE, self.onSize)
def __resized(self, event):
wp = WindowProperties()
wp.setOrigin(0, 0)
wp.setSize(*self.GetClientSizeTuple())
self.win.requestProperties(wp)
# This doesn't actually do anything, since wx won't call
# EVT_CLOSE on a child window, only on the toplevel window
# that contains it.
self.Bind(wx.EVT_CLOSE, self.__closeEvent)
if hasattr(wxgl, 'GLCanvas'):
def __closeEvent(self, event):
self.cleanup()
event.Skip()
def cleanup(self):
""" Parent windows should call cleanp() to clean up the
wxPandaWindow explicitly (since we can't catch EVT_CLOSE
directly). """
if self.win:
base.closeWindow(self.win)
self.win = None
self.Destroy()
def onSize(self, event):
wp = WindowProperties()
wp.setOrigin(0, 0)
wp.setSize(*self.GetClientSizeTuple())
self.win.requestProperties(wp)
event.Skip()
if not hasattr(wxgl, 'GLCanvas'):
OpenGLPandaWindow = None
else:
class OpenGLPandaWindow(wxgl.GLCanvas):
""" This class implements a Panda3D "window" that actually draws
within the wx GLCanvas object. It is supported whenever OpenGL is
@ -88,8 +115,18 @@ if hasattr(wxgl, 'GLCanvas'):
}
def __init__(self, *args, **kw):
gsg = None
if 'gsg' in kw:
gsg = kw['gsg']
del kw['gsg']
base.startWx()
wxgl.GLCanvas.__init__(self, *args, **kw)
# Can't share the GSG when a new wxgl.GLContext is created
# automatically.
gsg = None
callbackWindowDict = {
'Events' : self.__eventsCallback,
'Properties' : self.__propertiesCallback,
@ -111,14 +148,14 @@ if hasattr(wxgl, 'GLCanvas'):
self.SetCurrent()
if base.win:
self.win = base.openWindow(callbackWindowDict = callbackWindowDict, pipe = pipe)
self.win = base.openWindow(callbackWindowDict = callbackWindowDict, pipe = pipe, gsg = gsg, type = 'onscreen')
else:
base.openDefaultWindow(callbackWindowDict = callbackWindowDict, pipe = pipe)
base.openDefaultWindow(callbackWindowDict = callbackWindowDict, pipe = pipe, gsg = gsg, type = 'onscreen')
self.win = base.win
self.inputDevice = self.win.getInputDevice(0)
self.Bind(wx.EVT_SIZE, self.__resized)
self.Bind(wx.EVT_SIZE, self.onSize)
self.Bind(wx.EVT_LEFT_DOWN, lambda event: self.__buttonDown(MouseButton.one()))
self.Bind(wx.EVT_LEFT_UP, lambda event: self.__buttonUp(MouseButton.one()))
self.Bind(wx.EVT_MIDDLE_DOWN, lambda event: self.__buttonDown(MouseButton.two()))
@ -131,6 +168,24 @@ if hasattr(wxgl, 'GLCanvas'):
self.Bind(wx.EVT_KEY_UP, self.__keyUp)
self.Bind(wx.EVT_CHAR, self.__keystroke)
# This doesn't actually do anything, since wx won't call
# EVT_CLOSE on a child window, only on the toplevel window
# that contains it.
self.Bind(wx.EVT_CLOSE, self.__closeEvent)
def __closeEvent(self, event):
self.cleanup()
event.Skip()
def cleanup(self):
""" Parent windows should call cleanp() to clean up the
wxPandaWindow explicitly (since we can't catch EVT_CLOSE
directly). """
if self.win:
base.closeWindow(self.win)
self.win = None
self.Destroy()
def __buttonDown(self, button):
self.inputDevice.buttonDown(button)
@ -189,18 +244,23 @@ if hasattr(wxgl, 'GLCanvas'):
cbType = data.getCallbackType()
if cbType == CallbackGraphicsWindow.RCTBeginFrame:
self.SetCurrent()
if not self.IsShownOnScreen():
return False
elif cbType == CallbackGraphicsWindow.RCTEndFlip:
self.SwapBuffers()
data.upcall()
def __resized(self, event):
def onSize(self, event):
wp = WindowProperties()
wp.setSize(*self.GetClientSizeTuple())
self.win.requestProperties(wp)
event.Skip()
# Choose the best implementation of WxPandaWindow for the platform.
WxPandaWindow = None
if platform.system() == 'Darwin':
WxPandaWindow = OpenGLPandaWindow
else:
if not WxPandaWindow:
WxPandaWindow = EmbeddedPandaWindow

View File

@ -23,7 +23,7 @@ TypeHandle MouseAndKeyboard::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: MouseAndKeyboard::Constructor
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
MouseAndKeyboard::
@ -46,7 +46,7 @@ MouseAndKeyboard(GraphicsWindow *window, int device, const string &name) :
////////////////////////////////////////////////////////////////////
// Function: MouseAndKeyboard::set_source
// Access: Public
// Access: Published
// Description: Redirects the class to get the data from the mouse
// and keyboard associated with a different window
// and/or device number.
@ -59,7 +59,7 @@ set_source(GraphicsWindow *window, int device) {
////////////////////////////////////////////////////////////////////
// Function: MouseAndKeyboard::get_source_window
// Access: Public
// Access: Published
// Description: Returns the associated source window.
////////////////////////////////////////////////////////////////////
PT(GraphicsWindow) MouseAndKeyboard::
@ -69,7 +69,7 @@ get_source_window() const {
////////////////////////////////////////////////////////////////////
// Function: MouseAndKeyboard::get_source_device
// Access: Public
// Access: Published
// Description: Returns the associated source device.
////////////////////////////////////////////////////////////////////
int MouseAndKeyboard::

View File

@ -49,7 +49,6 @@ PUBLISHED:
MouseAndKeyboard(GraphicsWindow *window, int device, const string &name);
void set_source(GraphicsWindow *window, int device);
public:
PT(GraphicsWindow) get_source_window() const;
int get_source_device() const;

View File

@ -38,6 +38,11 @@ CallbackGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
#ifdef DO_MEMORY_USAGE
MemoryUsage::update_type(this, this);
#endif
// Let's ensure that these properties are set to *something*
// initially.
_properties.set_origin(0, 0);
_properties.set_size(0, 0);
}
////////////////////////////////////////////////////////////////////