Ver Fonte

Updated to be inheritable

Gyedo Jeon há 16 anos atrás
pai
commit
de1e105e82

+ 2 - 0
direct/src/leveleditor/LevelEditor.py

@@ -9,6 +9,7 @@ from LevelEditorBase import *
 from ObjectHandler import *
 from ObjectPalette import *
 from LevelEditorUI import *
+from ProtoPalette import *
 
 class LevelEditor(LevelEditorBase):
     """ Class for Panda3D LevelEditor """ 
@@ -22,6 +23,7 @@ class LevelEditor(LevelEditorBase):
         # connect them in your own LevelEditor class
         self.objectPalette = ObjectPalette()
         self.objectHandler = ObjectHandler(self)
+        self.protoPalette = ProtoPalette()
 
         # LevelEditorUI class must declared after ObjectPalette
         self.ui = LevelEditorUI(self)

+ 0 - 2
direct/src/leveleditor/LevelEditorBase.py

@@ -15,7 +15,6 @@ base = ShowBase(False)
 from ObjectMgr import *
 from FileMgr import *
 from ActionMgr import *
-from ProtoPalette import *
 from MayaConverter import *
 
 class LevelEditorBase(DirectObject):
@@ -27,7 +26,6 @@ class LevelEditorBase(DirectObject):
         self.objectMgr = ObjectMgr(self)
         self.fileMgr = FileMgr(self)
         self.actionMgr = ActionMgr()
-        self.protoPalette = ProtoPalette()
 
         # define your own config file in inherited class
         self.settingsFile = None

+ 3 - 310
direct/src/leveleditor/LevelEditorUI.py

@@ -1,63 +1,6 @@
-import wx
-import os
-from wx.lib.agw import fourwaysplitter as FWS
+from LevelEditorUIBase import *
 
-from pandac.PandaModules import *
-from direct.wxwidgets.WxAppShell import *
-from direct.directtools.DirectSelection import SelectionRay
-
-from ViewPort import *
-from ObjectPaletteUI import *
-from ObjectPropertyUI import *
-from SceneGraphUI import *
-from LayerEditorUI import *
-from HotKeyUI import *
-from ProtoPaletteUI import *
-from ActionMgr import *
-
-class PandaTextDropTarget(wx.TextDropTarget):
-    def __init__(self, editor, view):
-        wx.TextDropTarget.__init__(self)
-        self.editor = editor
-        self.view = view
-
-    def OnDropText(self, x, y, text):
-        # create new object
-        action = ActionAddNewObj(self.editor, text)
-        self.editor.actionMgr.push(action)
-        newobj = action()
-
-        # change window coordinate to mouse coordinate
-        mx = 2 * (x/float(self.view.ClientSize.GetWidth()) - 0.5)
-        my = -2 * (y/float(self.view.ClientSize.GetHeight()) - 0.5)
-
-        # create ray from the camera to detect 3d position
-        iRay = SelectionRay(self.view.camera)
-        iRay.collider.setFromLens(self.view.camNode, mx, my)
-        iRay.collideWithBitMask(1)
-        iRay.ct.traverse(self.view.collPlane)
-
-        if iRay.getNumEntries() > 0:
-            entry = iRay.getEntry(0)
-            hitPt = entry.getSurfacePoint(entry.getFromNodePath())
-
-            # create a temp nodePath to get the position
-            np = NodePath('temp')
-            np.setPos(self.view.camera, hitPt)
-
-            # update temp nodePath's HPR and scale with newobj's
-            np.setHpr(newobj.getHpr())
-            np.setScale(newobj.getScale())
-
-            # transform newobj to cursor position
-            obj = self.editor.objectMgr.findObjectByNodePath(newobj)
-            action = ActionTransformObj(self.editor, obj[OG.OBJ_UID], Mat4(np.getMat()))
-            self.editor.actionMgr.push(action)
-            np.remove()
-            action()
-        del iRay
-
-class LevelEditorUI(WxAppShell):
+class LevelEditorUI(LevelEditorUIBase):
     """ Class for Panda3D LevelEditor """ 
     frameWidth = 800
     frameHeight = 600
@@ -65,256 +8,6 @@ class LevelEditorUI(WxAppShell):
     appname         = 'Panda3D Level Editor'
     
     def __init__(self, editor, *args, **kw):
-        # Create the Wx app
-        self.wxApp = wx.App(redirect = False)
-        self.wxApp.SetAppName("Panda3D LevelEditor")
-        self.wxApp.SetClassName("P3DLevelEditor")
-        self.editor = editor
-
         if not kw.get('size'):
             kw['size'] = wx.Size(self.frameWidth, self.frameHeight)
