Skip to content

Commit e6f9ebc

Browse files
committed
Added mouse input handling to Panda3D example.
1 parent 752766a commit e6f9ebc

1 file changed

Lines changed: 112 additions & 17 deletions

File tree

cefpython/cef1/windows/binaries/panda3d_.py

Lines changed: 112 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,7 @@
1414
#
1515
# This will enable your copy of python to find the panda libraries.
1616

17-
# TODO: implement forwarding key/mouse events to the CEF browser.
18-
# Browser object has following methods: SendKeyEvent(),
19-
# SendMouseClickEvent(), SendMouseMoveEvent(),
20-
# SendMouseWheelEvent(), SendFocusEvent(),
21-
# SendCaptureLostEvent().
17+
# TODO: fix the blurriness of the browser when window is resized.
2218

2319
import platform
2420
if platform.architecture()[0] != "32bit":
@@ -37,46 +33,145 @@
3733
from panda3d.core import *
3834
from direct.showbase.DirectObject import DirectObject
3935
from direct.task import Task
40-
from math import pi, sin, cos
36+
from math import pi, sin, cos, floor, ceil
37+
import platform
38+
import ctypes
4139

4240
class World(DirectObject):
43-
4441
browser = None
4542
texture = None
4643

4744
def __init__(self):
45+
wp = WindowProperties()
46+
wp.setTitle('Panda3D example')
47+
base.win.requestProperties(wp)
4848

4949
environ = loader.loadModel("models/environment")
5050
environ.reparentTo(render)
5151
environ.setScale(0.25,0.25,0.25)
5252
environ.setPos(-8,42,0)
5353
taskMgr.add(self.spinCameraTask, "SpinCameraTask")
5454

55-
windowHandle = base.win.getWindowHandle().getIntHandle()
56-
5755
self.texture = Texture()
58-
self.texture.setXSize(400)
59-
self.texture.setYSize(300)
6056
self.texture.setCompression(Texture.CMOff)
6157
self.texture.setComponentType(Texture.TUnsignedByte)
6258
self.texture.setFormat(Texture.FRgba4)
59+
self.texture.setTexturesPower2(0)
60+
self.texture.setAutoTextureScale(0)
6361

64-
cardMaker = CardMaker("browser2d")
65-
cardMaker.setFrame(-0.75,.75,-0.75,0.75)
66-
card = render2d.attachNewNode(cardMaker.generate())
67-
card.setTexture(self.texture)
68-
card.setHpr(0, 0, 5)
62+
self.cardMaker = CardMaker("browser2d")
63+
self.cardMaker.setFrame(-0.75, 0.75, -0.75, 0.75)
64+
node = self.cardMaker.generate()
65+
self.nodePath = render2d.attachNewNode(node)
66+
self.nodePath.setTexture(self.texture)
67+
self.nodePath.setHpr(0, 0, 5)
6968

69+
windowHandle = base.win.getWindowHandle().getIntHandle()
7070
windowInfo = cefpython.WindowInfo()
7171
windowInfo.SetAsOffscreen(windowHandle)
72+
7273
self.browser = cefpython.CreateBrowserSync(
7374
windowInfo, browserSettings={}, navigateURL="cefsimple.html")
7475
self.browser.SetClientHandler(
7576
ClientHandler(self.browser, self.texture))
76-
self.browser.SetSize(cefpython.PET_VIEW, 400, 300);
77+
78+
# SetFocus needs to be called after browser creation.
79+
if platform.system() == "Windows":
80+
ctypes.windll.user32.SetFocus(windowHandle)
81+
82+
self.setBrowserSize()
83+
self.accept("window-event", self.setBrowserSize)
84+
85+
# Browser methods for sending mouse/keyboard/focus events:
86+
# SendKeyEvent(), SendMouseClickEvent(), SendMouseMoveEvent(),
87+
# SendMouseWheelEvent(), SendFocusEvent(), SendCaptureLostEvent().
88+
89+
self.initMouseHandlers()
90+
self.initKeyboardHandlers()
7791

7892
taskMgr.add(self.messageLoop, "CefMessageLoop")
7993

