ToonTownRewritten/toontown/shtiker/HtmlView.py

283 lines
11 KiB
Python

import array, sys
from direct.showbase.DirectObject import DirectObject
from direct.task.Task import Task
from direct.directnotify import DirectNotifyGlobal
from pandac.PandaModules import Texture
from pandac.PandaModules import CardMaker
from pandac.PandaModules import NodePath
from pandac.PandaModules import Point3, Vec3, Vec4, VBase4D, Point2
from pandac.PandaModules import PNMImage
from pandac.PandaModules import TextureStage
from pandac.PandaModules import Texture
from pandac.PandaModules import WindowProperties
from direct.interval.IntervalGlobal import *
from pandac.PandaModules import AwWebView
from pandac.PandaModules import AwWebCore
WEB_WIDTH_PIXELS = 784
WEB_HEIGHT_PIXELS = 451
WEB_WIDTH = 1024
WEB_HEIGHT = 512
WEB_HALF_WIDTH = WEB_WIDTH / 2
WIN_WIDTH = 800
WIN_HEIGHT = 600
GlobalWebcore = None
class HtmlView(DirectObject):
notify = DirectNotifyGlobal.directNotify.newCategory('HtmlView')
useHalfTexture = config.GetBool('news-half-texture', 0)
def __init__(self, parent = aspect2d):
global GlobalWebcore
self.parent = parent
self.mx = 0
self.my = 0
self.htmlFile = 'index.html'
self.transparency = False
if GlobalWebcore:
pass
else:
GlobalWebcore = AwWebCore(AwWebCore.LOGVERBOSE, True, AwWebCore.PFBGRA)
GlobalWebcore.setBaseDirectory('.')
for errResponse in xrange(400, 600):
GlobalWebcore.setCustomResponsePage(errResponse, 'error.html')
self.webView = GlobalWebcore.createWebView(WEB_WIDTH, WEB_HEIGHT, self.transparency, False, 70)
frameName = ''
inGameNewsUrl = self.getInGameNewsUrl()
self.imgBuffer = array.array('B')
for i in xrange(WEB_WIDTH * WEB_HEIGHT):
self.imgBuffer.append(0)
self.imgBuffer.append(0)
self.imgBuffer.append(0)
self.imgBuffer.append(255)
if self.useHalfTexture:
self.leftBuffer = array.array('B')
for i in xrange(WEB_HALF_WIDTH * WEB_HEIGHT):
self.leftBuffer.append(0)
self.leftBuffer.append(0)
self.leftBuffer.append(0)
self.leftBuffer.append(255)
self.rightBuffer = array.array('B')
for i in xrange(WEB_HALF_WIDTH * WEB_HEIGHT):
self.rightBuffer.append(0)
self.rightBuffer.append(0)
self.rightBuffer.append(0)
self.rightBuffer.append(255)
self.setupTexture()
if self.useHalfTexture:
self.setupHalfTextures()
self.accept('mouse1', self.mouseDown, [AwWebView.LEFTMOUSEBTN])
self.accept('mouse3', self.mouseDown, [AwWebView.RIGHTMOUSEBTN])
self.accept('mouse1-up', self.mouseUp, [AwWebView.LEFTMOUSEBTN])
self.accept('mouse3-up', self.mouseUp, [AwWebView.RIGHTMOUSEBTN])
def getInGameNewsUrl(self):
result = config.GetString('fallback-news-url', 'http://cdn.toontown.disney.go.com/toontown/en/gamenews/')
override = config.GetString('in-game-news-url', '')
if override:
self.notify.info('got an override url, using %s for in a game news' % override)
result = override
else:
try:
launcherUrl = base.launcher.getValue('GAME_IN_GAME_NEWS_URL', '')
if launcherUrl:
result = launcherUrl
self.notify.info('got GAME_IN_GAME_NEWS_URL from launcher using %s' % result)
else:
self.notify.info('blank GAME_IN_GAME_NEWS_URL from launcher, using %s' % result)
except:
self.notify.warning('got exception getting GAME_IN_GAME_NEWS_URL from launcher, using %s' % result)
return result
def setupTexture(self):
cm = CardMaker('quadMaker')
cm.setColor(1.0, 1.0, 1.0, 1.0)
aspect = base.camLens.getAspectRatio()
htmlWidth = 2.0 * aspect * WEB_WIDTH_PIXELS / float(WIN_WIDTH)
htmlHeight = 2.0 * float(WEB_HEIGHT_PIXELS) / float(WIN_HEIGHT)
cm.setFrame(-htmlWidth / 2.0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0)
bottomRightX = WEB_WIDTH_PIXELS / float(WEB_WIDTH + 1)
bottomRightY = WEB_HEIGHT_PIXELS / float(WEB_HEIGHT + 1)
cm.setUvRange(Point2(0, 1 - bottomRightY), Point2(bottomRightX, 1))
card = cm.generate()
self.quad = NodePath(card)
self.quad.reparentTo(self.parent)
self.guiTex = Texture('guiTex')
self.guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba)
self.guiTex.setMinfilter(Texture.FTLinear)
self.guiTex.setKeepRamImage(True)
self.guiTex.makeRamImage()
self.guiTex.setWrapU(Texture.WMRepeat)
self.guiTex.setWrapV(Texture.WMRepeat)
ts = TextureStage('webTS')
self.quad.setTexture(ts, self.guiTex)
self.quad.setTexScale(ts, 1.0, -1.0)
self.quad.setTransparency(0)
self.quad.setTwoSided(True)
self.quad.setColor(1.0, 1.0, 1.0, 1.0)
self.calcMouseLimits()
def setupHalfTextures(self):
self.setupLeftTexture()
self.setupRightTexture()
self.fullPnmImage = PNMImage(WEB_WIDTH, WEB_HEIGHT, 4)
self.leftPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)
self.rightPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)
def setupLeftTexture(self):
cm = CardMaker('quadMaker')
cm.setColor(1.0, 1.0, 1.0, 1.0)
aspect = base.camLens.getAspectRatio()
htmlWidth = 2.0 * aspect * WEB_WIDTH / float(WIN_WIDTH)
htmlHeight = 2.0 * float(WEB_HEIGHT) / float(WIN_HEIGHT)
cm.setFrame(-htmlWidth / 2.0, 0, -htmlHeight / 2.0, htmlHeight / 2.0)
card = cm.generate()
self.leftQuad = NodePath(card)
self.leftQuad.reparentTo(self.parent)
self.leftGuiTex = Texture('guiTex')
self.leftGuiTex.setupTexture(Texture.TT2dTexture, WEB_HALF_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba)
self.leftGuiTex.setKeepRamImage(True)
self.leftGuiTex.makeRamImage()
self.leftGuiTex.setWrapU(Texture.WMClamp)
self.leftGuiTex.setWrapV(Texture.WMClamp)
ts = TextureStage('leftWebTS')
self.leftQuad.setTexture(ts, self.leftGuiTex)
self.leftQuad.setTexScale(ts, 1.0, -1.0)
self.leftQuad.setTransparency(0)
self.leftQuad.setTwoSided(True)
self.leftQuad.setColor(1.0, 1.0, 1.0, 1.0)
def setupRightTexture(self):
cm = CardMaker('quadMaker')
cm.setColor(1.0, 1.0, 1.0, 1.0)
aspect = base.camLens.getAspectRatio()
htmlWidth = 2.0 * aspect * WEB_WIDTH / float(WIN_WIDTH)
htmlHeight = 2.0 * float(WEB_HEIGHT) / float(WIN_HEIGHT)
cm.setFrame(0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0)
card = cm.generate()
self.rightQuad = NodePath(card)
self.rightQuad.reparentTo(self.parent)
self.rightGuiTex = Texture('guiTex')
self.rightGuiTex.setupTexture(Texture.TT2dTexture, WEB_HALF_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba)
self.rightGuiTex.setKeepRamImage(True)
self.rightGuiTex.makeRamImage()
self.rightGuiTex.setWrapU(Texture.WMClamp)
self.rightGuiTex.setWrapV(Texture.WMClamp)
ts = TextureStage('rightWebTS')
self.rightQuad.setTexture(ts, self.rightGuiTex)
self.rightQuad.setTexScale(ts, 1.0, -1.0)
self.rightQuad.setTransparency(0)
self.rightQuad.setTwoSided(True)
self.rightQuad.setColor(1.0, 1.0, 1.0, 1.0)
def calcMouseLimits(self):
ll = Point3()
ur = Point3()
self.quad.calcTightBounds(ll, ur)
self.notify.debug('ll=%s ur=%s' % (ll, ur))
offset = self.quad.getPos(aspect2d)
self.notify.debug('offset = %s ' % offset)
ll.setZ(ll.getZ() + offset.getZ())
ur.setZ(ur.getZ() + offset.getZ())
self.notify.debug('new LL=%s, UR=%s' % (ll, ur))
relPointll = self.quad.getRelativePoint(aspect2d, ll)
self.notify.debug('relPoint = %s' % relPointll)
self.mouseLL = (aspect2d.getScale()[0] * ll[0], aspect2d.getScale()[2] * ll[2])
self.mouseUR = (aspect2d.getScale()[0] * ur[0], aspect2d.getScale()[2] * ur[2])
self.notify.debug('original mouseLL=%s, mouseUR=%s' % (self.mouseLL, self.mouseUR))
def writeTex(self, filename = 'guiText.png'):
self.notify.debug('writing texture')
self.guiTex.generateRamMipmapImages()
self.guiTex.write(filename)
def toggleRotation(self):
if self.interval.isPlaying():
self.interval.finish()
else:
self.interval.loop()
def mouseDown(self, button):
messenger.send('wakeup')
self.webView.injectMouseDown(button)
def mouseUp(self, button):
self.webView.injectMouseUp(button)
def reload(self):
pass
def zoomIn(self):
self.webView.zoomIn()
def zoomOut(self):
self.webView.zoomOut()
def toggleTransparency(self):
self.transparency = not self.transparency
self.webView.setTransparent(self.transparency)
def update(self, task):
if base.mouseWatcherNode.hasMouse():
x, y = self._translateRelativeCoordinates(base.mouseWatcherNode.getMouseX(), base.mouseWatcherNode.getMouseY())
if self.mx - x != 0 or self.my - y != 0:
self.webView.injectMouseMove(x, y)
self.mx, self.my = x, y
if self.webView.isDirty():
self.webView.render(self.imgBuffer.buffer_info()[0], WEB_WIDTH * 4, 4)
Texture.setTexturesPower2(2)
textureBuffer = self.guiTex.modifyRamImage()
textureBuffer.setData(self.imgBuffer.tostring())
if self.useHalfTexture:
self.guiTex.store(self.fullPnmImage)
self.leftPnmImage.copySubImage(self.fullPnmImage, 0, 0, 0, 0, WEB_HALF_WIDTH, WEB_HEIGHT)
self.rightPnmImage.copySubImage(self.fullPnmImage, 0, 0, WEB_HALF_WIDTH, 0, WEB_HALF_WIDTH, WEB_HEIGHT)
self.leftGuiTex.load(self.leftPnmImage)
self.rightGuiTex.load(self.rightPnmImage)
self.quad.hide()
Texture.setTexturesPower2(1)
GlobalWebcore.update()
return Task.cont
def _translateRelativeCoordinates(self, x, y):
sx = int((x - self.mouseLL[0]) / (self.mouseUR[0] - self.mouseLL[0]) * WEB_WIDTH_PIXELS)
sy = WEB_HEIGHT_PIXELS - int((y - self.mouseLL[1]) / (self.mouseUR[1] - self.mouseLL[1]) * WEB_HEIGHT_PIXELS)
return (sx, sy)
def unload(self):
self.ignoreAll()
self.webView.destroy()
self.webView = None
return
def onCallback(self, name, args):
if name == 'requestFPS':
pass
def onBeginNavigation(self, url, frameName):
pass
def onBeginLoading(self, url, frameName, statusCode, mimeType):
pass
def onFinishLoading(self):
self.notify.debug('finished loading')
def onReceiveTitle(self, title, frameName):
pass
def onChangeTooltip(self, tooltip):
pass
def onChangeCursor(self, cursor):
pass
def onChangeKeyboardFocus(self, isFocused):
pass
def onChangeTargetURL(self, url):
pass