Browse Source

Seperated WX UI Frame

Gyedo Jeon 15 years ago
parent
commit
a5e19e546b

+ 8 - 5
direct/src/leveleditor/ActionMgr.py

@@ -86,11 +86,14 @@ class ActionAddNewObj(ActionBase):
         else:
             print "Undo: addNewObject"
             obj = self.editor.objectMgr.findObjectByNodePath(self.result)
-            self.uid = obj[OG.OBJ_UID]
-            self.editor.ui.sceneGraphUI.delete(self.uid)
-            base.direct.deselect(self.result)
-            base.direct.removeNodePath(self.result)
-            self.result = None
+            if obj:
+                self.uid = obj[OG.OBJ_UID]
+                self.editor.ui.sceneGraphUI.delete(self.uid)
+                base.direct.deselect(self.result)
+                base.direct.removeNodePath(self.result)
+                self.result = None
+            else:
+                print "Can't undo this add"
 
 class ActionDeleteObj(ActionBase):
     """ Action class for deleting object """

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

@@ -5,15 +5,10 @@ You should write your own LevelEditor class inheriting this.
 Refer LevelEditor.py for example.
 """
 
-from pandac.PandaModules import *
-from direct.showbase.ShowBase import *
 from direct.showbase.DirectObject import *
-from direct.directtools.DirectGlobals import *
 from direct.directtools.DirectUtil import *
 from direct.gui.DirectGui import *
 
-base = ShowBase(False)
-
 from FileMgr import *
 from ActionMgr import *
 from MayaConverter import *
@@ -30,85 +25,12 @@ class LevelEditorBase(DirectObject):
         self.actionMgr = ActionMgr()
 
         self.NPParent = render
+
         # define your own config file in inherited class
-        self.settingsFile = None
+        self.settingsFile = None        
         
     def initialize(self):
         """ You should call this in your __init__ method of inherited LevelEditor class """
-        fTk = 0
-        fWx = 0
-        base.startDirect(fWantTk = fTk, fWantWx = fWx)
-
-        base.closeWindow(base.win)
-        base.win = base.winList[3]
-
-        base.direct.disableMouseEvents()
-        newMouseEvents = map(lambda x: "_le_per_%s"%x, base.direct.mouseEvents) +\
-                         map(lambda x: "_le_fro_%s"%x, base.direct.mouseEvents) +\
-                         map(lambda x: "_le_lef_%s"%x, base.direct.mouseEvents) +\
-                         map(lambda x: "_le_top_%s"%x, base.direct.mouseEvents)
-        base.direct.mouseEvents = newMouseEvents
-        base.direct.enableMouseEvents()
-
-        base.direct.disableKeyEvents()
-        keyEvents = map(lambda x: "_le_per_%s"%x, base.direct.keyEvents) +\
-                         map(lambda x: "_le_fro_%s"%x, base.direct.keyEvents) +\
-                         map(lambda x: "_le_lef_%s"%x, base.direct.keyEvents) +\
-                         map(lambda x: "_le_top_%s"%x, base.direct.keyEvents)
-        base.direct.keyEvents = keyEvents
-        base.direct.enableKeyEvents()
-
-        base.direct.disableModifierEvents()
-        modifierEvents = map(lambda x: "_le_per_%s"%x, base.direct.modifierEvents) +\
-                         map(lambda x: "_le_fro_%s"%x, base.direct.modifierEvents) +\
-                         map(lambda x: "_le_lef_%s"%x, base.direct.modifierEvents) +\
-                         map(lambda x: "_le_top_%s"%x, base.direct.modifierEvents)
-        base.direct.modifierEvents = modifierEvents
-        base.direct.enableModifierEvents()
-
-        base.direct.cameraControl.lockRoll = True
-        base.direct.setFScaleWidgetByCam(1)
-
-        unpickables = [
-            "z-guide",
-            "y-guide",
-            "x-guide",
-            "x-disc-geom",
-            "x-ring-line",
-            "x-post-line",
-            "y-disc-geom",
-            "y-ring-line",
-            "y-post-line",
-            "z-disc-geom",
-            "z-ring-line",
-            "z-post-line",
-            "centerLines",
-            "majorLines",
-            "minorLines",
-            "Sphere",]
-
-        for unpickable in unpickables:
-            base.direct.addUnpickable(unpickable)
-
-        base.direct.manipulationControl.optionalSkipFlags |= SKIP_UNPICKABLE
-        base.direct.manipulationControl.fAllowMarquee = 1
-        base.direct.manipulationControl.supportMultiView()
-        base.direct.cameraControl.useMayaCamControls = 1
-        base.direct.cameraControl.perspCollPlane = self.ui.perspView.collPlane
-        for widget in base.direct.manipulationControl.widgetList:
-            widget.setBin('gui-popup', 0)
-            widget.setDepthTest(0)
-
-        # [gjeon] to intercept messages here
-        base.direct.ignore('DIRECT-delete')
-        base.direct.ignore('DIRECT-select')
-        base.direct.ignore('DIRECT-preDeselectAll')
-        base.direct.ignore('DIRECT-toggleWidgetVis')
-        base.direct.fIgnoreDirectOnlyKeyMap = 1
-        
-        # [gjeon] do not use the old way of finding current DR
-        base.direct.drList.tryToGetCurrentDr = False
-
         # specifiy what obj can be 'selected' as objects
         base.direct.selected.addTag('OBJRoot')
 

+ 1 - 5
direct/src/leveleditor/LevelEditorUI.py

@@ -2,12 +2,8 @@ from LevelEditorUIBase import *
 
 class LevelEditorUI(LevelEditorUIBase):
     """ Class for Panda3D LevelEditor """ 
-    frameWidth = 800
-    frameHeight = 600
     appversion      = '0.1'
     appname         = 'Panda3D Level Editor'
     
-    def __init__(self, editor, *args, **kw):
-        if not kw.get('size'):
-            kw['size'] = wx.Size(self.frameWidth, self.frameHeight)
+    def __init__(self, editor):
         LevelEditorUIBase.__init__(self, editor)

+ 30 - 132
direct/src/leveleditor/LevelEditorUIBase.py

@@ -1,12 +1,12 @@
-import wx
-import os
-from wx.lib.agw import fourwaysplitter as FWS
+## import wx
+## import os
+## from wx.lib.agw import fourwaysplitter as FWS
 
 from pandac.PandaModules import *
-from direct.wxwidgets.WxAppShell import *
+from direct.wxwidgets.WxPandaShell import *
 from direct.directtools.DirectSelection import SelectionRay
 
-from ViewPort import *
+#from ViewPort import *
 from ObjectPaletteUI import *
 from ObjectPropertyUI import *
 from SceneGraphUI import *
@@ -113,50 +113,30 @@ ID_GRID_SNAP = 303
 ID_SHOW_PANDA_OBJECT = 304
 ID_HOT_KEYS = 305
 
-ID_FOUR_VIEW = 401
-ID_TOP_VIEW = 402
-ID_FRONT_VIEW = 403
-ID_LEFT_VIEW = 404
-ID_PERSP_VIEW = 405
-
-class LevelEditorUIBase(WxAppShell):
+class LevelEditorUIBase(WxPandaShell):
     """ Class for Panda3D LevelEditor """ 
+    def __init__(self, editor):
+        self.MENU_TEXTS.update({
+            ID_NEW : ("&New", "LE-NewScene"),
+            ID_OPEN : ("&Open", "LE-OpenScene"),
+            ID_SAVE : ("&Save", "LE-SaveScene"),
+            ID_SAVE_AS : ("Save &As", None),
+            wx.ID_EXIT : ("&Quit", "LE-Quit"),
+            ID_DUPLICATE : ("&Duplicate", "LE-Duplicate"),
+            ID_MAKE_LIVE : ("Make &Live", "LE-MakeLive"),
+            ID_UNDO : ("&Undo", "LE-Undo"),
+            ID_REDO : ("&Redo", "LE-Redo"),
+            ID_SHOW_GRID : ("&Show Grid", None),
+            ID_GRID_SIZE : ("&Grid Size", None),
+            ID_GRID_SNAP : ("Grid S&nap", None),
+            ID_SHOW_PANDA_OBJECT : ("Show &Panda Objects", None),
+            ID_HOT_KEYS : ("&Hot Keys", None),
+            })
 
-    MENU_TEXTS = {
-        ID_NEW : ("&New", "LE-NewScene"),
-        ID_OPEN : ("&Open", "LE-OpenScene"),
-        ID_SAVE : ("&Save", "LE-SaveScene"),
-        ID_SAVE_AS : ("Save &As", None),
-        wx.ID_EXIT : ("&Quit", "LE-Quit"),
-        ID_DUPLICATE : ("&Duplicate", "LE-Duplicate"),
-        ID_MAKE_LIVE : ("Make &Live", "LE-MakeLive"),
-        ID_UNDO : ("&Undo", "LE-Undo"),
-        ID_REDO : ("&Redo", "LE-Redo"),
-        ID_SHOW_GRID : ("&Show Grid", None),
-        ID_GRID_SIZE : ("&Grid Size", None),
-        ID_GRID_SNAP : ("Grid S&nap", None),
-        ID_SHOW_PANDA_OBJECT : ("Show &Panda Objects", None),
-        ID_HOT_KEYS : ("&Hot Keys", None),
-        ID_FOUR_VIEW : ("Four Views", None),
-        ID_TOP_VIEW : ("Top View", None),        
-        ID_FRONT_VIEW : ("Front View", None),
-        ID_LEFT_VIEW : ("Left View", None),
-        ID_PERSP_VIEW : ("Persp View", None),
-        }
-    
-    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
+        WxPandaShell.__init__(self, fStartDirect=True)        
         self.contextMenu = ViewportMenu()
-
-        if not kw.get('size'):
-            kw['size'] = wx.Size(self.frameWidth, self.frameHeight)
-        WxAppShell.__init__(self, *args, **kw)        
         self.bindKeyEvents(True)
-        self.initialize()
 
     def bindKeyEvents(self, toBind=True):
         if toBind:
@@ -214,24 +194,8 @@ class LevelEditorUIBase(WxAppShell):
         self.hotKeysMenuItem = self.menuOptions.Append(ID_HOT_KEYS, self.MENU_TEXTS[ID_HOT_KEYS][0])
         self.Bind(wx.EVT_MENU, self.onHotKeys, self.hotKeysMenuItem)
 
-        self.menuView = wx.Menu()
-        self.menuBar.Insert(3, self.menuView, "&View")
-
-        menuItem = self.menuView.AppendRadioItem(ID_FOUR_VIEW, self.MENU_TEXTS[ID_FOUR_VIEW][0])
-        self.Bind(wx.EVT_MENU, lambda p0=None, p1=-1:self.onViewChange(p0, p1), menuItem)
-
-        menuItem = self.menuView.AppendRadioItem(ID_TOP_VIEW, self.MENU_TEXTS[ID_TOP_VIEW][0])
-        self.Bind(wx.EVT_MENU, lambda p0=None, p1=0:self.onViewChange(p0, p1), menuItem)
-
-        menuItem = self.menuView.AppendRadioItem(ID_FRONT_VIEW, self.MENU_TEXTS[ID_FRONT_VIEW][0])
-        self.Bind(wx.EVT_MENU, lambda p0=None, p1=1:self.onViewChange(p0, p1), menuItem)
-
-        menuItem = self.menuView.AppendRadioItem(ID_LEFT_VIEW, self.MENU_TEXTS[ID_LEFT_VIEW][0])
-        self.Bind(wx.EVT_MENU, lambda p0=None, p1=2:self.onViewChange(p0, p1), menuItem)
+        WxPandaShell.createMenu(self)
 
-        menuItem = self.menuView.AppendRadioItem(ID_PERSP_VIEW, self.MENU_TEXTS[ID_PERSP_VIEW][0])
-        self.Bind(wx.EVT_MENU, lambda p0=None, p1=3:self.onViewChange(p0, p1), menuItem)
-        
     def updateMenu(self):
         hotKeyDict = {}
         for hotKey in base.direct.hotKeyMap.keys():
@@ -247,27 +211,8 @@ class LevelEditorUIBase(WxAppShell):
                     menuItem.SetText(desc[0] + "\t%s"%hotKey)
 
     def createInterface(self):
-        self.createMenu()
+        WxPandaShell.createInterface(self)
         
-        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)
@@ -276,15 +221,14 @@ class LevelEditorUIBase(WxAppShell):
         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)
@@ -292,23 +236,13 @@ class LevelEditorUIBase(WxAppShell):
         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.rightBarDownPane.Layout()
+        self.Layout()
 
         self.objectPaletteUI = ObjectPaletteUI(self.leftBarUpPane0, self.editor)
         self.protoPaletteUI = ProtoPaletteUI(self.leftBarUpPane1, self.editor)
@@ -318,16 +252,6 @@ class LevelEditorUIBase(WxAppShell):
 
         self.showGridMenuItem.Check(True)
 
-    def onViewChange(self, evt, viewIdx):
-        for i in range(4):
-            if viewIdx >=0 and\
-               i != viewIdx:
-                base.winList[i].setActive(0)
-            else:
-                base.winList[i].setActive(1)
-
-        self.viewFrame.SetExpanded(viewIdx)
-
     def onRightDown(self, evt=None):
         """Invoked when the viewport is right-clicked."""
         if evt == None:
@@ -412,32 +336,6 @@ class LevelEditorUIBase(WxAppShell):
             keyDesc = base.direct.hotKeyMap[input]
             messenger.send(keyDesc[1])
 
-    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 reset(self):
         self.sceneGraphUI.reset()
         self.layerEditorUI.reset()

+ 0 - 243
direct/src/leveleditor/ViewPort.py

@@ -1,243 +0,0 @@
-"""
-Contains classes useful for 3D viewports.
-
-Originally written by pro-rsoft,
-Modified by gjeon.
-"""
-
-__all__ = ["Viewport", "ViewportManager"]
-
-from direct.showbase.DirectObject import DirectObject
-from direct.directtools.DirectGrid import DirectGrid
-from direct.showbase.ShowBase import WindowControls
-from direct.directtools.DirectGlobals import *
-from pandac.PandaModules import WindowProperties, OrthographicLens, Point3, Plane, CollisionPlane, CollisionNode, NodePath
-import wx
-
-HORIZONTAL = wx.SPLIT_HORIZONTAL
-VERTICAL   = wx.SPLIT_VERTICAL
-CREATENEW  = 99
-VPLEFT     = 10
-VPFRONT    = 11
-VPTOP      = 12
-VPPERSPECTIVE = 13
-
-class ViewportManager:
-  """Manages the global viewport stuff."""
-  viewports = []
-  gsg = None
-
-  @staticmethod
-  def initializeAll(*args, **kwargs):
-    """Calls initialize() on all the viewports."""
-    for v in ViewportManager.viewports:
-      v.initialize(*args, **kwargs)
-  
-  @staticmethod
-  def updateAll(*args, **kwargs):
-    """Calls Update() on all the viewports."""
-    for v in ViewportManager.viewports:
-      v.Update(*args, **kwargs)
-  
-  @staticmethod
-  def layoutAll(*args, **kwargs):
-    """Calls Layout() on all the viewports."""
-    for v in ViewportManager.viewports:
-      v.Layout(*args, **kwargs)
-
-class Viewport(wx.Panel, DirectObject):
-  """Class representing a 3D Viewport."""
-  CREATENEW  = CREATENEW
-  VPLEFT     = VPLEFT
-  VPFRONT    = VPFRONT
-  VPTOP      = VPTOP
-  VPPERSPECTIVE = VPPERSPECTIVE
-  def __init__(self, name, *args, **kwargs):
-    self.name = name
-    DirectObject.__init__(self)
-    wx.Panel.__init__(self, *args, **kwargs)
-
-    ViewportManager.viewports.append(self)
-    self.win = None
-    self.camera = None
-    self.lens = None
-    self.camPos = None
-    self.camLookAt = None
-    self.initialized = False
-    self.grid = None
-    self.collPlane = None
-
-  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)
-    #self.camera.reparentTo(render)
-    self.cam.reparentTo(self.camera)
-    self.camNode = self.cam.node()
-
-    self.camNode.setCameraMask(LE_CAM_MASKS[self.name])
-
-    self.bt = base.setupMouse(self.win, True)
-    self.bt.node().setPrefix('_le_%s_'%self.name[:3])    
-    mw = self.bt.getParent()
-    mk = mw.getParent()
-    winCtrl = WindowControls(
-                self.win, mouseWatcher=mw,
-                cam=self.camera,
-                camNode = self.camNode,
-                cam2d=None,
-                mouseKeyboard =mk,
-                grid = self.grid)
-    base.setupWindowControls(winCtrl)
-
-    self.initialized = True
-    if self.lens != None:      self.cam.node().setLens(self.lens)
-    if self.camPos != None:    self.camera.setPos(self.camPos)
-    if self.camLookAt != None: self.camera.lookAt(self.camLookAt)
-
-    self.camLens = self.camNode.getLens()
-
-    if self.name in ['top', 'front', 'left']:
-      x = self.ClientSize.GetWidth() * 0.1
-      y = self.ClientSize.GetHeight() * 0.1
-      self.camLens.setFilmSize(x, y)
-
-    self.Bind(wx.EVT_SIZE, self.onSize)
-
-##     self.accept("wheel_down", self.zoomOut)
-##     self.accept("wheel_up", self.zoomIn)
-##     self.accept("page_down", self.zoomOut)
-##     self.accept("page_down-repeat", self.zoomOut)
-##     self.accept("page_up", self.zoomIn)
-##     self.accept("page_up-repeat", self.zoomIn)
-    #self.accept("mouse3", self.onRightDown)
-  
-  def close(self):
-    """Closes the viewport."""
-    if self.initialized:
-      Window.close(self)
-    ViewportManager.viewports.remove(self)
-  
-  def onSize(self, evt):
-    """Invoked when the viewport is resized."""
-    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:
-          if dr.camNode == self.camNode:
-            dr.updateFilmSize(newWidth, newHeight)
-            break
-      
-  def onRightDown(self, evt = None):
-    """Invoked when the viewport is right-clicked."""
-    if evt == None:
-      mpos = wx.GetMouseState()
-      mpos = self.ScreenToClient((mpos.x, mpos.y))
-    else:
-      mpos = evt.GetPosition()
-    self.Update()
-    #self.PopupMenu(self.menu, mpos)
-    #self.menu.Destroy()
-  
-  def zoomOut(self):
-    self.camera.setY(self.camera, -MOUSE_ZOO_SPEED)
-  
-  def zoomIn(self):
-    self.camera.setY(self.camera,  MOUSE_ZOOM_SPEED)
-  
-  @staticmethod
-  def make(parent, vpType = None):
-    """Safe constructor that also takes CREATENEW, VPLEFT, VPTOP, etc."""
-    if vpType == None or vpType == CREATENEW:
-      return Viewport(parent)
-    if isinstance(vpType, Viewport): return vpType
-    if vpType == VPLEFT:  return Viewport.makeLeft(parent)
-    if vpType == VPFRONT: return Viewport.makeFront(parent)
-    if vpType == VPTOP:   return Viewport.makeTop(parent)
-    if vpType == VPPERSPECTIVE:  return Viewport.makePerspective(parent)
-    raise TypeError, "Unknown viewport type: %s" % vpType
-  
-  @staticmethod
-  def makeOrthographic(parent, name, campos):
-    v = Viewport(name, parent)
-    v.lens = OrthographicLens()
-    v.lens.setFilmSize(30)
-    v.camPos = campos
-    v.camLookAt = Point3(0, 0, 0)
-    v.grid = DirectGrid(parent=render)
-    if name == 'left':
-      v.grid.setHpr(0, 0, 90)
-      collPlane = CollisionNode('LeftGridCol')
-      collPlane.addSolid(CollisionPlane(Plane(1, 0, 0, 0)))
-      collPlane.setIntoCollideMask(BitMask32.bit(21))
-      v.collPlane = NodePath(collPlane)
-      v.collPlane.wrtReparentTo(v.grid)
-      #v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_leftViewGridBack")
-      LE_showInOneCam(v.grid, name)
-    elif name == 'front':
-      v.grid.setHpr(90, 0, 90)
-      collPlane = CollisionNode('FrontGridCol')
-      collPlane.addSolid(CollisionPlane(Plane(0, -1, 0, 0)))
-      collPlane.setIntoCollideMask(BitMask32.bit(21))
-      v.collPlane = NodePath(collPlane)      
-      v.collPlane.wrtReparentTo(v.grid)
-      #v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_frontViewGridBack")
-      LE_showInOneCam(v.grid, name)
-    else:
-      collPlane = CollisionNode('TopGridCol')
-      collPlane.addSolid(CollisionPlane(Plane(0, 0, 1, 0)))
-      collPlane.setIntoCollideMask(BitMask32.bit(21))
-      v.collPlane = NodePath(collPlane)
-      v.collPlane.reparentTo(v.grid)
-      #v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_topViewGridBack")
-      LE_showInOneCam(v.grid, name)
-    return v
-  
-  @staticmethod
-  def makePerspective(parent):
-    v = Viewport('persp', parent)
-    v.camPos = Point3(-19, -19, 19)
-    v.camLookAt = Point3(0, 0, 0)
-
-    v.grid = DirectGrid(parent=render)
-    collPlane = CollisionNode('PerspGridCol')
-    collPlane.addSolid(CollisionPlane(Plane(0, 0, 1, 0)))
-    oldBitmask = collPlane.getIntoCollideMask()
-    collPlane.setIntoCollideMask(BitMask32.bit(21)|oldBitmask)
-    v.collPlane = NodePath(collPlane)
-    v.collPlane.reparentTo(v.grid)
-    #v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_perspViewGridBack")
-    LE_showInOneCam(v.grid, 'persp')
-    return v
-  
-  @staticmethod
-  def makeLeft(parent): return Viewport.makeOrthographic(parent, 'left', Point3(600, 0, 0))
-  @staticmethod
-  def makeFront(parent): return Viewport.makeOrthographic(parent, 'front', Point3(0, -600, 0))
-  @staticmethod
-  def makeTop(parent): return Viewport.makeOrthographic(parent, 'top', Point3(0, 0, 600))
-