NoUserOrg

Reto Spoerri : Game Design : Zürich

ProgrammingCodeSnippletsPanda3dWindowEmbeddedInAWx-window

Filed in: Resources.ProgrammingCodeSnippletsPanda3dWindowEmbeddedInAWx-window · Modified on : Fri, 31 Jul 09

Embeds a panda3d window into a WX-Window.

13.5.2009

import wxversion
wxversion.select('2.8')
import wx

from direct.wxwidgets.WxAppShell import WxAppShell

from pandac.PandaModules import *
loadPrcFileData("", "window-type none")

from direct.directbase import DirectStart


class P3dViewport(wx.Panel):
  # this panel contains the panda 3d window
  def __init__(self, *args, **kwargs):
    wx.Panel.__init__(self, *args, **kwargs)

  def initialize(self):
    # the panda3d window must be put into the panel after the wx-window has
    # been created
    assert self.GetHandle() != 0

    # put the panda3d 
    wp = WindowProperties()
    wp.setOrigin(0, 0)
    wp.setSize(self.ClientSize.GetWidth(), self.ClientSize.GetHeight())
    wp.setParentWindow(self.GetHandle())
    base.openDefaultWindow(props = wp, gsg = None)

    # attach the resize event
    wx.EVT_SIZE(self, self.OnResize)

  def OnResize(self, event):
    # when the wx-panel is resized, fit the panda3d window into it
    frame_size = event.GetSize()
    wp = WindowProperties()
    wp.setOrigin(0, 0)
    wp.setSize(frame_size.GetWidth(), frame_size.GetHeight())
    base.win.requestProperties(wp)

class EditorApp(WxAppShell):
  def __init__(self):
    # Create the Wx app, must be done before calling parent WxAppShell
    self.wxApp = wx.App(redirect = False)
    self.wxApp.SetAppName("Panda Editor")
    self.wxApp.SetClassName("PEditor")

    WxAppShell.__init__(self, title = "Panda Editor") #, pos = origin)

    self.verticalSplitter = wx.SplitterWindow(self, style = wx.SP_3D | wx.SP_BORDER)
    self.verticalSplitter.SetMinimumPaneSize(100)
    self.horizontalSplitter = wx.SplitterWindow(self.verticalSplitter, style = wx.SP_3D | wx.SP_BORDER)
    self.horizontalSplitter.SetMinimumPaneSize(100)

    self.p3dViewport = P3dViewport(self.verticalSplitter)

    assert self.horizontalSplitter.SplitHorizontally(wx.Panel(self.horizontalSplitter), wx.Panel(self.horizontalSplitter))
    assert self.verticalSplitter.SplitVertically(self.p3dViewport, self.horizontalSplitter, -200)

    sizer = wx.BoxSizer(wx.VERTICAL)
    sizer.Add(self.verticalSplitter, 1, wx.EXPAND, 0)

    self.SetSizer(sizer)
    self.Layout()

    # update the wx-window and run a step (window created?)
    self.Update()
    self.wxStep()
    # update the p3d window
    self.p3dViewport.initialize()

    # do something with the panda3d view
    loader.loadModel('smiley').reparentTo(render)

  def appInit(self):
    # 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 onDestroy(self, evt):
    # called on wx window destroy
    wx.EventLoop.SetActive(self.oldLoop)

  def wxStep(self, task = None):
    # process the events wx sends
    while self.evtLoop.Pending():
      self.evtLoop.Dispatch()
    self.wxApp.ProcessIdle()
    if task != None: return task.cont


editorApp = EditorApp()
run()