All notifications are sent from C++. I don’t know where to look in C++, but you can fix it by reopening Panda window. So you can get it right after it’s minimized too, or using other controls, as you described in your old post :
discourse.panda3d.org/viewtopic.php?t=2487
This is based on David’s MDI sample :
import wx
import sys,time
from pandac.PandaModules import *
loadPrcFileData('', '''
window-type none
# notify-level-windisplay spam
win-origin 0 0 # <-------- to remove the offset of the 3D window
''')
from direct.directbase.DirectStart import *
from direct.showbase.DirectObject import DirectObject
class App(wx.PySimpleApp,DirectObject):
def __init__(self):
wx.PySimpleApp.__init__(self)
#Create a new event loop (to overide default wxEventLoop)
self.evtloop = wx.EventLoop()
self.old = wx.EventLoop.GetActive()
wx.EventLoop.SetActive(self.evtloop)
taskMgr.add(self.wx, "Custom wx Event Loop")
# wxWindows calls this method to initialize the application
def OnInit(self):
self.SetAppName('My wx app')
self.SetClassName('MyAppClass')
self.parent = wx.MDIParentFrame(None, -1, 'My wx app',size=(600,-1))
self.PandaWnd = wx.MDIChildFrame(self.parent, -1, 'Panda window')
self.controlsFrame = wx.MDIChildFrame(self.parent, -1, 'controls window')
self.dummyFrame = wx.MDIChildFrame(self.parent, -1, 'dummy window',style=wx.FRAME_NO_TASKBAR)
self.panel = wx.Panel(self.controlsFrame)
self.dummyPanel = wx.Panel(self.dummyFrame)
self.parent.SetClientSize((550, 450))
self.parent.Center()
self.parent.Show(True)
PandaWndSize=(500,400)
self.PandaWnd.SetClientSize(PandaWndSize)
self.PandaWnd.Show(True)
# I need to know when I have to re-open PANDA window
self.PandaWnd.Bind(wx.EVT_SET_FOCUS,self.onPandaWindowGetFocus)
# opens Panda window
base.windowType = 'onscreen'
props = WindowProperties.getDefault()
props.setParentWindow(self.PandaWnd.GetHandle())
props.setSize(*PandaWndSize)
base.openDefaultWindow(props = props)
# controls
self.textbox = wx.TextCtrl(self.panel,-1,size=(200,-1))
self.button = wx.Button(self.panel,wx.ID_OK)
# controls window sizer
controlsSizer = wx.BoxSizer(wx.VERTICAL)
controlsSizer.Add(self.textbox, 0, wx.ALIGN_CENTER_HORIZONTAL, 5)
controlsSizer.Add(self.button, 0, wx.ALIGN_CENTER_HORIZONTAL, 5)
self.panel.SetSizer(controlsSizer)
controlsSizer.Fit(self.controlsFrame)
controlsSizer.SetSizeHints(self.controlsFrame)
# app window sizer
MDISizer = wx.BoxSizer(wx.VERTICAL)
MDISizer.Add(self.controlsFrame, 0, wx.ALIGN_LEFT, 5)
MDISizer.Add(self.PandaWnd, 0, wx.ALIGN_LEFT, 5)
MDISizer.Add(self.dummyFrame, 0, wx.ALIGN_LEFT, 5)
self.dummyPanel.SetSizer(MDISizer)
MDISizer.Fit(self.parent)
MDISizer.SetSizeHints(self.parent)
# events
self.acceptOnce('delete',self.delVP2)
self.accept('escape',self.exit)
self.accept('a',printTM)
camera.setPos(7.61, -12.01, 3.52)
camera.setHpr(36.70, -4.25, 2.87)
mat=Mat4(camera.getMat())
mat.invertInPlace()
base.mouseInterfaceNode.setMat(mat)
# main scene
p4=loader.loadModel('panda-model')
p4.setScale(.01)
p4.reparentTo(render)
# scene 1
scene1=NodePath('SCENE 1')
panda=loader.loadModel('panda')
panda.reparentTo(scene1)
panda.hprInterval(5,Vec3(360,0,0)).loop()
self.VPcam1 = Camera('vpcam1')
self.VPcam1.setScene(scene1)
self.VPcamNP1 = scene1.attachNewNode(self.VPcam1)
self.VPcamNP1.setPos(panda.getBounds().getCenter())
self.VPcamNP1.setY(-panda.getBounds().getRadius()*3.5)
self.makeDisplayRegion('dr1',base.win,self.VPcamNP1,.7,1,0,.33,sort=1000)
# scene 2
scene2=NodePath('SCENE 2')
smiley=loader.loadModel('smiley')
smiley.reparentTo(scene2)
smiley.hprInterval(5,Vec3(360,0,0)).loop()
self.VPcam2 = Camera('vpcam2')
self.VPcam2.setScene(scene2)
self.VPcamNP2 = scene2.attachNewNode(self.VPcam2)
self.VPcamNP2.setPos(smiley.getBounds().getCenter())
self.VPcamNP2.setY(-smiley.getBounds().getRadius()*3.5)
self.makeDisplayRegion('dr2',base.win,self.VPcamNP2,.7,1,.33,.66,sort=1100)
# scene 3
scene3=NodePath('SCENE 3')
teapot=loader.loadModel('teapot')
teapot.reparentTo(scene3)
teapot.hprInterval(5,Vec3(360,0,0)).loop()
self.VPcam3 = Camera('vpcam3')
self.VPcam3.setScene(scene3)
self.VPcamNP3 = scene3.attachNewNode(self.VPcam3)
self.VPcamNP3.setPos(teapot.getBounds().getCenter())
self.VPcamNP3.setY(-teapot.getBounds().getRadius()*3.5)
self.makeDisplayRegion('dr3',base.win,self.VPcamNP3,.7,1,.66,1,sort=1200)
return True
def makeDisplayRegion(self,name,win,cam,l=0,r=1,b=0,t=1,sort=1000):
dr=win.makeDisplayRegion(l,r,b,t)
dr.setCamera(cam)
dr.setSort(sort)
cam.setSx(base.getAspectRatio()*(r-l)/(t-b))
setattr(self,name,dr)
if not hasattr(self,'DisplayRegionsCollection'):
self.DisplayRegionsCollection=[]
self.DisplayRegionsCollection.append((name,cam,l,r,b,t,dr))
# print 'DR:',name,win,cam,l,r,b,t
def removeDisplayRegion(self,name):
for c in self.DisplayRegionsCollection:
if c[0]==name:
self.DisplayRegionsCollection.remove(c)
return
def recreateDisplayRegions(self):
lastDRNC=self.DisplayRegionsCollection
self.DisplayRegionsCollection=[]
for name,cam,l,r,b,t,dr in lastDRNC:
self.makeDisplayRegion(name,base.win,cam,l,r,b,t)
def delVP2(self):
self.dr2.getCamera().getTop().removeChildren()
self.dr2.getCamera().getTop().removeNode() # remove scene 2
self.removeDisplayRegion('dr2')
def exit(self):
Mdlg = wx.MessageDialog(None,'Are you sure to quit ?',caption='Confirmation',
style=wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION|wx.CENTER)
if Mdlg.ShowModal()==wx.ID_NO:
return
# upon showbase shutdown, Panda window will regain focus, avoid it
self.PandaWnd.Unbind(wx.EVT_SET_FOCUS)
sys.exit()
def onPandaWindowGetFocus(self, e):
mouse2camEnabled = base.mouse2cam.getParent()==base.mouseInterface
props=WindowProperties(base.win.getProperties())
# props.setParentWindow(self.PandaWnd.GetHandle())
# re-open the window
base.openMainWindow(props=props, gsg=base.win.getGsg(), keepCamera=1)
# restore mouse interface
if mouse2camEnabled and not base.mouseInterface.isStashed():
base.changeMouseInterface(base.mouseInterface)
print 'MOUSE_2_CAMERA INTERFACE ACTIVE'
# user-made display regions are gone due to closing the main window,
# so re-create them again
self.recreateDisplayRegions()
# who knows the aspect ratio is changed ? let showbase takes care of it
messenger.send('window-event',[base.win])
def wx(self, task):
while self.evtloop.Pending():
self.evtloop.Dispatch()
# time.sleep(0.01)
self.ProcessIdle()
return task.cont
def close(self):
wx.EventLoop.SetActive(self.old)
def printTM():
print taskMgr
# messenger.toggleVerbose()
app = App()
run()
Read more :
discourse.panda3d.org/viewtopic.php?t=2848
David, what is the origin used for here :
WinGraphicsWindow::open_regular_window (winGraphicsWindow.cxx) :
_hWnd = CreateWindow(wclass._name.c_str(), title.c_str(),
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS ,
//x_origin, y_origin,
x_origin,y_origin,
x_size, y_size,
_hparent, NULL, hinstance, 0);
It’s when we use other parent window set in window properties. I don’t think anyone would want the offset.