-        WxAppShell.__init__(self, *args, **kw)        
-
-        self.initialize()
-        self.Bind(wx.EVT_SET_FOCUS, self.onSetFocus)
-        self.Bind(wx.EVT_KEY_DOWN, self.onSetFocus)
-
-    def createMenu(self):
-        menuItem = self.menuFile.Insert(0, -1 , "&New")
-        self.Bind(wx.EVT_MENU, self.onNew, menuItem)
-        
-        menuItem = self.menuFile.Insert(1, -1 , "&Load")
-        self.Bind(wx.EVT_MENU, self.onLoad, menuItem)
-
-        menuItem = self.menuFile.Insert(2, -1 , "&Save")
-        self.Bind(wx.EVT_MENU, self.onSave, menuItem)
-
-        menuItem = self.menuFile.Insert(3, -1 , "Save &As")
-        self.Bind(wx.EVT_MENU, self.onSaveAs, menuItem)
-
-        self.menuEdit = wx.Menu()
-        self.menuBar.Insert(1, self.menuEdit, "&Edit")
-
-        menuItem = self.menuEdit.Append(-1, "&Duplicate")
-        self.Bind(wx.EVT_MENU, self.onDuplicate, menuItem)
-
-        menuItem = self.menuEdit.Append(-1, "&Undo")
-        self.Bind(wx.EVT_MENU, self.editor.actionMgr.undo, menuItem)
-
-        menuItem = self.menuEdit.Append(-1, "&Redo")
-        self.Bind(wx.EVT_MENU, self.editor.actionMgr.redo, menuItem)
-
-        self.menuOptions = wx.Menu()
-        self.menuBar.Insert(2, self.menuOptions, "&Options")
-
-        self.gridSizeMenuItem = self.menuOptions.Append(-1, "&Grid Size")
-        self.Bind(wx.EVT_MENU, self.onGridSize, self.gridSizeMenuItem)
-
-        self.gridSnapMenuItem = self.menuOptions.Append(-1, "Grid &Snap", kind = wx.ITEM_CHECK)
-        self.Bind(wx.EVT_MENU, self.toggleGridSnap, self.gridSnapMenuItem)
-
-        self.showPandaObjectsMenuItem = self.menuOptions.Append(-1, "Show &Panda Objects", kind = wx.ITEM_CHECK)
-        self.Bind(wx.EVT_MENU, self.onShowPandaObjects, self.showPandaObjectsMenuItem)
-
-        self.hotKeysMenuItem = self.menuOptions.Append(-1, "&Hot Keys")
-        self.Bind(wx.EVT_MENU, self.onHotKeys, self.hotKeysMenuItem)
-
-    def createInterface(self):
-        self.createMenu()
-        
-        self.mainFrame = wx.SplitterWindow(self, style = wx.SP_3D | wx.SP_BORDER)
-        self.leftFrame = wx.SplitterWindow(self.mainFrame, style = wx.SP_3D | wx.SP_BORDER)
-        self.baseFrame = wx.SplitterWindow(self.mainFrame, style = wx.SP_3D | wx.SP_BORDER)
-        self.viewFrame = FWS.FourWaySplitter(self.baseFrame, style=wx.SP_LIVE_UPDATE)
-        self.rightFrame = wx.SplitterWindow(self.baseFrame, style = wx.SP_3D | wx.SP_BORDER)
-
-        self.topView = Viewport.makeTop(self.viewFrame)
-        self.viewFrame.AppendWindow(self.topView)
-
-        self.frontView = Viewport.makeFront(self.viewFrame)
-        self.viewFrame.AppendWindow(self.frontView)
-
-        self.leftView = Viewport.makeLeft(self.viewFrame)
-        self.viewFrame.AppendWindow(self.leftView)
-
-        self.perspView = Viewport.makePerspective(self.viewFrame)
-        self.viewFrame.AppendWindow(self.perspView)
-
-        self.leftBarUpPane = wx.Panel(self.leftFrame)
-        self.leftBarUpNB = wx.Notebook(self.leftBarUpPane, style=wx.NB_BOTTOM)
-        sizer = wx.BoxSizer(wx.VERTICAL)
-        sizer.Add(self.leftBarUpNB, 1, wx.EXPAND)
-        self.leftBarUpPane.SetSizer(sizer)
-        self.leftBarUpPane0 = wx.Panel(self.leftBarUpNB, -1)
-        self.leftBarUpNB.AddPage(self.leftBarUpPane0, 'Object Palette')
-        self.leftBarUpPane1 = wx.Panel(self.leftBarUpNB, -1)
-        self.leftBarUpNB.AddPage(self.leftBarUpPane1, 'Proto Palette')
-        self.leftBarDownPane = wx.Panel(self.leftFrame)
-        self.leftBarDownNB = wx.Notebook(self.leftBarDownPane)
-        sizer = wx.BoxSizer(wx.VERTICAL)
-        sizer.Add(self.leftBarDownNB, 1, wx.EXPAND)
-        self.leftBarDownPane.SetSizer(sizer)
-        self.leftBarDownPane0 = wx.Panel(self.leftBarDownNB, -1)
-        self.leftBarDownNB.AddPage(self.leftBarDownPane0, 'Scene Graph')
-        self.rightBarUpPane = wx.Panel(self.rightFrame)
-        self.rightBarDownPane = wx.Panel(self.rightFrame)
-        self.rightBarDownNB = wx.Notebook(self.rightBarDownPane)
-        sizer = wx.BoxSizer(wx.VERTICAL)
-        sizer.Add(self.rightBarDownNB, 1, wx.EXPAND)
-        self.rightBarDownPane.SetSizer(sizer)
-        self.rightBarDownPane0 = wx.Panel(self.rightBarDownNB, -1)
-        self.rightBarDownNB.AddPage(self.rightBarDownPane0, 'Layers')
-
-        self.leftFrame.SplitHorizontally(self.leftBarUpPane, self.leftBarDownPane)
-        self.rightFrame.SplitHorizontally(self.rightBarUpPane, self.rightBarDownPane)
-        self.mainFrame.SplitVertically(self.leftFrame, self.baseFrame, 200)
-        self.baseFrame.SplitVertically(self.viewFrame, self.rightFrame, 600)
-        
-        self.topView.SetDropTarget(PandaTextDropTarget(self.editor, self.topView))
-        self.frontView.SetDropTarget(PandaTextDropTarget(self.editor, self.frontView))
-        self.leftView.SetDropTarget(PandaTextDropTarget(self.editor, self.leftView))
-        self.perspView.SetDropTarget(PandaTextDropTarget(self.editor, self.perspView))
-        
-        self.leftFrame.SetSashGravity(0.5)
-        self.rightFrame.SetSashGravity(0.5)        
-        self.baseFrame.SetSashGravity(1.0)
-
-        sizer = wx.BoxSizer(wx.VERTICAL)
-        sizer.Add(self.mainFrame, 1, wx.EXPAND, 0)
-        self.SetSizer(sizer); self.Layout()
-
-        self.objectPaletteUI = ObjectPaletteUI(self.leftBarUpPane0, self.editor)
-        self.protoPaletteUI = ProtoPaletteUI(self.leftBarUpPane1, self.editor)
-        self.objectPropertyUI = ObjectPropertyUI(self.rightBarUpPane, self.editor)
-        self.sceneGraphUI = SceneGraphUI(self.leftBarDownPane0, self.editor)
-        self.layerEditorUI = LayerEditorUI(self.rightBarDownPane0, self.editor)
-
-    def onSetFocus(self):
-        print 'wx got focus'
-
-    def appInit(self):
-        """Overridden from WxAppShell.py."""
-        # Create a new event loop (to overide default wxEventLoop)
-        self.evtLoop = wx.EventLoop()
-        self.oldLoop = wx.EventLoop.GetActive()
-        wx.EventLoop.SetActive(self.evtLoop)
-        taskMgr.add(self.wxStep, "evtLoopTask")
-
-    def initialize(self):
-        """Initializes the viewports and editor."""
-        self.Update()
-        ViewportManager.updateAll()
-        self.wxStep()
-        ViewportManager.initializeAll()
-        # Position the camera
-        if base.trackball != None:
-          base.trackball.node().setPos(0, 30, 0)
-          base.trackball.node().setHpr(0, 15, 0)
-
-    def wxStep(self, task = None):
-        """A step in the WX event loop. You can either call this yourself or use as task."""
-        while self.evtLoop.Pending():
-          self.evtLoop.Dispatch()
-        self.wxApp.ProcessIdle()
-        if task != None: return task.cont
-
-    def onNew(self, evt):
-        self.editor.reset()
-        self.sceneGraphUI.reset()
-        self.layerEditorUI.reset()
-
-    def onLoad(self, evt):
-        dialog = wx.FileDialog(None, "Choose a file", os.getcwd(), "", "*.py", wx.OPEN)
-        if dialog.ShowModal() == wx.ID_OK:
-            self.editor.load(dialog.GetPath())
-        dialog.Destroy()
-
-    def onSave(self, evt):
-        if self.editor.currentFile is None:
-            self.onSaveAs(evt)
-        else:
-            self.editor.save()
-
-    def onSaveAs(self, evt):
-        dialog = wx.FileDialog(None, "Choose a file", os.getcwd(), "", "*.py", wx.SAVE)
-        if dialog.ShowModal() == wx.ID_OK:
-            self.editor.saveAs(dialog.GetPath())
-        dialog.Destroy()
-
-    def onDuplicate(self, evt):
-        self.editor.objectMgr.duplicateSelected()
-
-    def toggleGridSnap(self, evt):
-        if self.gridSnapMenuItem.IsChecked():
-            base.direct.manipulationControl.fGridSnap = 1
-        else:
-            base.direct.manipulationControl.fGridSnap = 0            
-
-    def onGridSize(self, evt):
-        gridSizeUI = GridSizeUI(self, -1, 'Change Grid Size', self.perspView.grid.gridSize, self.perspView.grid.gridSpacing)
-        gridSizeUI.ShowModal()
-        gridSizeUI.Destroy()
-        
-    def onShowPandaObjects(self, evt):
-        self.sceneGraphUI.showPandaObjectChildren()
-
-    def onDestroy(self, evt):
-        self.editor.protoPalette.saveToFile()
-        self.editor.saveSettings()
-
-    def updateGrids(self, newSize, newSpacing):
-        self.perspView.grid.gridSize = newSize
-        self.perspView.grid.gridSpacing = newSpacing
-        self.perspView.grid.updateGrid()
-
-        self.topView.grid.gridSize = newSize
-        self.topView.grid.gridSpacing = newSpacing
-        self.topView.grid.updateGrid()
-
-        self.frontView.grid.gridSize = newSize
-        self.frontView.grid.gridSpacing = newSpacing
-        self.frontView.grid.updateGrid()
-
-        self.leftView.grid.gridSize = newSize
-        self.leftView.grid.gridSpacing = newSpacing
-        self.leftView.grid.updateGrid()        
-
-    def onHotKeys(self, evt):
-        hotKeyUI = HotKeyUI(self, -1, 'Hot Key List')
-        hotKeyUI.ShowModal()
-        hotKeyUI.Destroy()
-
-class GridSizeUI(wx.Dialog):
-    def __init__(self, parent, id, title, gridSize, gridSpacing):
-        wx.Dialog.__init__(self, parent, id, title, size=(250, 240))
-
-        self.parent = parent
-        panel = wx.Panel(self, -1)
-        vbox = wx.BoxSizer(wx.VERTICAL)
-
-        wx.StaticBox(panel, -1, 'Grid Size', (5, 5), (235, 80))
-
-        self.gridSizeSlider = WxSlider(panel, -1, float(gridSize), 10.0, 100000.0,
-                           pos = (10, 25), size=(220, -1),
-                           style=wx.SL_HORIZONTAL | wx.SL_LABELS, textSize=(80,20))
-        self.gridSizeSlider.Enable()
-
-        wx.StaticBox(panel, -1, 'Grid Space', (5, 90), (235, 80))
-
-        self.gridSpacingSlider = WxSlider(panel, -1, float(gridSpacing), 0.01, 2000.0,
-                           pos = (10, 115), size=(220, -1),
-                           style=wx.SL_HORIZONTAL | wx.SL_LABELS)
-        self.gridSpacingSlider.Enable()
-        
-        okButton = wx.Button(self, -1, 'Apply', size=(70, 20))
-        okButton.Bind(wx.EVT_BUTTON, self.onApply)
-        vbox.Add(panel)
-        vbox.Add(okButton, 1, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 5)
-
-        self.SetSizer(vbox)
-
-    def onApply(self, evt):
-        newSize = self.gridSizeSlider.GetValue()
-        newSpacing = self.gridSpacingSlider.GetValue()
-        self.parent.updateGrids(newSize, newSpacing)
-        self.Destroy()
+        LevelEditorUIBase.__init__(self, editor)

