Dear Forum,
Given: PandaViewport with 3 DisplayRegions
Problem: Wheel_up Wheel_doen not recived in DispayregionFront and DisplayRegionTop
import sys
import os
from multiprocessing import Process, Pipe
import wx
from pandac.PandaModules import VBase4
from direct.task import Task
from pandac.PandaModules import WindowProperties
from pandac.PandaModules import loadPrcFileData
from direct.showbase.ShowBase import ShowBase
from direct.showbase import DirectObject
from panda3d.core import *
from CameraHandlerClass import CameraHandler
class PandaViewport(wx.Panel):
"""A special Panel which holds a Panda3d window."""
def __init__(self, *args, **kwargs):
wx.Panel.__init__(self, *args, **kwargs)
# See __doc__ of initialize() for this callback
self.GetTopLevelParent().Bind(wx.EVT_SHOW, self.onShow)
def onShow(self, event):
if event.GetShow() and self.GetHandle():
# Windows can't get it right from here. Call it after this function.
if os.name == "nt":
wx.CallAfter(self.initialize)
# All other OSes should be okay with instant init.
else:
self.initialize()
event.Skip()
def initialize(self):
"""This method requires the top most window to be visible, i.e. you called Show()
on it. Call initialize() after the whole Panel has been laid out and the UI is mostly done.
It will spawn a new process with a new Panda3D window and this Panel as parent.
"""
assert self.GetHandle() != 0
self.pipe, remote_pipe = Pipe()
w, h = self.ClientSize.GetWidth(), self.ClientSize.GetHeight()
self.panda_process = Process(target=Panda3dApp, args=(w, h, self.GetHandle(), remote_pipe))
self.panda_process.start()
self.Bind(wx.EVT_SIZE, self.onResize)
self.Bind(wx.EVT_KILL_FOCUS, self.onDefocus)
self.Bind(wx.EVT_WINDOW_DESTROY, self.onDestroy)
self.SetFocus()
# We need to check the pipe for requests frequently
self.pipe_timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.checkPipe, self.pipe_timer)
self.pipe_timer.Start(1000.0/60) # 60 times a second
def onResize(self, event):
# when the wx-panel is resized, fit the panda3d window into it
w, h = event.GetSize().GetWidth(), event.GetSize().GetHeight()
self.pipe.send(["resize", w, h])
def onDefocus(self, event):
f = wx.Window.FindFocus()
if f:
# This makes Panda lose keyboard focus
f.GetTopLevelParent().Raise()
def onDestroy(self, event):
self.pipe.send(["close",])
# Give Panda a second to close itself and terminate it if it doesn't
self.panda_process.join(1)
if self.panda_process.is_alive():
self.panda_process.terminate()
def checkPipe(self, event):
# Panda requested focus (and probably already has keyboard focus), so make wx
# set it officially. This prevents other widgets from being rendered focused.
if self.pipe.poll():
request = self.pipe.recv()
if request == "focus":
self.SetFocus()
class Panda3dApp(object):
def __init__(self, width, height, handle, pipe):
"""Arguments:
width -- width of the window
height -- height of the window
handle -- parent window handle
pipe -- multiprocessing pipe for communication
"""
self.pipe = pipe
loadPrcFileData("", "window-type none")
loadPrcFileData("", "audio-library-name null")
base = ShowBase()
wp = WindowProperties()
wp.setOrigin(0, 0)
wp.setSize(width, height)
# This causes warnings on Windows
#wp.setForeground(True)
wp.setParentWindow(handle)
self.OutputWindow = base.openDefaultWindow(props=wp,makeCamera = False, gsg=None)
self.camPersNP = base.makeCamera(base.win, camName = "camPers",
displayRegion= (0,0.669,0,1))
self.DisplayPers = self.camPersNP.node().getDisplayRegion(0)
self.DisplayPers.setClearColor(VBase4(0.098, 0.098, 0.196, 1))
self.DisplayPers.setClearColorActive(True)
self.DisplayPers.setClearDepthActive(True)
base.mouseWatcherNode.setDisplayRegion(self.DisplayPers)
self.DisplayTop = base.win.makeDisplayRegion(0.67,1,0.5,1)
self.DisplayTop.setClearColor(VBase4(0.098, 0.098, 0.196, 1))
self.DisplayTop.setClearColorActive(True)
self.DisplayTop.setClearDepthActive(True)
self.MouseWatcherTop = MouseWatcher()
base.mouseWatcher.getParent().attachNewNode(self.MouseWatcherTop)
self.MouseWatcherTop.setDisplayRegion(self.DisplayTop)
self.CamTopNP = render.attachNewNode(Camera('camTop'))
self.DisplayTop.setCamera(self.CamTopNP)
self.CamTopNP.reparentTo(render)
self.CamTopNP.setPos(0,-50,150)
self.CamTopNP.lookAt(0,0,0)
self.lensTop = OrthographicLens()
self.lensTop.setFilmSize(100,100)
self.CamTopNP.node().setLens(self.lensTop)
self.DisplayFront = base.win.makeDisplayRegion(0.67,1,0,0.499)
self.DisplayFront.setClearColor(VBase4(0.098, 0.098, 0.196, 1))
self.DisplayFront.setClearColorActive(True)
self.DisplayFront.setClearDepthActive(True)
self.MouseWatcherFront = MouseWatcher()
base.mouseWatcher.getParent().attachNewNode(self.MouseWatcherFront)
self.MouseWatcherFront.setDisplayRegion(self.DisplayFront)
self.CamFrontNP = render.attachNewNode(Camera('camFront'))
self.DisplayFront.setCamera(self.CamFrontNP)
self.CamFrontNP.reparentTo(render)
self.CamFrontNP.setPos( 0,-50,0)
self.CamFrontNP.lookAt(0,0,0)
self.lensFront = OrthographicLens()
self.lensFront.setFilmSize(100,100)
self.CamFrontNP.node().setLens(self.lensFront)
self.loadEnvironment()
self.camHandler = CameraHandler()
#self.initLogging()
base.taskMgr.add(self.checkPipe, "check pipe")
#base.taskMgr.add(self.mouse, "mouse")
def printA():
print "'a' key recieved by panda"
base.accept("a", printA)
base.accept("mouse1-up", self.getFocus)
base.accept("wheel_up", self.wheelUp)
base.accept("wheel_down",self.wheelDown)
run()
def wheelUp(self):
print "WheelUP"
#print base.mouseWatcherNode
#if (base.mouseWatcherNode.hasMouse()):
# print "Pers"
# print base.mouseWatcherNode.getMouse()
#print self.MouseWatcherTop
#if (self.MouseWatcherTop.hasMouse()):
fs=self.lensTop.getFilmSize()
self.lensTop.setFilmSize(fs*0.9)
#print "Top"
#if (self.MouseWatcherFront.hasMouse()):
fs=self.lensFront.getFilmSize()
self.lensFront.setFilmSize(fs*0.9)
# print "Front"
# print self.MouseWatcherFront.getMouse()
def wheelDown(self):
print "WheelDown"
#print base.mouseWatcherNode
#if (base.mouseWatcherNode.hasMouse()):
# print "Pers"
# print base.mouseWatcherNode.getMouse()
#print self.MouseWatcherTop
#if (self.MouseWatcherTop.hasMouse()):
fs=self.lensTop.getFilmSize()
self.lensTop.setFilmSize(fs*1.1)
#print "Top"
#print self.MouseWatcherTop.getMouse()
#print self.MouseWatcherFront
#if (self.MouseWatcherFront.hasMouse()):
fs=self.lensFront.getFilmSize()
self.lensFront.setFilmSize(fs*1.1)
# print "Front"
# print self.MouseWatcherFront.getMouse()
#return Task.cont
def loadEnvironment(self):
env = loader.loadModel("models/environment")
env.reparentTo(render)
env.setScale(0.025, 0.025, 0.025)
env.setPos(-8, 42, 0)
def getFocus(self):
"""Bring Panda3d to foreground, so that it gets keyboard focus.
Also send a message to wx, so that it doesn't render a widget focused.
We also need to say wx that Panda now has focus, so that it can notice when
to take focus back.
"""
print "gotFocus"
wp = WindowProperties()
# This causes warnings on Windows
#wp.setForeground(True)
base.win.requestProperties(wp)
self.pipe.send("focus")
def resizeWindow(self, width, height):
old_wp = base.win.getProperties()
if old_wp.getXSize() == width and old_wp.getYSize() == height:
return
wp = WindowProperties()
wp.setOrigin(0, 0)
wp.setSize(width, height)
base.win.requestProperties(wp)
def checkPipe(self, task):
"""This task is responsible for executing actions requested by wxWidgets.
Currently supported requests with params:
resize, width, height
close
"""
# TODO: only use the last request of a type
# e.g. from multiple resize requests take only the latest into account
while self.pipe.poll():
request = self.pipe.recv()
if request[0] == "resize":
self.resizeWindow(request[1], request[2])
elif request[0] == "close":
sys.exit()
return Task.cont
# Test
class MyParentFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(
self, None, -1, "Hello!", size=(800,600),pos =(50,50),
style = wx.DEFAULT_FRAME_STYLE
)
self.p1 = PandaViewport (self)
def OnSize(self, event):
xsize = self.GetSize().width
ysize = self.GetSize().height
self.p1.SetSize(((self.GetSize().width),(self.GetSize().height)))
def OnSashChanged(self, evt):
pass
def OnSashChanging(self, evt):
pass
def OnExit(self, evt):
#print('OnExit')
self.Close(True)
if __name__ == "__main__":
app = wx.App(redirect=False)
frame = MyParentFrame()
frame.Show()
app.MainLoop()
event “mouse1-up” is received all over the place.
any advice?
with kind regards
Martin