from panda3d.core import * import ShtikerPage import ShtikerBook from direct.gui.DirectGui import * from direct.directnotify import DirectNotifyGlobal from toontown.toonbase import TTLocalizer import os import string from toontown.toonbase import ToontownGlobals from sys import platform class PhotoAlbumPage(ShtikerPage.ShtikerPage): notify = DirectNotifyGlobal.directNotify.newCategory('PhotoAlbumPage') def __init__(self): ShtikerPage.ShtikerPage.__init__(self) self.textRolloverColor = Vec4(1, 1, 0, 1) self.textDownColor = Vec4(0.5, 0.9, 1, 1) self.textDisabledColor = Vec4(0.4, 0.8, 0.4, 1) self.photos = {} self.selectedFileName = None self.selectedFilePath = None self.installPath = os.getcwd() self.photoPath = TTLocalizer.ScreenshotPath self.photoIndex = 0 return def load(self): if not os.path.exists(self.photoPath): os.mkdir(self.photoPath) self.notify.info('Made new directory to save screenshots.') self.title = DirectLabel(parent=self, relief=None, text=TTLocalizer.PhotoPageTitle, text_scale=0.1, pos=(0, 0, 0.6)) self.pictureImage = loader.loadModel('phase_3.5/models/gui/photo_frame') self.pictureImage.setScale(0.2) self.pictureImage.setPos(0.44, 0, 0.25) self.pictureImage.reparentTo(self) self.pictureFg = self.pictureImage.find('**/fg') self.pictureFg.setColor(1, 1, 1, 0.1) guiButton = loader.loadModel('phase_3/models/gui/quit_button') self.pictureCaption = DirectLabel(parent=self, relief=None, text=TTLocalizer.PhotoPageAddName, text_scale=0.05, text_wordwrap=10, text_align=TextNode.ACenter, pos=(0.45, 0, -0.22)) self.renameButton = DirectButton(parent=self, relief=None, image=(guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')), image_scale=(1, 1, 1), pos=(0.40, 0, -0.35), text=TTLocalizer.PhotoPageAddName, text_scale=0.06, text_pos=(0, -0.02), command=self.renameImage, state=DGG.DISABLED) self.directoryButton = DirectButton(parent=self, relief=None, image=(guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')), image_scale=(1.3, 1, 1), pos=(0.46, 0, -0.50), text=TTLocalizer.PhotoPageDirectory, text_scale=0.06, text_pos=(0, -0.02), command=self.openPhotoDirectory, state=DGG.NORMAL) trashcanGui = loader.loadModel('phase_3/models/gui/trashcan_gui') self.deleteButton = DirectButton(parent=self, image=(trashcanGui.find('**/TrashCan_CLSD'), trashcanGui.find('**/TrashCan_OPEN'), trashcanGui.find('**/TrashCan_RLVR')), text=('', TTLocalizer.AvatarChoiceDelete, TTLocalizer.AvatarChoiceDelete), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), text_scale=0.1, text_pos=(0, -0.1), text_font=ToontownGlobals.getInterfaceFont(), textMayChange=0, relief=None, pos=(0.68, 0, -0.33), scale=0.4, state=DGG.DISABLED, command=self.deleteImage) guiButton.removeNode() trashcanGui.removeNode() gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui') self.scrollList = DirectScrolledList(parent=self, relief=None, forceHeight=0.07, pos=(-0.5, 0, 0), incButton_image=(gui.find('**/FndsLst_ScrollUp'), gui.find('**/FndsLst_ScrollDN'), gui.find('**/FndsLst_ScrollUp_Rllvr'), gui.find('**/FndsLst_ScrollUp')), incButton_relief=None, incButton_scale=(1.3, 1.3, -1.3), incButton_pos=(0.08, 0, -0.60), incButton_image3_color=Vec4(1, 1, 1, 0.2), decButton_image=(gui.find('**/FndsLst_ScrollUp'), gui.find('**/FndsLst_ScrollDN'), gui.find('**/FndsLst_ScrollUp_Rllvr'), gui.find('**/FndsLst_ScrollUp')), decButton_relief=None, decButton_scale=(1.3, 1.3, 1.3), decButton_pos=(0.08, 0, 0.52), decButton_image3_color=Vec4(1, 1, 1, 0.2), itemFrame_pos=(-0.237, 0, 0.41), itemFrame_scale=1.0, itemFrame_relief=DGG.SUNKEN, itemFrame_frameSize=(-0.05, 0.66, -0.98, 0.07), itemFrame_frameColor=(0.85, 0.95, 1, 1), itemFrame_borderWidth=(0.01, 0.01), numItemsVisible=13, items=[]) self.renamePanel = DirectFrame(parent=self, relief=None, pos=(0.45, 0, -0.45), image=DGG.getDefaultDialogGeom(), image_color=ToontownGlobals.GlobalDialogColor, image_scale=(1.0, 1.0, 0.6), text=TTLocalizer.PhotoPageAddNamePanel, text_scale=0.06, text_pos=(0.0, 0.13), sortOrder=NO_FADE_SORT_INDEX) self.renameEntry = DirectEntry(parent=self.renamePanel, relief=DGG.SUNKEN, scale=0.06, pos=(-0.3, 0, 0), borderWidth=(0.1, 0.1), numLines=1, cursorKeys=1, frameColor=(0.8, 0.8, 0.5, 1), frameSize=(-0.2, 10, -0.4, 1.1), command=self.renameDialog) buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui') self.bCancel = DirectButton(parent=self.renamePanel, image=(buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')), relief=None, text=TTLocalizer.PhotoPageCancel, text_scale=0.05, text_pos=(0.0, -0.1), pos=(0.0, 0.0, -0.1), command=self.renameCancel) self.renamePanel.hide() self.deletePanel = DirectFrame(parent=self, relief=None, pos=(0.45, 0, -0.45), image=DGG.getDefaultDialogGeom(), image_color=ToontownGlobals.GlobalDialogColor, image_scale=(1.0, 1.0, 0.6), text='', text_scale=0.06, text_pos=(0.0, 0.13), sortOrder=NO_FADE_SORT_INDEX) self.dOk = DirectButton(parent=self.deletePanel, image=(buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr')), relief=None, text=TTLocalizer.PhotoPageConfirm, text_scale=0.05, text_pos=(0.0, -0.1), pos=(-0.1, 0.0, -0.1), command=self.deleteConfirm) self.dCancel = DirectButton(parent=self.deletePanel, image=(buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')), relief=None, text=TTLocalizer.PhotoPageCancel, text_scale=0.05, text_pos=(0.0, -0.1), pos=(0.1, 0.0, -0.1), command=self.deleteCancel) self.deletePanel.hide() self.errorPanel = DirectFrame(parent=self, relief=None, pos=(0.45, 0, -0.45), image=DGG.getDefaultDialogGeom(), image_color=ToontownGlobals.GlobalDialogColor, image_scale=(1.0, 1.0, 0.6), text='', text_wordwrap=16, text_scale=0.06, text_pos=(0.0, 0.13), sortOrder=NO_FADE_SORT_INDEX) self.bClose = DirectButton(parent=self.errorPanel, image=(buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')), relief=None, text=TTLocalizer.PhotoPageClose, text_scale=0.05, text_pos=(0.0, -0.1), pos=(0.0, 0.0, -0.1), command=self.errorConfirm) self.errorPanel.hide() self.scroll = loader.loadModel('phase_3/models/gui/toon_council').find('**/scroll') self.scroll.reparentTo(self) self.scroll.setPos(0.0, 1.0, 0.2) self.scroll.setScale(0.6, 0.6, 0.6) self.tip = DirectLabel(parent=self.scroll, relief=None, text=TTLocalizer.PhotoPageTutorial, text_scale=0.13, pos=(0.0, 0.0, 0.1), text_fg=(0.4, 0.3, 0.2, 1), text_wordwrap=18, text_align=TextNode.ACenter) self.leftArrow = DirectButton(parent=self, relief=None, image=(gui.find('**/Horiz_Arrow_UP'), gui.find('**/Horiz_Arrow_DN'), gui.find('**/Horiz_Arrow_Rllvr'), gui.find('**/Horiz_Arrow_UP')), image3_color=Vec4(1, 1, 1, 0.5), scale=(-1.0, 1.0, 1.0), pos=(0.15, 0, -0.21), command=self.prevPhoto) self.rightArrow = DirectButton(parent=self, relief=None, image=(gui.find('**/Horiz_Arrow_UP'), gui.find('**/Horiz_Arrow_DN'), gui.find('**/Horiz_Arrow_Rllvr'), gui.find('**/Horiz_Arrow_UP')), image3_color=Vec4(1, 1, 1, 0.5), pos=(0.75, 0, -0.21), command=self.nextPhoto) gui.removeNode() buttons.removeNode() return def unload(self): del self.title del self.scrollList del self.pictureImage del self.pictureFg del self.pictureCaption del self.deleteButton del self.renameButton del self.directoryButton del self.renamePanel del self.renameEntry del self.scroll del self.tip del self.errorPanel del self.bCancel del self.bClose del self.deletePanel del self.dOk del self.dCancel del self.leftArrow del self.rightArrow ShtikerPage.ShtikerPage.unload(self) def renameDialog(self, str): if os.path.isfile(self.photoPath + self.selectedFileName): separator = '_' validChars = string.letters + string.digits + ' -#&.,' str = filter(lambda s: s in validChars, str) oldName = self.selectedFileName numUnders = oldName.count(separator) if numUnders == 0: newName = oldName[0:18] + separator + str + separator + oldName[17:] elif numUnders == 2: sp = oldName.split(separator) newName = sp[0] + separator + str + separator + sp[2] else: self.renameCleanup() return 0 if str.isspace() or str == '': self.renameCancel() else: os.rename(self.photoPath + oldName, self.photoPath + newName) self.renameCleanup() self.updateScrollList() self.chosePhoto(newName) return 1 else: self.renameCancel() self.errorPanel['text'] = 'Huh. It looks like this snapshot has been deleted or removed.' self.errorPanel.show() self.updateScrollList() def renameCancel(self): self.renameCleanup() def renameCleanup(self): self.renamePanel.hide() chatEntry = base.localAvatar.chatMgr.chatInputNormal.chatEntry chatEntry['backgroundFocus'] = self.oldFocus def renameImage(self): self.deleteCleanup() if self.getPhotoName(self.selectedFileName) == TTLocalizer.PhotoPageNoName: self.renameEntry.set('') else: self.renameEntry.set(self.getPhotoName(self.selectedFileName)) self.renamePanel.show() chatEntry = base.localAvatar.chatMgr.chatInputNormal.chatEntry chatEntry['backgroundFocus'] = 0 self.renameEntry['focus'] = 1 self.notify.debug(self.selectedFileName) def deleteConfirm(self): if os.path.isfile(self.photoPath + self.selectedFileName): os.remove(self.photoPath + self.selectedFileName) self.selectedFileName = None self.deleteCleanup() self.updateScrollList() return else: self.deleteCancel() self.errorPanel['text'] = 'Huh. It looks like this snapshot has already been deleted.' self.errorPanel.show() self.updateScrollList() def deleteCancel(self): self.deleteCleanup() def deleteCleanup(self): self.deletePanel.hide() def deleteImage(self): self.renameCleanup() self.deletePanel['text'] = TTLocalizer.PhotoPageDelete + '\n"%s"?' % self.getPhotoName(self.selectedFileName) self.deletePanel.show() def makePhotoButton(self, fileName): return DirectButton(relief=None, text=self.getPhotoName(fileName), text_scale=0.06, text_align=TextNode.ALeft, text1_bg=self.textDownColor, text2_bg=self.textRolloverColor, text3_fg=self.textDisabledColor, command=self.chosePhoto, extraArgs=[fileName]) def errorConfirm(self): self.errorPanel.hide() def getPhotoName(self, fileName): separator = '_' numUnders = fileName.count(separator) if numUnders == 0: return TTLocalizer.PhotoPageNoName elif numUnders == 2: return fileName.split(separator)[1] else: return TTLocalizer.PhotoPageUnknownName def chosePhoto(self, fileName): if fileName: self.selectedFileName = fileName self.selectedFilePath = self.photoPath + fileName if os.path.isfile(self.photoPath + self.selectedFileName): photoTexture = loader.loadTexture(self.selectedFilePath) photoName = self.getPhotoName(fileName) self.pictureFg.setTexture(photoTexture, 1) self.pictureFg.setColor(1, 1, 1, 1) self.pictureCaption['text'] = photoName self.renameButton['state'] = DGG.NORMAL self.deleteButton['state'] = DGG.NORMAL self.renameEntry.set(photoName) else: self.errorPanel['text'] = 'Huh. It looks like this snapshot has been deleted or removed.' self.errorPanel.show() self.updateScrollList() else: self.selectedFileName = None self.pictureFg.clearTexture() self.pictureFg.setColor(1, 1, 1, 0.1) self.pictureCaption['text'] = '' self.renameButton['state'] = DGG.DISABLED self.deleteButton['state'] = DGG.DISABLED self.renameEntry.set('') return def getPhotos(self): files = os.listdir(self.photoPath) photos = [] for fileName in files: if fileName[0:17] == 'stride-screenshot' and fileName[-4:] == '.jpg': photos.append(fileName) return photos def openPhotoDirectory(self): if platform == "darwin": OSXPhotoDir = self.installPath + '/user/screenshots' os.system('open "%s"' % OSXPhotoDir) self.notify.debug(OSXPhotoDir) elif platform == "win32": PhotoDir = self.installPath + '/user/screenshots/' os.startfile(PhotoDir) self.notify.debug(PhotoDir) def newScreenshot(self, filename): self.updateScrollList() def updateScrollList(self): newPhotos = self.getPhotos() for photo in self.photos.keys(): if photo not in newPhotos: photoButton = self.photos[photo] self.scrollList.removeItem(photoButton) photoButton.destroy() del self.photos[photo] for photo in newPhotos: if not self.photos.has_key(photo): photoButton = self.makePhotoButton(photo) self.scrollList.addItem(photoButton) self.photos[photo] = photoButton if self.photos.keys(): self.chosePhoto(self.photos.keys()[0]) self.scroll.hide() self.scrollList.show() self.pictureImage.show() self.rightArrow.show() self.leftArrow.show() self.renameButton.show() self.deleteButton.show() self.scrollList.show() else: self.chosePhoto(None) self.scroll.show() self.scrollList.hide() self.pictureImage.hide() self.rightArrow.hide() self.leftArrow.hide() self.renameButton.hide() self.deleteButton.hide() return def enter(self): self.accept('screenshot', self.newScreenshot) self.updateScrollList() chatEntry = base.localAvatar.chatMgr.chatInputNormal.chatEntry self.oldFocus = chatEntry['backgroundFocus'] ShtikerPage.ShtikerPage.enter(self) def exit(self): self.ignore('screenshot') self.renameCleanup() self.deleteCleanup() ShtikerPage.ShtikerPage.exit(self) def updateArrows(self): self.photoIndex = 0 self.chosePhoto(self.getPhotos()[self.photoIndex]) def prevPhoto(self): try: self.chosePhoto(self.getPhotos()[self.photoIndex]) self.photoIndex -= 1 except:self.photoIndex = 0 def nextPhoto(self): try: self.chosePhoto(self.getPhotos()[self.photoIndex]) self.photoIndex += 1 except:self.photoIndex = 0