94+
def setBrowserSize(self, window=None):
95+
width = int(round(base.win.getXSize() * 0.75))
96+
height = int(round(base.win.getYSize() * 0.75))
97+
self.texture.setXSize(width)
98+
self.texture.setYSize(height)
99+
self.browser.SetSize(cefpython.PET_VIEW, width, height)
100+
101+
def initMouseHandlers(self):
102+
taskMgr.add(self.onMouseMove, "onMouseMove")
103+
self.accept("mouse1", self.onMouseDown)
104+
self.accept("mouse1-up", self.onMouseUp)
105+
self.accept("wheel_up", self.onMouseWheelUp)
106+
self.accept("wheel_down", self.onMouseWheelDown)
107+
108+
def initKeyboardHandlers(self):
109+
pass
110+
111+
def isMouseInsideBrowser(self, mouse):
112+
if mouse.getX() >= -0.75 and mouse.getX() <= 0.75 and (
113+
mouse.getY() >= -0.75 and mouse.getY() <= 0.75):
114+
return True
115+
else:
116+
return False
117+
118+
def getMousePixelCoordinates(self, mouse):
119+
# This calculation works only for the browser area.
120+
relX = mouse.getX()
121+
relY = mouse.getY()
122+
relX += 0.75 # 0 .. 1.5
123+
relY += 0.75 # 0 .. 1.5
124+
width = self.texture.getXSize()
125+
height = self.texture.getYSize()
126+
width /= 1.5
127+
height /= 1.5
128+
pixelX = relX * width
129+
pixelY = relY * height
130+
pixelY = abs(pixelY - self.texture.getYSize())
131+
pixelX = int(round(pixelX))
132+
pixelY = int(round(pixelY))
133+
return (pixelX, pixelY)
134+
135+
def onMouseMove(self, task):
136+
if base.mouseWatcherNode.hasMouse():
137+
mouse = base.mouseWatcherNode.getMouse()
138+
if self.isMouseInsideBrowser(mouse):
139+
self.nodePath.setHpr(0, 0, 0)
140+
(x,y) = self.getMousePixelCoordinates(mouse)
141+
self.browser.SendMouseMoveEvent(x, y, mouseLeave=False)
142+
else:
143+
self.browser.SendMouseMoveEvent(-1, -1, mouseLeave=True)
144+
self.nodePath.setHpr(0, 0, 5)
145+
else:
146+
self.nodePath.setHpr(0, 0, 5)
147+
return Task.cont
148+
149+
def onMouseDown(self):
150+
mouse = base.mouseWatcherNode.getMouse()
151+
(x,y) = self.getMousePixelCoordinates(mouse)
152+
self.browser.SendMouseClickEvent(x, y, cefpython.MOUSEBUTTON_LEFT,
153+
mouseUp=False, clickCount=1)
154+
155+
def onMouseUp(self):
156+
mouse = base.mouseWatcherNode.getMouse()
157+
(x,y) = self.getMousePixelCoordinates(mouse)
158+
self.browser.SendMouseClickEvent(x, y, cefpython.MOUSEBUTTON_LEFT,
159+
mouseUp=True, clickCount=1)
160+
161+
def onMouseWheelUp(self):
162+
if base.mouseWatcherNode.hasMouse():
163+
mouse = base.mouseWatcherNode.getMouse()
164+
if self.isMouseInsideBrowser(mouse):
165+
(x,y) = self.getMousePixelCoordinates(mouse)
166+
self.browser.SendMouseWheelEvent(x, y, deltaX=0, deltaY=120)
167+
168+
def onMouseWheelDown(self):
169+
if base.mouseWatcherNode.hasMouse():
170+
mouse = base.mouseWatcherNode.getMouse()
171+
if self.isMouseInsideBrowser(mouse):
172+
(x,y) = self.getMousePixelCoordinates(mouse)
173+
self.browser.SendMouseWheelEvent(x, y, deltaX=0, deltaY=-120)
174+
80175
def messageLoop(self, task):
81176
cefpython.SingleMessageLoop()
82177
return Task.cont

0 commit comments

Comments
 (0)