2019-11-02 17:27:54 -05:00
|
|
|
import os
|
2022-12-16 18:40:57 -06:00
|
|
|
from panda3d.core import VirtualFileSystem, Filename, DSearchPath
|
|
|
|
from panda3d.core import Texture, CardMaker, PNMImage, TextureStage
|
|
|
|
from panda3d.core import NodePath
|
|
|
|
from panda3d.core import Point2
|
2019-11-02 17:27:54 -05:00
|
|
|
from direct.showbase import DirectObject
|
|
|
|
from direct.gui.DirectGui import DirectFrame, DirectButton, DGG, DirectLabel
|
|
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
|
|
from toontown.toonbase import TTLocalizer
|
|
|
|
from toontown.toonbase import ToontownGlobals
|
|
|
|
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
|
|
|
|
|
|
|
|
class IssueFrame(DirectFrame):
|
|
|
|
NewsBaseDir = config.GetString('news-base-dir', '/httpNews')
|
|
|
|
FrameDimensions = (-1.30666637421,
|
|
|
|
1.30666637421,
|
|
|
|
-0.751666665077,
|
|
|
|
0.751666665077)
|
|
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('IssueFrame')
|
|
|
|
ContentPattern = 'tt_i_art_%s_%s%d.jpg'
|
|
|
|
SectionIdents = ['hom',
|
|
|
|
'new',
|
|
|
|
'evt',
|
|
|
|
'tot',
|
|
|
|
'att',
|
|
|
|
'tnr']
|
|
|
|
|
|
|
|
def __init__(self, parent, newsDir, dateStr, myIssueIndex, numIssues, strFilenames):
|
|
|
|
DirectFrame.__init__(self, frameColor=(1, 1, 1, 0), frameSize=self.FrameDimensions, relief=DGG.FLAT, parent=parent)
|
|
|
|
self.hide()
|
|
|
|
self.accept('newsSnapshot', self.doSnapshot)
|
2019-11-17 17:51:35 -06:00
|
|
|
self._parent = parent
|
2019-11-02 17:27:54 -05:00
|
|
|
self.newsDir = newsDir
|
|
|
|
self.dateStr = dateStr
|
|
|
|
self.myIssueIndex = myIssueIndex
|
|
|
|
self.numIssues = numIssues
|
|
|
|
self.strFilenames = strFilenames
|
|
|
|
self.sectionList = []
|
|
|
|
self.sectionFrames = {}
|
|
|
|
self.flatSubsectionList = []
|
|
|
|
self.parseNewsContent()
|
|
|
|
self.load()
|
|
|
|
self.curSection = 0
|
|
|
|
self.curSubsection = 0
|
|
|
|
|
|
|
|
def parseNewsContent(self):
|
|
|
|
for section, ident in enumerate(self.SectionIdents):
|
|
|
|
subSectionList = []
|
|
|
|
curSubSection = 0
|
|
|
|
endSearch = False
|
|
|
|
while not endSearch:
|
|
|
|
justName = self.ContentPattern % (self.dateStr, ident, curSubSection + 1)
|
|
|
|
fullName = Filename(self.newsDir + '/' + justName)
|
|
|
|
if self.strFilenames:
|
|
|
|
if justName in self.strFilenames:
|
|
|
|
subSectionList.append(fullName)
|
|
|
|
self.flatSubsectionList.append((section, curSubSection))
|
|
|
|
curSubSection += 1
|
|
|
|
else:
|
|
|
|
endSearch = True
|
|
|
|
else:
|
|
|
|
theFile = vfs.getFile(Filename(fullName), status_only=1)
|
|
|
|
if theFile:
|
|
|
|
subSectionList.append(fullName)
|
|
|
|
self.flatSubsectionList.append((section, curSubSection))
|
|
|
|
curSubSection += 1
|
|
|
|
else:
|
|
|
|
endSearch = True
|
|
|
|
|
|
|
|
if not subSectionList:
|
|
|
|
self.notify.warning('Could not load %s' % fullName)
|
|
|
|
subSectionList.append('error_' + str(fullName))
|
|
|
|
self.flatSubsectionList.append((section, 0))
|
|
|
|
self.sectionList.append(subSectionList)
|
|
|
|
|
|
|
|
self.notify.debug('%s' % self.sectionList)
|
|
|
|
|
|
|
|
def getPreviousTarget(self, section, subSection):
|
|
|
|
result = None
|
|
|
|
if (section, subSection) in self.flatSubsectionList:
|
|
|
|
index = self.flatSubsectionList.index((section, subSection))
|
|
|
|
if index > 0:
|
|
|
|
result = self.flatSubsectionList[index - 1]
|
|
|
|
return result
|
|
|
|
|
|
|
|
def getNextTarget(self, section, subSection):
|
|
|
|
result = None
|
|
|
|
if (section, subSection) in self.flatSubsectionList:
|
|
|
|
index = self.flatSubsectionList.index((section, subSection))
|
|
|
|
if index < len(self.flatSubsectionList) - 1:
|
|
|
|
result = self.flatSubsectionList[index + 1]
|
|
|
|
return result
|
|
|
|
|
|
|
|
def load(self):
|
|
|
|
self.gui = loader.loadModel('phase_3.5/models/gui/tt_m_gui_ign_directNewsGui')
|
|
|
|
self.guiNav = loader.loadModel('phase_3.5/models/gui/tt_m_gui_ign_directNewsGuiNav')
|
|
|
|
numPagesLoaded = 0
|
|
|
|
totalNumberOfPages = len(self.flatSubsectionList)
|
|
|
|
for section, subSectionList in enumerate(self.sectionList):
|
|
|
|
self.notify.debug('loading section %d' % section)
|
|
|
|
self.sectionFrames[section] = {}
|
|
|
|
for subsection, fullFilename in enumerate(subSectionList):
|
|
|
|
self.notify.debug('loading subsection %d' % subsection)
|
|
|
|
newPage = self.createPage(section, subsection, fullFilename)
|
|
|
|
numPagesLoaded += 1
|
|
|
|
self.sectionFrames[section][subsection] = newPage
|
|
|
|
|
|
|
|
def createPage(self, section, subsection, fullFilename):
|
|
|
|
upsellBackground = loader.loadModel('phase_3.5/models/gui/tt_m_gui_ign_newsStatusBackground')
|
|
|
|
imageScaleX = self.FrameDimensions[1] - self.FrameDimensions[0]
|
|
|
|
imageScaleY = self.FrameDimensions[3] - self.FrameDimensions[2]
|
|
|
|
pageFrame = DirectFrame(frameColor=(1, 1, 1, 0), frameSize=self.FrameDimensions, image=upsellBackground, image_scale=(imageScaleX, 1, imageScaleY), relief=DGG.FLAT, parent=self, text='', text_scale=0.06, text_pos=(0, -0.4))
|
|
|
|
if 'error_' in str(fullFilename):
|
|
|
|
pageFrame['text'] = TTLocalizer.NewsPageErrorDownloadingFileCanStillRead % fullFilename[len('error_'):]
|
|
|
|
else:
|
|
|
|
quad = self.loadFlatQuad(fullFilename)
|
|
|
|
if quad:
|
|
|
|
quad.reparentTo(pageFrame)
|
|
|
|
else:
|
|
|
|
pageFrame['text'] = TTLocalizer.NewsPageErrorDownloadingFileCanStillRead % fullFilename
|
|
|
|
self.loadRightArrow(section, subsection, pageFrame)
|
|
|
|
self.loadLeftArrow(section, subsection, pageFrame)
|
|
|
|
if section == 0 and subsection == 0:
|
|
|
|
self.loadHomePageButtons(section, subsection, pageFrame)
|
|
|
|
else:
|
|
|
|
self.loadNavButtons(pageFrame)
|
|
|
|
pageFrame.hide()
|
|
|
|
return pageFrame
|
|
|
|
|
|
|
|
def loadRightArrow(self, section, subsection, pageFrame):
|
|
|
|
nextTarget = self.getNextTarget(section, subsection)
|
|
|
|
position = (1.16, 0, -0.69)
|
|
|
|
xSize = 48
|
|
|
|
desiredXSize = 22
|
|
|
|
imageScale = float(desiredXSize) / xSize
|
|
|
|
if nextTarget:
|
|
|
|
image = self.gui.find('**/tt_i_art_btn_ArrowRight')
|
|
|
|
rollover = self.gui.find('**/tt_i_art_btn_ArrowRightRo')
|
|
|
|
rightArrow = DirectButton(relief=None, parent=pageFrame, command=self.gotoPage, extraArgs=(nextTarget[0], nextTarget[1]), image=(image,
|
|
|
|
image,
|
|
|
|
rollover,
|
|
|
|
image), pos=position, image_scale=imageScale)
|
|
|
|
return
|
|
|
|
|
|
|
|
def loadLeftArrow(self, section, subsection, pageFrame):
|
|
|
|
prevTarget = self.getPreviousTarget(section, subsection)
|
|
|
|
position = (-1.16, 0, -0.69)
|
|
|
|
xSize = 48
|
|
|
|
desiredXSize = 22
|
|
|
|
imageScale = float(desiredXSize) / xSize
|
|
|
|
if prevTarget:
|
|
|
|
image = self.gui.find('**/tt_i_art_btn_ArrowLeft')
|
|
|
|
rollover = self.gui.find('**/tt_i_art_btn_ArrowLeftRo')
|
|
|
|
rightArrow = DirectButton(relief=None, parent=pageFrame, command=self.gotoPage, extraArgs=(prevTarget[0], prevTarget[1]), image=(image,
|
|
|
|
image,
|
|
|
|
rollover,
|
|
|
|
image), pos=position, image_scale=imageScale)
|
|
|
|
return
|
|
|
|
|
|
|
|
def loadHomePageButtons(self, section, subsection, pageFrame):
|
|
|
|
buttonNames = ['',
|
|
|
|
'tt_i_art_btn_HomNew',
|
|
|
|
'tt_i_art_btn_HomEvt',
|
|
|
|
'tt_i_art_btn_HomTot',
|
|
|
|
'tt_i_art_btn_HomAsk',
|
|
|
|
'tt_i_art_btn_HomTnr']
|
|
|
|
rolloverButtonNames = []
|
|
|
|
for name in buttonNames:
|
|
|
|
ro = name + 'Ro'
|
|
|
|
rolloverButtonNames.append(ro)
|
|
|
|
|
|
|
|
positions = [(0, 0.0),
|
|
|
|
(-1.05333, 0, 0.29333),
|
|
|
|
(-1.05333, 0, 0.0666667),
|
|
|
|
(-1.05333, 0, -0.156667),
|
|
|
|
(-1.05333, 0, -0.383333),
|
|
|
|
(-1.05333, 0, -0.606667)]
|
|
|
|
xSize = 136
|
|
|
|
desiredXSize = 69
|
|
|
|
image_scale = float(desiredXSize) / xSize
|
|
|
|
image_scale *= float(69) / 70
|
|
|
|
self.sectionBtns = []
|
2019-12-30 00:07:56 -06:00
|
|
|
for section in range(1, len(self.SectionIdents)):
|
2019-11-02 17:27:54 -05:00
|
|
|
image = self.gui.find('**/%s' % buttonNames[section])
|
|
|
|
rolloverImage = self.gui.find('**/%s' % rolloverButtonNames[section])
|
|
|
|
if image.isEmpty():
|
|
|
|
self.notify.error('cant find %s' % buttonNames[section])
|
|
|
|
sectionBtn = DirectButton(relief=None, parent=pageFrame, image=(image,
|
|
|
|
image,
|
|
|
|
rolloverImage,
|
|
|
|
image), image_scale=image_scale, command=self.gotoPage, extraArgs=(section, 0), enableEdit=1, pos=positions[section])
|
|
|
|
|
|
|
|
readMorePos = (0.906666, 0, -0.19)
|
|
|
|
readImage = self.gui.find('**/tt_i_art_btn_ReadMore')
|
|
|
|
readRollover = self.gui.find('**/tt_i_art_btn_ReadMoreRo')
|
|
|
|
xSize = 228.0
|
|
|
|
desiredXSize = 113.0
|
|
|
|
imageScale = desiredXSize / xSize
|
|
|
|
readMoreBtn = DirectButton(relief=None, parent=pageFrame, image=(readImage,
|
|
|
|
readImage,
|
|
|
|
readRollover,
|
|
|
|
readImage), image_scale=imageScale, command=self.gotoPage, extraArgs=(1, 0), enableEdit=1, pos=readMorePos)
|
|
|
|
self.loadWeekNavButtons(pageFrame)
|
|
|
|
return
|
|
|
|
|
|
|
|
def loadWeekNavButtons(self, pageFrame):
|
|
|
|
if self.numIssues <= 1:
|
|
|
|
return
|
|
|
|
if self.myIssueIndex == self.numIssues - 1:
|
|
|
|
weekStr = TTLocalizer.IssueFrameThisWeek
|
|
|
|
elif self.myIssueIndex == self.numIssues - 2:
|
|
|
|
weekStr = TTLocalizer.IssueFrameLastWeek
|
|
|
|
else:
|
|
|
|
weeksAgo = self.numIssues - self.myIssueIndex - 1
|
|
|
|
weekStr = TTLocalizer.IssueFrameWeeksAgo % weeksAgo
|
|
|
|
prevImage = self.gui.find('**/tt_i_art_btn_ArchiveArrwLeftNormal')
|
|
|
|
prevImageRo = self.gui.find('**/tt_i_art_btn_ArchiveArrwLeftRo')
|
|
|
|
prevImageDisabled = self.gui.find('**/tt_i_art_btn_ArchiveArrwLeftDisabled')
|
|
|
|
actualY1 = 78.0
|
|
|
|
desiredY1 = 42.0
|
|
|
|
y1Scale = desiredY1 / actualY1
|
|
|
|
prevWeekBtn = DirectButton(relief=None, parent=pageFrame, image=[prevImage,
|
|
|
|
prevImage,
|
|
|
|
prevImageRo,
|
|
|
|
prevImageDisabled], image_scale=y1Scale, command=self.changeWeek, extraArgs=(self.myIssueIndex - 1,), pos=(0.806666, 0, 0.62))
|
|
|
|
if self.myIssueIndex == 0:
|
|
|
|
prevWeekBtn['state'] = DGG.DISABLED
|
|
|
|
nextImage = self.gui.find('**/tt_i_art_btn_ArchiveArrwRightNormal')
|
|
|
|
nextImageRo = self.gui.find('**/tt_i_art_btn_ArchiveArrwRightRo')
|
|
|
|
nextImageDisabled = self.gui.find('**/tt_i_art_btn_ArchiveArrwRightDisabled')
|
|
|
|
actualY2Scale = 63.0
|
|
|
|
desiredY2Scale = 34.0
|
|
|
|
y2Scale = desiredY2Scale / actualY2Scale
|
|
|
|
nextWeekBtn = DirectButton(relief=None, parent=pageFrame, image=[nextImage,
|
|
|
|
nextImage,
|
|
|
|
nextImageRo,
|
|
|
|
nextImageDisabled], image_scale=y2Scale, command=self.changeWeek, extraArgs=(self.myIssueIndex + 1,), pos=(1.16, 0, 0.623333))
|
|
|
|
if self.myIssueIndex == self.numIssues - 1:
|
|
|
|
nextWeekBtn['state'] = DGG.DISABLED
|
|
|
|
actualX = 176.0
|
|
|
|
desiredX = 89.0
|
|
|
|
imageScale = desiredX / actualX
|
|
|
|
midImage = self.gui.find('**/tt_i_art_btn_ArchiveMiddle')
|
|
|
|
weekColor = (0.0 / 255.0,
|
|
|
|
23.0 / 255.0,
|
|
|
|
140.0 / 255.0,
|
|
|
|
1.0)
|
|
|
|
weekLabel = DirectLabel(relief=None, image=midImage, image_scale=imageScale, parent=pageFrame, text=weekStr, text_font=ToontownGlobals.InterfaceFont, text_fg=weekColor, text_scale=0.043, text_pos=(0, -0.01, 0), pos=(0.983333, 0, 0.62))
|
|
|
|
return
|
|
|
|
|
|
|
|
def loadNavButtons(self, pageFrame):
|
|
|
|
buttonNames = ['tt_i_art_btn_NavHom',
|
|
|
|
'tt_i_art_btn_NavNew',
|
|
|
|
'tt_i_art_btn_NavEvt',
|
|
|
|
'tt_i_art_btn_NavTot',
|
|
|
|
'tt_i_art_btn_NavAtt',
|
|
|
|
'tt_i_art_btn_NavTnr']
|
|
|
|
rolloverButtonNames = []
|
|
|
|
for name in buttonNames:
|
|
|
|
ro = name + 'Ro'
|
|
|
|
rolloverButtonNames.append(ro)
|
|
|
|
|
|
|
|
xPos = 1.24667
|
|
|
|
positions = [(xPos, 0, 0.623333),
|
|
|
|
(xPos, 0, 0.536663),
|
|
|
|
(xPos, 0, 0.45),
|
|
|
|
(xPos, 0, 0.36333),
|
|
|
|
(xPos, 0, 0.276667),
|
|
|
|
(xPos, 0, 0.19)]
|
|
|
|
xSize1 = 177
|
|
|
|
desiredXSize1 = 90
|
|
|
|
image_scale1 = float(desiredXSize1) / xSize1
|
|
|
|
image_scale = 1
|
|
|
|
xSize2 = 300
|
|
|
|
desiredXSize2 = 152
|
|
|
|
image_scale2 = float(desiredXSize2) / xSize2
|
|
|
|
image_scale2 *= 30.0 / 30.0
|
|
|
|
rolloverPositions = [(1.15, 0, 0.623333),
|
|
|
|
(1.15, 0, 0.533333),
|
|
|
|
(1.15, 0, 0.443333),
|
|
|
|
(1.045, 0, 0.353333),
|
|
|
|
(1.045, 0, 0.263334),
|
|
|
|
(1.045, 0, 0.173333)]
|
|
|
|
imageScales = [image_scale1,
|
|
|
|
image_scale1,
|
|
|
|
image_scale1,
|
|
|
|
image_scale2,
|
|
|
|
image_scale2,
|
|
|
|
image_scale2]
|
|
|
|
frameSizeAdj1 = 0.1
|
|
|
|
frameSize1 = (-0.04 + frameSizeAdj1,
|
|
|
|
0.04 + frameSizeAdj1,
|
|
|
|
-0.04,
|
|
|
|
0.04)
|
|
|
|
frameSizeAdj2 = 0.21
|
|
|
|
frameSize2 = (-0.04 + frameSizeAdj2,
|
|
|
|
0.04 + frameSizeAdj2,
|
|
|
|
-0.04,
|
|
|
|
0.04)
|
|
|
|
frameSizes = (frameSize1,
|
|
|
|
frameSize1,
|
|
|
|
frameSize1,
|
|
|
|
frameSize2,
|
|
|
|
frameSize2,
|
|
|
|
frameSize2)
|
|
|
|
self.sectionBtns = []
|
2019-12-30 00:07:56 -06:00
|
|
|
for section in range(0, len(self.SectionIdents)):
|
2019-11-02 17:27:54 -05:00
|
|
|
image = self.guiNav.find('**/%s' % buttonNames[section])
|
|
|
|
rolloverImage = self.guiNav.find('**/%s' % rolloverButtonNames[section])
|
|
|
|
if image.isEmpty():
|
|
|
|
self.notify.error('cant find %s' % buttonNames[section])
|
|
|
|
sectionBtn = DirectButton(relief=None, parent=pageFrame, frameSize=frameSizes[section], image=(image,
|
|
|
|
rolloverImage,
|
|
|
|
rolloverImage,
|
|
|
|
image), image_scale=imageScales[section], command=self.gotoPage, extraArgs=(section, 0), enableEdit=1, pos=rolloverPositions[section])
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
def gotoPage(self, section, subsection):
|
|
|
|
if base.config.GetBool('want-qa-regression', 0):
|
|
|
|
self.notify.info('QA-REGRESSION: INGAMENEWS: Goto Page')
|
|
|
|
self.sectionFrames[self.curSection][self.curSubsection].hide()
|
|
|
|
self.sectionFrames[section][subsection].show()
|
|
|
|
self.curSection = section
|
|
|
|
self.curSubsection = subsection
|
|
|
|
messenger.send('wakeup')
|
|
|
|
base.cr.centralLogger.writeClientEvent('news gotoPage %s %s %s' % (self.dateStr, section, subsection))
|
|
|
|
|
|
|
|
def loadFlatQuad(self, fullFilename):
|
|
|
|
cm = CardMaker('cm-%s' % fullFilename)
|
|
|
|
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()
|
|
|
|
quad = NodePath(card)
|
|
|
|
jpgFile = PNMImage(WEB_WIDTH, WEB_HEIGHT)
|
|
|
|
smallerJpgFile = PNMImage()
|
|
|
|
readFile = smallerJpgFile.read(Filename(fullFilename))
|
|
|
|
if readFile:
|
|
|
|
jpgFile.copySubImage(smallerJpgFile, 0, 0)
|
|
|
|
guiTex = Texture('guiTex')
|
|
|
|
guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba)
|
|
|
|
guiTex.setMinfilter(Texture.FTLinear)
|
|
|
|
guiTex.load(jpgFile)
|
|
|
|
guiTex.setWrapU(Texture.WMClamp)
|
|
|
|
guiTex.setWrapV(Texture.WMClamp)
|
|
|
|
ts = TextureStage('webTS')
|
|
|
|
quad.setTexture(ts, guiTex)
|
|
|
|
quad.setTransparency(0)
|
|
|
|
quad.setTwoSided(True)
|
|
|
|
quad.setColor(1.0, 1.0, 1.0, 1.0)
|
|
|
|
result = quad
|
|
|
|
else:
|
|
|
|
result = None
|
|
|
|
Texture.setTexturesPower2(1)
|
|
|
|
return result
|
|
|
|
|
|
|
|
def loadBackground(self):
|
|
|
|
self.backFrame = DirectFrame(parent=self, frameColor=(1, 1, 1, 1), frameSize=self.FrameDimensions, pos=(0, 0, 0), relief=None)
|
|
|
|
return
|
|
|
|
|
|
|
|
def loadMainPage(self):
|
|
|
|
self.mainFrame = DirectFrame(parent=self, frameSize=self.FrameDimensions, frameColor=(1, 0, 0, 1))
|
|
|
|
|
|
|
|
def activate(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def deactivate(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def unload(self):
|
|
|
|
self.ignore('newsSnapshot')
|
|
|
|
|
|
|
|
def doSnapshot(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def changeWeek(self, newIssueWeek):
|
|
|
|
if base.config.GetBool('want-qa-regression', 0):
|
|
|
|
self.notify.info('QA-REGRESSION: INGAMENEWS: Change Week')
|
|
|
|
messenger.send('newsChangeWeek', [newIssueWeek])
|