Explorar o código

leveleditor works on Mac too

David Rose %!s(int64=14) %!d(string=hai) anos
pai
achega
5e4ca78c07

+ 22 - 15
direct/src/showbase/ShowBase.py

@@ -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 startTk(self, fWantTk = 1):
-        self.wantTk = fWantTk
-        if self.wantTk:
+    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 = 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):

+ 1 - 1
direct/src/showbase/TkGlobal.py

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

+ 1 - 0
direct/src/showbase/WxGlobal.py

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

+ 11 - 21
direct/src/wxwidgets/ViewPort.py

@@ -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:

+ 2 - 2
direct/src/wxwidgets/WxPandaShell.py

@@ -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):

+ 90 - 30
direct/src/showbase/WxPandaWindow.py → direct/src/wxwidgets/WxPandaWindow.py

@@ -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. """
-
-        def __init__(self, *args, **kw):
-            wx.Window.__init__(self, *args, **kw)
-
-            wp = WindowProperties.getDefault()
+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):
+        gsg = None
+        if 'gsg' in kw:
+            gsg = kw['gsg']
+            del kw['gsg']
+
+        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
-
-            self.Bind(wx.EVT_SIZE, self.__resized)
-
-        def __resized(self, event):
-            wp = WindowProperties()
-            wp.setOrigin(0, 0)
-            wp.setSize(*self.GetClientSizeTuple())
-            self.win.requestProperties(wp)
-
-if hasattr(wxgl, 'GLCanvas'):
+        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.onSize)
+
+        # 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.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

+ 4 - 4
panda/src/device/mouseAndKeyboard.cxx

@@ -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::

+ 0 - 1
panda/src/device/mouseAndKeyboard.h

@@ -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;
   

+ 5 - 0
panda/src/display/callbackGraphicsWindow.cxx

@@ -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);
 }
 
 ////////////////////////////////////////////////////////////////////