+ 316 - 0
direct/src/leveleditor/LevelEditorUIBase.py

@@ -0,0 +1,316 @@
+import wx
+import os
+from wx.lib.agw import fourwaysplitter as FWS
+
+from pandac.PandaModules import *
+from direct.wxwidgets.WxAppShell import *
+from direct.directtools.DirectSelection import SelectionRay
+
+from ViewPort import *
+from ObjectPaletteUI import *
+from ObjectPropertyUI import *
+from SceneGraphUI import *
+from LayerEditorUI import *
+from HotKeyUI import *
+from ProtoPaletteUI import *
+from ActionMgr import *
+
+class PandaTextDropTarget(wx.TextDropTarget):
+    def __init__(self, editor, view):
+        wx.TextDropTarget.__init__(self)
+        self.editor = editor
+        self.view = view
+
+    def OnDropText(self, x, y, text):
+        # create new object
+        action = ActionAddNewObj(self.editor, text)
+        self.editor.actionMgr.push(action)
+        newobj = action()
+
+        # change window coordinate to mouse coordinate
+        mx = 2 * (x/float(self.view.ClientSize.GetWidth()) - 0.5)
+        my = -2 * (y/float(self.view.ClientSize.GetHeight()) - 0.5)
+
+        # create ray from the camera to detect 3d position
+        iRay = SelectionRay(self.view.camera)
+        iRay.collider.setFromLens(self.view.camNode, mx, my)
+        iRay.collideWithBitMask(1)
+        iRay.ct.traverse(self.view.collPlane)
+
+        if iRay.getNumEntries() > 0:
+            entry = iRay.getEntry(0)
+            hitPt = entry.getSurfacePoint(entry.getFromNodePath())
+
+            # create a temp nodePath to get the position
+            np = NodePath('temp')
+            np.setPos(self.view.camera, hitPt)
+
+            # update temp nodePath's HPR and scale with newobj's
+            np.setHpr(newobj.getHpr())
+            np.setScale(newobj.getScale())
+
+            # transform newobj to cursor position
+            obj = self.editor.objectMgr.findObjectByNodePath(newobj)
+            action = ActionTransformObj(self.editor, obj[OG.OBJ_UID], Mat4(np.getMat()))
+            self.editor.actionMgr.push(action)
+            np.remove()
+            action()
+        del iRay
+
+class LevelEditorUIBase(WxAppShell):
+    """ Class for Panda3D LevelEditor """ 
+    
+    def __init__(self, editor, *args, **kw):
+        # Create the Wx app
+        self.wxApp = wx.App(redirect = False)
+        self.wxApp.SetAppName("Panda3D LevelEditor")
+        self.wxApp.SetClassName("P3DLevelEditor")
+        self.editor = editor
+
+        if not kw.get('size'):
+            kw['size'] = wx.Size(self.frameWidth, self.frameHeight)
+        WxAppShell.__init__(self, *args, **kw)        
+
+        self.initialize()
+        self.Bind(wx.EVT_SET_FOCUS, self.onSetFocus)
+        self.Bind(wx.EVT_KEY_DOWN, self.onSetFocus)
+
+    def createMenu(self):
+        menuItem = self.menuFile.Insert(0, -1 , "&New")
+        self.Bind(wx.EVT_MENU, self.onNew, menuItem)
+        
+        menuItem = self.menuFile.Insert(1, -1 , "&Load")
+        self.Bind(wx.EVT_MENU, self.onLoad, menuItem)
+
+        menuItem = self.menuFile.Insert(2, -1 , "&Save")
+        self.Bind(wx.EVT_MENU, self.onSave, menuItem)
+
+        menuItem = self.menuFile.Insert(3, -1 , "Save &As")
+        self.Bind(wx.EVT_MENU, self.onSaveAs, menuItem)
+
+        self.menuEdit = wx.Menu()
+        self.menuBar.Insert(1, self.menuEdit, "&Edit")
+
+        menuItem = self.menuEdit.Append(-1, "&Duplicate")
+        self.Bind(wx.EVT_MENU, self.onDuplicate, menuItem)
+
+        menuItem = self.menuEdit.Append(-1, "&Undo")
+        self.Bind(wx.EVT_MENU, self.editor.actionMgr.undo, menuItem)
+
+        menuItem = self.menuEdit.Append(-1, "&Redo")
+        self.Bind(wx.EVT_MENU, self.editor.actionMgr.redo, menuItem)
+
+        self.menuOptions = wx.Menu()
+        self.menuBar.Insert(2, self.menuOptions, "&Options")
+
+        self.gridSizeMenuItem = self.menuOptions.Append(-1, "&Grid Size")
+        self.Bind(wx.EVT_MENU, self.onGridSize, self.gridSizeMenuItem)
+
+        self.gridSnapMenuItem = self.menuOptions.Append(-1, "Grid &Snap", kind = wx.ITEM_CHECK)
+        self.Bind(wx.EVT_MENU, self.toggleGridSnap, self.gridSnapMenuItem)
+
+        self.showPandaObjectsMenuItem = self.menuOptions.Append(-1, "Show &Panda Objects", kind = wx.ITEM_CHECK)
+        self.Bind(wx.EVT_MENU, self.onShowPandaObjects, self.showPandaObjectsMenuItem)
+
+        self.hotKeysMenuItem = self.menuOptions.Append(-1, "&Hot Keys")
+        self.Bind(wx.EVT_MENU, self.onHotKeys, self.hotKeysMenuItem)
+
+    def createInterface(self):
+        self.createMenu()
+        
+        self.mainFrame = wx.SplitterWindow(self, style = wx.SP_3D | wx.SP_BORDER)
+        self.leftFrame = wx.SplitterWindow(self.mainFrame, style = wx.SP_3D | wx.SP_BORDER)
+        self.baseFrame = wx.SplitterWindow(self.mainFrame, style = wx.SP_3D | wx.SP_BORDER)
+        self.viewFrame = FWS.FourWaySplitter(self.baseFrame, style=wx.SP_LIVE_UPDATE)
+        self.rightFrame = wx.SplitterWindow(self.baseFrame, style = wx.SP_3D | wx.SP_BORDER)
+
+        self.topView = Viewport.makeTop(self.viewFrame)
+        self.viewFrame.AppendWindow(self.topView)
+
+        self.frontView = Viewport.makeFront(self.viewFrame)
+        self.viewFrame.AppendWindow(self.frontView)
+
+        self.leftView = Viewport.makeLeft(self.viewFrame)
+        self.viewFrame.AppendWindow(self.leftView)
+
+        self.perspView = Viewport.makePerspective(self.viewFrame)
+        self.viewFrame.AppendWindow(self.perspView)
+
+        self.leftBarUpPane = wx.Panel(self.leftFrame)
+        self.leftBarUpNB = wx.Notebook(self.leftBarUpPane, style=wx.NB_BOTTOM)
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        sizer.Add(self.leftBarUpNB, 1, wx.EXPAND)
+        self.leftBarUpPane.SetSizer(sizer)
+        self.leftBarUpPane0 = wx.Panel(self.leftBarUpNB, -1)
+        self.leftBarUpNB.AddPage(self.leftBarUpPane0, 'Object Palette')
+        self.leftBarUpPane1 = wx.Panel(self.leftBarUpNB, -1)
+        self.leftBarUpNB.AddPage(self.leftBarUpPane1, 'Proto Palette')
+        self.leftBarDownPane = wx.Panel(self.leftFrame)
+        self.leftBarDownNB = wx.Notebook(self.leftBarDownPane)
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        sizer.Add(self.leftBarDownNB, 1, wx.EXPAND)
+        self.leftBarDownPane.SetSizer(sizer)
+        self.leftBarDownPane0 = wx.Panel(self.leftBarDownNB, -1)
+        self.leftBarDownNB.AddPage(self.leftBarDownPane0, 'Scene Graph')
+        self.rightBarUpPane = wx.Panel(self.rightFrame)
+        self.rightBarDownPane = wx.Panel(self.rightFrame)
+        self.rightBarDownNB = wx.Notebook(self.rightBarDownPane)
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        sizer.Add(self.rightBarDownNB, 1, wx.EXPAND)
+        self.rightBarDownPane.SetSizer(sizer)
+        self.rightBarDownPane0 = wx.Panel(self.rightBarDownNB, -1)
+        self.rightBarDownNB.AddPage(self.rightBarDownPane0, 'Layers')
+
+        self.leftFrame.SplitHorizontally(self.leftBarUpPane, self.leftBarDownPane)
+        self.rightFrame.SplitHorizontally(self.rightBarUpPane, self.rightBarDownPane)
+        self.mainFrame.SplitVertically(self.leftFrame, self.baseFrame, 200)
+        self.baseFrame.SplitVertically(self.viewFrame, self.rightFrame, 600)
+        
+        self.topView.SetDropTarget(PandaTextDropTarget(self.editor, self.topView))
+        self.frontView.SetDropTarget(PandaTextDropTarget(self.editor, self.frontView))
+        self.leftView.SetDropTarget(PandaTextDropTarget(self.editor, self.leftView))
+        self.perspView.SetDropTarget(PandaTextDropTarget(self.editor, self.perspView))
+        
+        self.leftFrame.SetSashGravity(0.5)
+        self.rightFrame.SetSashGravity(0.5)        
+        self.baseFrame.SetSashGravity(1.0)
+
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        sizer.Add(self.mainFrame, 1, wx.EXPAND, 0)
+        self.SetSizer(sizer); self.Layout()
+
+        self.objectPaletteUI = ObjectPaletteUI(self.leftBarUpPane0, self.editor)
+        self.protoPaletteUI = ProtoPaletteUI(self.leftBarUpPane1, self.editor)
+        self.objectPropertyUI = ObjectPropertyUI(self.rightBarUpPane, self.editor)
+        self.sceneGraphUI = SceneGraphUI(self.leftBarDownPane0, self.editor)
+        self.layerEditorUI = LayerEditorUI(self.rightBarDownPane0, self.editor)
+
+    def onSetFocus(self):
+        print 'wx got focus'
+
+    def appInit(self):
+        """Overridden from WxAppShell.py."""
+        # Create a new event loop (to overide default wxEventLoop)
+        self.evtLoop = wx.EventLoop()
+        self.oldLoop = wx.EventLoop.GetActive()
+        wx.EventLoop.SetActive(self.evtLoop)
+        taskMgr.add(self.wxStep, "evtLoopTask")
+
+    def initialize(self):
+        """Initializes the viewports and editor."""
+        self.Update()
+        ViewportManager.updateAll()
+        self.wxStep()
+        ViewportManager.initializeAll()
+        # Position the camera
+        if base.trackball != None:
+          base.trackball.node().setPos(0, 30, 0)
+          base.trackball.node().setHpr(0, 15, 0)
+
+    def wxStep(self, task = None):
+        """A step in the WX event loop. You can either call this yourself or use as task."""
+        while self.evtLoop.Pending():
+          self.evtLoop.Dispatch()
+        self.wxApp.ProcessIdle()
+        if task != None: return task.cont
+
+    def onNew(self, evt):
+        self.editor.reset()
+        self.sceneGraphUI.reset()
+        self.layerEditorUI.reset()
+
+    def onLoad(self, evt):
+        dialog = wx.FileDialog(None, "Choose a file", os.getcwd(), "", "*.py", wx.OPEN)
+        if dialog.ShowModal() == wx.ID_OK:
+            self.editor.load(dialog.GetPath())
+        dialog.Destroy()
+
+    def onSave(self, evt):
+        if self.editor.currentFile is None:
+            self.onSaveAs(evt)
+        else:
+            self.editor.save()
+
+    def onSaveAs(self, evt):
+        dialog = wx.FileDialog(None, "Choose a file", os.getcwd(), "", "*.py", wx.SAVE)
+        if dialog.ShowModal() == wx.ID_OK:
+            self.editor.saveAs(dialog.GetPath())
+        dialog.Destroy()
+
+    def onDuplicate(self, evt):
+        self.editor.objectMgr.duplicateSelected()
+
+    def toggleGridSnap(self, evt):
+        if self.gridSnapMenuItem.IsChecked():
+            base.direct.manipulationControl.fGridSnap = 1
+        else:
+            base.direct.manipulationControl.fGridSnap = 0            
+
+    def onGridSize(self, evt):
+        gridSizeUI = GridSizeUI(self, -1, 'Change Grid Size', self.perspView.grid.gridSize, self.perspView.grid.gridSpacing)
+        gridSizeUI.ShowModal()
+        gridSizeUI.Destroy()
+        
+    def onShowPandaObjects(self, evt):
+        self.sceneGraphUI.showPandaObjectChildren()
+
+    def onDestroy(self, evt):
+        self.editor.protoPalette.saveToFile()
+        self.editor.saveSettings()
+
+    def updateGrids(self, newSize, newSpacing):
+        self.perspView.grid.gridSize = newSize
+        self.perspView.grid.gridSpacing = newSpacing
+        self.perspView.grid.updateGrid()
+
+        self.topView.grid.gridSize = newSize
+        self.topView.grid.gridSpacing = newSpacing
+        self.topView.grid.updateGrid()
+
+        self.frontView.grid.gridSize = newSize
+        self.frontView.grid.gridSpacing = newSpacing
+        self.frontView.grid.updateGrid()
+
+        self.leftView.grid.gridSize = newSize
+        self.leftView.grid.gridSpacing = newSpacing
+        self.leftView.grid.updateGrid()        
+
+    def onHotKeys(self, evt):
+        hotKeyUI = HotKeyUI(self, -1, 'Hot Key List')
+        hotKeyUI.ShowModal()
+        hotKeyUI.Destroy()
+
+class GridSizeUI(wx.Dialog):
+    def __init__(self, parent, id, title, gridSize, gridSpacing):
+        wx.Dialog.__init__(self, parent, id, title, size=(250, 240))
+
+        self.parent = parent
+        panel = wx.Panel(self, -1)
+        vbox = wx.BoxSizer(wx.VERTICAL)
+
+        wx.StaticBox(panel, -1, 'Grid Size', (5, 5), (235, 80))
+
+        self.gridSizeSlider = WxSlider(panel, -1, float(gridSize), 10.0, 100000.0,
+                           pos = (10, 25), size=(220, -1),
+                           style=wx.SL_HORIZONTAL | wx.SL_LABELS, textSize=(80,20))
+        self.gridSizeSlider.Enable()
+
+        wx.StaticBox(panel, -1, 'Grid Space', (5, 90), (235, 80))
+
+        self.gridSpacingSlider = WxSlider(panel, -1, float(gridSpacing), 0.01, 2000.0,
+                           pos = (10, 115), size=(220, -1),
+                           style=wx.SL_HORIZONTAL | wx.SL_LABELS)
+        self.gridSpacingSlider.Enable()
+        
+        okButton = wx.Button(self, -1, 'Apply', size=(70, 20))
+        okButton.Bind(wx.EVT_BUTTON, self.onApply)
+        vbox.Add(panel)
+        vbox.Add(okButton, 1, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 5)
+
+        self.SetSizer(vbox)
+
+    def onApply(self, evt):
+        newSize = self.gridSizeSlider.GetValue()
+        newSpacing = self.gridSpacingSlider.GetValue()
+        self.parent.updateGrids(newSize, newSpacing)
+        self.Destroy()

