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

View File

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

View File

@ -18,4 +18,5 @@ def spawnWxLoop():
base.wxApp = wx.PySimpleApp(redirect = False) base.wxApp = wx.PySimpleApp(redirect = False)
# Spawn this task # Spawn this task
taskMgr.remove('wxLoop')
taskMgr.add(wxLoop, "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.directtools.DirectGrid import DirectGrid
from direct.showbase.ShowBase import WindowControls from direct.showbase.ShowBase import WindowControls
from direct.directtools.DirectGlobals import * from direct.directtools.DirectGlobals import *
from WxPandaWindow import WxPandaWindow
from pandac.PandaModules import WindowProperties, OrthographicLens, Point3, Plane, CollisionPlane, CollisionNode, NodePath from pandac.PandaModules import WindowProperties, OrthographicLens, Point3, Plane, CollisionPlane, CollisionNode, NodePath
import wx import wx
@ -46,7 +47,7 @@ class ViewportManager:
for v in ViewportManager.viewports: for v in ViewportManager.viewports:
v.Layout(*args, **kwargs) v.Layout(*args, **kwargs)
class Viewport(wx.Panel, DirectObject): class Viewport(WxPandaWindow, DirectObject):
"""Class representing a 3D Viewport.""" """Class representing a 3D Viewport."""
CREATENEW = CREATENEW CREATENEW = CREATENEW
VPLEFT = VPLEFT VPLEFT = VPLEFT
@ -56,10 +57,14 @@ class Viewport(wx.Panel, DirectObject):
def __init__(self, name, *args, **kwargs): def __init__(self, name, *args, **kwargs):
self.name = name self.name = name
DirectObject.__init__(self) DirectObject.__init__(self)
wx.Panel.__init__(self, *args, **kwargs)
kwargs['gsg'] = ViewportManager.gsg
WxPandaWindow.__init__(self, *args, **kwargs)
ViewportManager.viewports.append(self) ViewportManager.viewports.append(self)
self.win = None if ViewportManager.gsg == None:
ViewportManager.gsg = self.win.getGsg()
self.camera = None self.camera = None
self.lens = None self.lens = None
self.camPos = None self.camPos = None
@ -70,23 +75,10 @@ class Viewport(wx.Panel, DirectObject):
def initialize(self): def initialize(self):
self.Update() 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: if self.win:
self.cam2d = base.makeCamera2d(self.win) self.cam2d = base.makeCamera2d(self.win)
self.cam2d.node().setCameraMask(LE_CAM_MASKS[self.name]) self.cam2d.node().setCameraMask(LE_CAM_MASKS[self.name])
if ViewportManager.gsg == None:
ViewportManager.gsg = self.win.getGsg()
self.cam = base.camList[-1] self.cam = base.camList[-1]
self.camera = render.attachNewNode(self.name) self.camera = render.attachNewNode(self.name)
#self.camera.setName(self.name) #self.camera.setName(self.name)
@ -135,18 +127,16 @@ class Viewport(wx.Panel, DirectObject):
"""Closes the viewport.""" """Closes the viewport."""
if self.initialized: if self.initialized:
wx.Window.Close(self) wx.Window.Close(self)
base.closeWindow(self.win) #base.closeWindow(self.win)
ViewportManager.viewports.remove(self) ViewportManager.viewports.remove(self)
def onSize(self, evt): def onSize(self, evt):
"""Invoked when the viewport is resized.""" """Invoked when the viewport is resized."""
WxPandaWindow.onSize(self, evt)
if self.win != None: if self.win != None:
wp = WindowProperties()
wp.setOrigin(0, 0)
newWidth = self.ClientSize.GetWidth() newWidth = self.ClientSize.GetWidth()
newHeight = self.ClientSize.GetHeight() newHeight = self.ClientSize.GetHeight()
wp.setSize(newWidth, newHeight)
self.win.requestProperties(wp)
if hasattr(base, "direct") and base.direct: if hasattr(base, "direct") and base.direct:
for dr in base.direct.drList: for dr in base.direct.drList:

View File

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

View File

@ -17,33 +17,60 @@ from panda3d.core import *
__all__ = ['WxPandaWindow'] __all__ = ['WxPandaWindow']
if platform.system() != 'Darwin': class EmbeddedPandaWindow(wx.Window):
class EmbeddedPandaWindow(wx.Window):
""" This class implements a Panda3D window that is directly """ This class implements a Panda3D window that is directly
embedded within the frame. It is fully supported on Windows, embedded within the frame. It is fully supported on Windows,
partially supported on Linux, and not at all on OSX. """ partially supported on Linux, and not at all on OSX. """
def __init__(self, *args, **kw): def __init__(self, *args, **kw):
gsg = None
if 'gsg' in kw:
gsg = kw['gsg']
del kw['gsg']
base.startWx()
wx.Window.__init__(self, *args, **kw) wx.Window.__init__(self, *args, **kw)
wp = WindowProperties.getDefault() wp = WindowProperties.getDefault()
if platform.system() != 'Darwin':
wp.setParentWindow(self.GetHandle()) wp.setParentWindow(self.GetHandle())
if base.win: if base.win:
self.win = base.openWindow(props = wp) self.win = base.openWindow(props = wp, gsg = gsg, type = 'onscreen')
else: else:
base.openDefaultWindow(props = wp) base.openDefaultWindow(props = wp, gsg = gsg, type = 'onscreen')
self.win = base.win self.win = base.win
self.Bind(wx.EVT_SIZE, self.__resized) self.Bind(wx.EVT_SIZE, self.onSize)
def __resized(self, event): # 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 onSize(self, event):
wp = WindowProperties() wp = WindowProperties()
wp.setOrigin(0, 0) wp.setOrigin(0, 0)
wp.setSize(*self.GetClientSizeTuple()) wp.setSize(*self.GetClientSizeTuple())
self.win.requestProperties(wp) self.win.requestProperties(wp)
event.Skip()
if hasattr(wxgl, 'GLCanvas'): if not hasattr(wxgl, 'GLCanvas'):
OpenGLPandaWindow = None
else:
class OpenGLPandaWindow(wxgl.GLCanvas): class OpenGLPandaWindow(wxgl.GLCanvas):
""" This class implements a Panda3D "window" that actually draws """ This class implements a Panda3D "window" that actually draws
within the wx GLCanvas object. It is supported whenever OpenGL is within the wx GLCanvas object. It is supported whenever OpenGL is
@ -88,8 +115,18 @@ if hasattr(wxgl, 'GLCanvas'):
} }
def __init__(self, *args, **kw): 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) wxgl.GLCanvas.__init__(self, *args, **kw)
# Can't share the GSG when a new wxgl.GLContext is created
# automatically.
gsg = None
callbackWindowDict = { callbackWindowDict = {
'Events' : self.__eventsCallback, 'Events' : self.__eventsCallback,
'Properties' : self.__propertiesCallback, 'Properties' : self.__propertiesCallback,
@ -111,14 +148,14 @@ if hasattr(wxgl, 'GLCanvas'):
self.SetCurrent() self.SetCurrent()
if base.win: if base.win:
self.win = base.openWindow(callbackWindowDict = callbackWindowDict, pipe = pipe) self.win = base.openWindow(callbackWindowDict = callbackWindowDict, pipe = pipe, gsg = gsg, type = 'onscreen')
else: else:
base.openDefaultWindow(callbackWindowDict = callbackWindowDict, pipe = pipe) base.openDefaultWindow(callbackWindowDict = callbackWindowDict, pipe = pipe, gsg = gsg, type = 'onscreen')
self.win = base.win self.win = base.win
self.inputDevice = self.win.getInputDevice(0) 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_DOWN, lambda event: self.__buttonDown(MouseButton.one()))
self.Bind(wx.EVT_LEFT_UP, lambda event: self.__buttonUp(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())) 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_KEY_UP, self.__keyUp)
self.Bind(wx.EVT_CHAR, self.__keystroke) 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): def __buttonDown(self, button):
self.inputDevice.buttonDown(button) self.inputDevice.buttonDown(button)
@ -189,18 +244,23 @@ if hasattr(wxgl, 'GLCanvas'):
cbType = data.getCallbackType() cbType = data.getCallbackType()
if cbType == CallbackGraphicsWindow.RCTBeginFrame: if cbType == CallbackGraphicsWindow.RCTBeginFrame:
self.SetCurrent() self.SetCurrent()
if not self.IsShownOnScreen():
return False
elif cbType == CallbackGraphicsWindow.RCTEndFlip: elif cbType == CallbackGraphicsWindow.RCTEndFlip:
self.SwapBuffers() self.SwapBuffers()
data.upcall() data.upcall()
def __resized(self, event): def onSize(self, event):
wp = WindowProperties() wp = WindowProperties()
wp.setSize(*self.GetClientSizeTuple()) wp.setSize(*self.GetClientSizeTuple())
self.win.requestProperties(wp) self.win.requestProperties(wp)
event.Skip()
# Choose the best implementation of WxPandaWindow for the platform. # Choose the best implementation of WxPandaWindow for the platform.
WxPandaWindow = None
if platform.system() == 'Darwin': if platform.system() == 'Darwin':
WxPandaWindow = OpenGLPandaWindow WxPandaWindow = OpenGLPandaWindow
else:
if not WxPandaWindow:
WxPandaWindow = EmbeddedPandaWindow WxPandaWindow = EmbeddedPandaWindow

View File

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

View File

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

View File

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