+ 4 - 60
direct/src/leveleditor/ProtoPalette.py

@@ -1,66 +1,10 @@
 """
 Palette for Prototyping
 """
-import os
-import imp
-import types
 
-from ObjectPaletteBase import *
+from ProtoPaletteBase import *
 
-class ProtoPalette(ObjectPaletteBase):
+class ProtoPalette(ProtoPaletteBase):
     def __init__(self):
-        ObjectPaletteBase.__init__(self)
-
-    def addItems(self):
-        if type(protoData) == types.DictType:
-            for key in protoData.keys():
-                if type(protoData[key]) == types.DictType:
-                    self.add(key, parent)
-                    self.addItems(protoData[key], key)
-                else:
-                    self.add(protoData[key], parent)
-
-    def populate(self):
-        dirname = os.path.dirname(__file__)
-        moduleName = 'protoPaletteData'
-        try:
-            file, pathname, description = imp.find_module(moduleName, [dirname])
-            module = imp.load_module(moduleName, file, pathname, description)
-            self.data = module.protoData
-            self.dataStruct = module.protoDataStruct
-        except:
-            print "protoPaletteData doesn't exist"
-            return
-
-        #self.addItems()
-
-    def saveProtoDataStruct(self, f):
-        if not f:
-            return
-
-        for key in self.dataStruct.keys():
-            f.write("\t'%s':'%s',\n"%(key, self.dataStruct[key]))
-
-    def saveProtoData(self, f):
-        if not f:
-           return
-
-        for key in self.data.keys():
-            if isinstance(self.data[key], ObjectBase):
-               f.write("\t'%s':ObjectBase(name='%s', model='%s', anims=%s, actor=True),\n"%(key, self.data[key].name, self.data[key].model, self.data[key].anims))
-            else:
-               f.write("\t'%s':ObjectGen(name='%s'),\n"%(key, self.data[key].name))
-
-    def saveToFile(self):
-        try:
-            f = open(os.path.dirname(__file__) + '/protoPaletteData.py', 'w')
-            f.write("from direct.leveleditor.ObjectPaletteBase import *\n\n")
-            f.write("protoData = {\n")
-            self.saveProtoData(f)
-            f.write("}\n")
-            f.write("protoDataStruct = {\n")
-            self.saveProtoDataStruct(f)
-            f.write("}\n")
-            f.close()
-        except:
-            pass
+        self.dirname = os.path.dirname(__file__)
+        ProtoPaletteBase.__init__(self)

+ 65 - 0
direct/src/leveleditor/ProtoPaletteBase.py

@@ -0,0 +1,65 @@
+"""
+Palette for Prototyping
+"""
+import os
+import imp
+import types
+
+from ObjectPaletteBase import *
+
+class ProtoPaletteBase(ObjectPaletteBase):
+    def __init__(self):
+        ObjectPaletteBase.__init__(self)
+
+    def addItems(self):
+        if type(protoData) == types.DictType:
+            for key in protoData.keys():
+                if type(protoData[key]) == types.DictType:
+                    self.add(key, parent)
+                    self.addItems(protoData[key], key)
+                else:
+                    self.add(protoData[key], parent)
+
+    def populate(self):
+        moduleName = 'protoPaletteData'
+        try:
+            file, pathname, description = imp.find_module(moduleName, [self.dirname])
+            module = imp.load_module(moduleName, file, pathname, description)
+            self.data = module.protoData
+            self.dataStruct = module.protoDataStruct
+        except:
+            print "protoPaletteData doesn't exist"
+            return
+
+        #self.addItems()
+
+    def saveProtoDataStruct(self, f):
+        if not f:
+            return
+
+        for key in self.dataStruct.keys():
+            f.write("\t'%s':'%s',\n"%(key, self.dataStruct[key]))
+
+    def saveProtoData(self, f):
+        if not f:
+           return
+
+        for key in self.data.keys():
+            if isinstance(self.data[key], ObjectBase):
+               f.write("\t'%s':ObjectBase(name='%s', model='%s', anims=%s, actor=True),\n"%(key, self.data[key].name, self.data[key].model, self.data[key].anims))
+            else:
+               f.write("\t'%s':ObjectGen(name='%s'),\n"%(key, self.data[key].name))
+
+    def saveToFile(self):
+        try:
+            f = open(self.dirname + '/protoPaletteData.py', 'w')
+            f.write("from direct.leveleditor.ObjectPaletteBase import *\n\n")
+            f.write("protoData = {\n")
+            self.saveProtoData(f)
+            f.write("}\n")
+            f.write("protoDataStruct = {\n")
+            self.saveProtoDataStruct(f)
+            f.write("}\n")
+            f.close()
+        except:
+            pass