class MailboxScreen(DirectObject.DirectObject): notify = directNotify.newCategory('MailboxScreen') def __init__(self, mailbox, avatar, doneEvent = None): self.mailbox = mailbox self.avatar = avatar self.items = self.getItems() self.doneEvent = doneEvent self.itemIndex = 0 self.itemPanel = None self.itemPicture = None self.ival = None self.itemText = None self.giftTag = None self.acceptingIndex = None self.numAtticAccepted = 0 self.dialogBox = None self.load() self.hide() return def show(self): self.frame.show() self.__showCurrentItem() def hide(self): self.ignore('friendsListChanged') if hasattr(self, 'frame'): self.frame.hide() else: self.notify.warning('hide called, but frame is deleted, self.frame deleted in:') if hasattr(self, 'frameDelStackTrace'): print self.frameDelStackTrace self.notify.warning('current stackTrace =') print StackTrace() self.notify.warning('crash averted, but root cause unknown') def load(self): self.accept('setMailboxContents-%s' % base.localAvatar.doId, self.__refreshItems) self.accept('setAwardMailboxContents-%s' % base.localAvatar.doId, self.__refreshItems) model = loader.loadModel('phase_5.5/models/gui/package_delivery_panel') background = model.find('**/bg') itemBoard = model.find('**/item_board') self.frame = DirectFrame(scale=1.1, relief=DGG.FLAT, frameSize=(-0.5, 0.5, -0.45, -0.05), frameColor=(0.737, 0.573, 0.345, 1.0)) self.background = DirectFrame(self.frame, image=background, image_scale=0.05, relief=None, pos=(0, 1, 0)) self.itemBoard = DirectFrame(parent=self.frame, image=itemBoard, image_scale=0.05, image_color=(0.922, 0.922, 0.753, 1), relief=None, pos=(0, 1, 0)) self.itemCountLabel = DirectLabel(parent=self.frame, relief=None, text=self.__getNumberOfItemsText(), text_wordwrap=16, pos=(0.0, 0.0, 0.7), scale=0.09) exitUp = model.find('**/bu_return_rollover') exitDown = model.find('**/bu_return_rollover') exitRollover = model.find('**/bu_return_rollover') exitUp.setP(-90) exitDown.setP(-90) exitRollover.setP(-90) self.DiscardButton = DirectButton(parent=self.frame, relief=None, image=(exitUp, exitDown, exitRollover, exitUp), pos=(-0.01, 1.0, -0.36), scale=0.048, text=('', TTLocalizer.MailBoxDiscard, TTLocalizer.MailBoxDiscard, ''), text_scale=1.0, text_pos=(0, -0.08), textMayChange=1, command=self.__makeDiscardInterface) gui2 = loader.loadModel('phase_3/models/gui/quit_button') self.quitButton = DirectButton(parent=self.frame, relief=None, image=(gui2.find('**/QuitBtn_UP'), gui2.find('**/QuitBtn_DN'), gui2.find('**/QuitBtn_RLVR')), pos=(0.5, 1.0, -0.42), scale=0.9, text=TTLocalizer.MailboxExitButton, text_font=ToontownGlobals.getSignFont(), text0_fg=(0.152, 0.75, 0.258, 1), text1_fg=(0.152, 0.75, 0.258, 1), text2_fg=(0.977, 0.816, 0.133, 1), text_scale=0.045, text_pos=(0, -0.01), command=self.__handleExit) self.gettingText = DirectLabel(parent=self.frame, relief=None, text='', text_wordwrap=10, pos=(0.0, 0.0, 0.32), scale=0.09) self.gettingText.hide() self.giftTagPanel = DirectLabel(parent=self.frame, relief=None, text='Gift TAG!!', text_wordwrap=16, pos=(0.0, 0.0, 0.01), scale=0.06) self.giftTagPanel.hide() self.itemText = DirectLabel(parent=self.frame, relief=None, text='', text_wordwrap=16, pos=(0.0, 0.0, -0.022), scale=0.07) self.itemText.hide() acceptUp = model.find('**/bu_check_up') acceptDown = model.find('**/bu_check_down') acceptRollover = model.find('**/bu_check_rollover') acceptUp.setP(-90) acceptDown.setP(-90) acceptRollover.setP(-90) self.acceptButton = DirectButton(parent=self.frame, relief=None, image=(acceptUp, acceptDown, acceptRollover, acceptUp), image3_color=(0.8, 0.8, 0.8, 0.6), pos=(-0.01, 1.0, -0.16), scale=0.048, text=('', TTLocalizer.MailboxAcceptButton, TTLocalizer.MailboxAcceptButton, ''), text_scale=1.0, text_pos=(0, -0.09), textMayChange=1, command=self.__handleAccept, state=DGG.DISABLED) nextUp = model.find('**/bu_next_up') nextUp.setP(-90) nextDown = model.find('**/bu_next_down') nextDown.setP(-90) nextRollover = model.find('**/bu_next_rollover') nextRollover.setP(-90) self.nextButton = DirectButton(parent=self.frame, relief=None, image=(nextUp, nextDown, nextRollover, nextUp), image3_color=(0.8, 0.8, 0.8, 0.6), pos=(0.31, 1.0, -0.26), scale=0.05, text=('', TTLocalizer.MailboxItemNext, TTLocalizer.MailboxItemNext, ''), text_scale=1, text_pos=(-0.2, 0.3), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), textMayChange=0, command=self.__nextItem, state=DGG.DISABLED) prevUp = model.find('**/bu_previous_up') prevUp.setP(-90) prevDown = model.find('**/bu_previous_down') prevDown.setP(-90) prevRollover = model.find('**/bu_previous_rollover') prevRollover.setP(-90) self.prevButton = DirectButton(parent=self.frame, relief=None, image=(prevUp, prevDown, prevRollover, prevUp), pos=(-0.35, 1, -0.26), scale=0.05, image3_color=(0.8, 0.8, 0.8, 0.6), text=('', TTLocalizer.MailboxItemPrev, TTLocalizer.MailboxItemPrev, ''), text_scale=1, text_pos=(0, 0.3), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), textMayChange=0, command=self.__prevItem, state=DGG.DISABLED) self.currentItem = None self.partyInviteVisual = InviteVisual(self.frame) self.partyInviteVisual.setScale(0.73) self.partyInviteVisual.setPos(0.0, 0.0, 0.48) self.partyInviteVisual.stash() if self.avatar: self.avatar.applyCheesyEffect(ToontownGlobals.CENormal) return def unload(self): if self.avatar: self.avatar.reconsiderCheesyEffect() self.__clearCurrentItem() if hasattr(self, 'frame'): self.frame.destroy() del self.frame self.frameDelStackTrace = StackTrace() else: self.notify.warning('unload, no self.frame') if hasattr(self, 'mailbox'): del self.mailbox else: self.notify.warning('unload, no self.mailbox') if self.dialogBox: self.dialogBox.cleanup() self.dialogBox = None for item in self.items: if isinstance(item, CatalogItem.CatalogItem): item.acceptItemCleanup() self.ignoreAll() return def justExit(self): self.__acceptExit() def __handleExit(self): if self.numAtticAccepted == 0: self.__acceptExit() elif self.numAtticAccepted == 1: self.dialogBox = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=TTLocalizer.CatalogAcceptInAttic, text_wordwrap=15, command=self.__acceptExit) self.dialogBox.show() else: self.dialogBox = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=TTLocalizer.CatalogAcceptInAtticP, text_wordwrap=15, command=self.__acceptExit) self.dialogBox.show() def __acceptExit(self, buttonValue = None): if hasattr(self, 'frame'): self.hide() self.unload() messenger.send(self.doneEvent) def __handleAccept(self): if base.config.GetBool('want-qa-regression', 0): self.notify.info('QA-REGRESSION: MAILBOX: Accept item') if self.acceptingIndex != None: return item = self.items[self.itemIndex] isAward = False if isinstance(item, CatalogItem.CatalogItem): isAward = item.isAward() if not base.cr.isPaid() and not (isinstance(item, InviteInfoBase) or isAward): TeaserPanel(pageName='clothing') else: self.acceptingIndex = self.itemIndex self.acceptButton['state'] = DGG.DISABLED self.__showCurrentItem() item = self.items[self.itemIndex] item.acceptItem(self.mailbox, self.acceptingIndex, self.__acceptItemCallback) return def __handleDiscard(self, buttonValue = None): if self.acceptingIndex != None: return elif buttonValue == -1: if self.dialogBox: self.dialogBox.cleanup() self.dialogBox = None self.__showCurrentItem() else: self.acceptingIndex = self.itemIndex self.acceptButton['state'] = DGG.DISABLED self.__showCurrentItem() item = self.items[self.itemIndex] item.discardItem(self.mailbox, self.acceptingIndex, self.__discardItemCallback) return def __discardItemCallback(self, retcode, item, index): if not hasattr(self, 'frame'): return if self.dialogBox: self.dialogBox.cleanup() self.dialogBox = None self.acceptingIndex = None self.__updateItems() if isinstance(item, InviteInfoBase): callback = self.__incIndexRemoveDialog self.dialogBox = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=item.getDiscardItemErrorText(retcode), text_wordwrap=15, command=callback) self.dialogBox.show() return def __makeDiscardInterface(self): if self.itemIndex >= 0 and self.itemIndex < len(self.items): item = self.items[self.itemIndex] if isinstance(item, InviteInfoBase): itemText = TTLocalizer.MailBoxRejectVerify % self.getItemName(item) yesText = TTLocalizer.MailboxReject else: itemText = TTLocalizer.MailBoxDiscardVerify % self.getItemName(item) yesText = TTLocalizer.MailboxDiscard self.dialogBox = TTDialog.TTDialog(style=TTDialog.TwoChoiceCustom, text=itemText, text_wordwrap=15, command=self.__handleDiscard, buttonText=[yesText, TTLocalizer.MailboxLeave]) self.dialogBox.show() def __acceptItemCallback(self, retcode, item, index): needtoUpdate = 0 if self.acceptingIndex == None: needtoUpdate = 1 if not hasattr(self, 'frame'): return if retcode == ToontownGlobals.P_UserCancelled: print 'mailbox screen user canceled' self.acceptingIndex = None self.__updateItems() return if self.acceptingIndex != index: self.notify.warning('Got unexpected callback for index %s, expected %s.' % (index, self.acceptingIndex)) return self.acceptingIndex = None if retcode < 0: self.notify.info('Could not take item %s: retcode %s' % (item, retcode)) if retcode == ToontownGlobals.P_NoTrunk: self.dialogBox = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=TTLocalizer.CatalogAcceptNoTrunk, text_wordwrap=15, command=self.__acceptError) else: self.dialogBox = TTDialog.TTDialog(style=TTDialog.TwoChoiceCustom, text=item.getAcceptItemErrorText(retcode), text_wordwrap=15, command=self.__handleDiscard, buttonText=[TTLocalizer.MailboxDiscard, TTLocalizer.MailboxLeave]) self.dialogBox.show() elif hasattr(item, 'storedInAttic') and item.storedInAttic(): self.numAtticAccepted += 1 self.itemIndex += 1 if needtoUpdate == 1: self.__updateItems() else: if isinstance(item, InviteInfoBase): self.__updateItems() callback = self.__incIndexRemoveDialog self.dialogBox = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=item.getAcceptItemErrorText(retcode), text_wordwrap=15, command=callback) self.dialogBox.show() return def __acceptError(self, buttonValue = None): self.dialogBox.cleanup() self.dialogBox = None self.__showCurrentItem() return def __incIndexRemoveDialog(self, junk = 0): self.__incIndex() self.dialogBox.cleanup() self.dialogBox = None self.__showCurrentItem() return def __incIndex(self, junk = 0): self.itemIndex += 1 def __acceptOk(self, index, buttonValue = None): self.acceptingIndex = None if self.dialogBox: self.dialogBox.cleanup() self.dialogBox = None self.items = self.getItems() if self.itemIndex > index or self.itemIndex >= len(self.items): print 'adjusting item index -1' self.itemIndex -= 1 if len(self.items) < 1: self.__handleExit() return self.itemCountLabel['text'] = (self.__getNumberOfItemsText(),) self.__showCurrentItem() return def __refreshItems(self): self.acceptingIndex = None self.__updateItems() return def __updateItems(self): if self.dialogBox: self.dialogBox.cleanup() self.dialogBox = None self.items = self.getItems() if self.itemIndex >= len(self.items): print 'adjusting item index -1' self.itemIndex = len(self.items) - 1 if len(self.items) == 0: print 'exiting due to lack of items' self.__handleExit() return self.itemCountLabel['text'] = (self.__getNumberOfItemsText(),) self.__showCurrentItem() return def __getNumberOfItemsText(self): if len(self.items) == 1: return TTLocalizer.MailboxOneItem else: return TTLocalizer.MailboxNumberOfItems % len(self.items) def __clearCurrentItem(self): if self.itemPanel: self.itemPanel.destroy() self.itemPanel = None if self.ival: self.ival.finish() self.ival = None if not self.gettingText.isEmpty(): self.gettingText.hide() if not self.itemText.isEmpty(): self.itemText.hide() if not self.giftTagPanel.isEmpty(): self.giftTagPanel.hide() if not self.acceptButton.isEmpty(): self.acceptButton['state'] = DGG.DISABLED if self.currentItem: if isinstance(self.currentItem, CatalogItem.CatalogItem): self.currentItem.cleanupPicture() self.currentItem = None return def checkFamily(self, doId): for familyMember in base.cr.avList: if familyMember.id == doId: return familyMember return None def __showCurrentItem(self): self.__clearCurrentItem() if len(self.items) < 1: self.__handleExit() return self.partyInviteVisual.stash() if self.itemIndex + 1 > len(self.items): self.itemIndex = len(self.items) - 1 item = self.items[self.itemIndex] if self.itemIndex == self.acceptingIndex: self.gettingText['text'] = TTLocalizer.MailboxGettingItem % self.getItemName(item) self.gettingText.show() return self.itemText['text'] = self.getItemName(item) self.currentItem = item if isinstance(item, CatalogItem.CatalogItem): self.acceptButton['text'] = ('', TTLocalizer.MailboxAcceptButton, TTLocalizer.MailboxAcceptButton, '') self.DiscardButton['text'] = ('', TTLocalizer.MailBoxDiscard, TTLocalizer.MailBoxDiscard, '') if item.isAward(): self.giftTagPanel['text'] = TTLocalizer.SpecialEventMailboxStrings[item.specialEventId] elif item.giftTag != None: nameOfSender = self.getSenderName(item.giftTag) if item.giftCode == ToontownGlobals.GIFT_RAT: self.giftTagPanel['text'] = TTLocalizer.CatalogAcceptRATBeans elif item.giftCode == ToontownGlobals.GIFT_partyrefund: self.giftTagPanel['text'] = TTLocalizer.CatalogAcceptPartyRefund else: self.giftTagPanel['text'] = TTLocalizer.MailboxGiftTag % nameOfSender else: self.giftTagPanel['text'] = '' self.itemPanel, self.ival = item.getPicture(base.localAvatar) elif isinstance(item, SimpleMailBase): self.acceptButton['text'] = ('', TTLocalizer.MailboxAcceptButton, TTLocalizer.MailboxAcceptButton, '') self.DiscardButton['text'] = ('', TTLocalizer.MailBoxDiscard, TTLocalizer.MailBoxDiscard, '') senderId = item.senderId nameOfSender = self.getSenderName(senderId) self.giftTagPanel['text'] = TTLocalizer.MailFromTag % nameOfSender self.itemText['text'] = item.body elif isinstance(item, InviteInfoBase): self.acceptButton['text'] = ('', TTLocalizer.MailboxAcceptInvite, TTLocalizer.MailboxAcceptInvite, '') self.DiscardButton['text'] = ('', TTLocalizer.MailBoxRejectInvite, TTLocalizer.MailBoxRejectInvite, '') partyInfo = None for party in self.avatar.partiesInvitedTo: if party.partyId == item.partyId: partyInfo = party break else: MailboxScreen.notify.error('Unable to find party with id %d to match invitation %s' % (item.partyId, item)) if self.mailbox: if item.status == PartyGlobals.InviteStatus.NotRead: self.mailbox.sendInviteReadButNotReplied(item.inviteKey) senderId = partyInfo.hostId nameOfSender = self.getSenderName(senderId) self.giftTagPanel['text'] = '' self.itemText['text'] = '' self.partyInviteVisual.updateInvitation(nameOfSender, partyInfo) self.partyInviteVisual.unstash() self.itemPanel = None self.ival = None else: self.acceptButton['text'] = ('', TTLocalizer.MailboxAcceptButton, TTLocalizer.MailboxAcceptButton, '') self.DiscardButton['text'] = ('', TTLocalizer.MailBoxDiscard, TTLocalizer.MailBoxDiscard, '') self.giftTagPanel['text'] = ' ' self.itemPanel = None self.ival = None self.itemText.show() self.giftTagPanel.show() if self.itemPanel and item.getTypeName() != TTLocalizer.ChatTypeName: self.itemPanel.reparentTo(self.itemBoard, -1) self.itemPanel.setPos(0, 0, 0.4) self.itemPanel.setScale(0.21) self.itemText['text_wordwrap'] = 16 self.itemText.setPos(0.0, 0.0, 0.075) elif isinstance(item, CatalogItem.CatalogItem) and item.getTypeName() == TTLocalizer.ChatTypeName: self.itemPanel.reparentTo(self.itemBoard, -1) self.itemPanel.setPos(0, 0, 0.35) self.itemPanel.setScale(0.21) self.itemText['text_wordwrap'] = 10 self.itemText.setPos(0, 0, 0.3) else: self.itemText.setPos(0, 0, 0.3) if self.ival: self.ival.loop() if self.acceptingIndex == None: self.acceptButton['state'] = DGG.NORMAL if self.itemIndex > 0: self.prevButton['state'] = DGG.NORMAL else: self.prevButton['state'] = DGG.DISABLED if self.itemIndex + 1 < len(self.items): self.nextButton['state'] = DGG.NORMAL else: self.nextButton['state'] = DGG.DISABLED return def __nextItem(self): messenger.send('wakeup') if self.itemIndex + 1 < len(self.items): self.itemIndex += 1 self.__showCurrentItem() def __prevItem(self): messenger.send('wakeup') if self.itemIndex > 0: self.itemIndex -= 1 self.__showCurrentItem() def getItemName(self, item): if isinstance(item, CatalogItem.CatalogItem): return item.getName() elif isinstance(item, str): return TTLocalizer.MailSimpleMail elif isinstance(item, InviteInfoBase): return TTLocalizer.InviteInvitation else: return '' def getItems(self): result = [] result = self.avatar.awardMailboxContents[:] result += self.avatar.mailboxContents[:] if self.avatar.mail: result += self.avatar.mail mailboxInvites = self.avatar.getInvitesToShowInMailbox() if mailboxInvites: result += mailboxInvites return result def getNumberOfAwardItems(self): result = 0 for item in self.items: if isinstance(item, CatalogItem.CatalogItem) and item.specialEventId > 0: result += 1 else: break return result def getSenderName(self, avId): sender = base.cr.identifyFriend(avId) nameOfSender = '' if sender: nameOfSender = sender.getName() else: sender = self.checkFamily(avId) if sender: nameOfSender = sender.name elif hasattr(base.cr, 'playerFriendsManager'): sender = base.cr.playerFriendsManager.getAvHandleFromId(avId) if sender: nameOfSender = sender.getName() if not sender: nameOfSender = TTLocalizer.MailboxGiftTagAnonymous if hasattr(base.cr, 'playerFriendsManager'): base.cr.playerFriendsManager.requestAvatarInfo(avId) self.accept('friendsListChanged', self.__showCurrentItem) return nameOfSender
class MailboxScreen(DirectObject.DirectObject): """ This class allows the user to accept items one at a time out of his or her mailbox. """ notify = directNotify.newCategory("MailboxScreen") def __init__(self, mailbox, avatar, doneEvent=None): assert (MailboxScreen.notify.debug("__init__")) # This is the DistributedMailbox that is handling our transactions. self.mailbox = mailbox # This is the avatar we're accepting for. self.avatar = avatar self.items = self.getItems() # Send this when we are done so whoever made us can get a callback self.doneEvent = doneEvent self.itemIndex = 0 self.itemPanel = None self.itemPicture = None self.ival = None self.itemText = None self.giftTag = None self.acceptingIndex = None self.numAtticAccepted = 0 self.dialogBox = None self.load() self.hide() def show(self): assert (MailboxScreen.notify.debug("show")) self.frame.show() self.__showCurrentItem() def hide(self): assert (MailboxScreen.notify.debug("hide")) self.ignore("friendsListChanged") if hasattr(self, 'frame'): self.frame.hide() else: self.notify.warning( "hide called, but frame is deleted, self.frame deleted in:") if hasattr(self, "frameDelStackTrace"): print self.frameDelStackTrace self.notify.warning("current stackTrace =") print StackTrace() self.notify.warning("crash averted, but root cause unknown") # this will force a crash, hopefully we get the log with it #self.frame.hide() def load(self): assert (MailboxScreen.notify.debug("load")) self.accept("setMailboxContents-%s" % (base.localAvatar.doId), self.__refreshItems) self.accept("setAwardMailboxContents-%s" % (base.localAvatar.doId), self.__refreshItems) # load the buttons model = loader.loadModel('phase_5.5/models/gui/package_delivery_panel') background = model.find('**/bg') itemBoard = model.find('**/item_board') self.frame = DirectFrame(scale=1.1, relief=DGG.FLAT, frameSize=(-0.5, 0.5, -0.45, -0.05), frameColor=(0.737, 0.573, 0.345, 1.000)) self.background = DirectFrame( self.frame, image=background, image_scale=0.05, relief=None, pos=(0, 1, 0), ) self.itemBoard = DirectFrame( parent=self.frame, image=itemBoard, image_scale=0.05, image_color=(.922, 0.922, 0.753, 1), relief=None, pos=(0, 1, 0), ) # shows how many items you have to browse through self.itemCountLabel = DirectLabel( parent=self.frame, relief=None, text=self.__getNumberOfItemsText(), text_wordwrap=16, pos=(0.0, 0.0, 0.7), scale=0.09, ) exitUp = model.find('**/bu_return_rollover') exitDown = model.find('**/bu_return_rollover') exitRollover = model.find('**/bu_return_rollover') exitUp.setP(-90) exitDown.setP(-90) exitRollover.setP(-90) # click this button to discard/decline an item in your mailbox self.DiscardButton = DirectButton( parent=self.frame, relief=None, image=(exitUp, exitDown, exitRollover, exitUp), pos=(-0.01, 1.0, -0.36), scale=0.048, text=("", TTLocalizer.MailBoxDiscard, TTLocalizer.MailBoxDiscard, ""), text_scale=1.0, text_pos=(0, -0.08), textMayChange=1, command=self.__makeDiscardInterface, ) gui2 = loader.loadModel("phase_3/models/gui/quit_button") # click this button to stop interacting with the mailbox self.quitButton = DirectButton( parent=self.frame, relief=None, image=( gui2.find("**/QuitBtn_UP"), gui2.find("**/QuitBtn_DN"), gui2.find("**/QuitBtn_RLVR"), ), pos=(0.5, 1.0, -0.42), scale=0.90, text=TTLocalizer.MailboxExitButton, text_font=ToontownGlobals.getSignFont(), text0_fg=(0.152, 0.750, 0.258, 1), text1_fg=(0.152, 0.750, 0.258, 1), text2_fg=(0.977, 0.816, 0.133, 1), text_scale=0.045, text_pos=(0, -0.01), command=self.__handleExit, ) self.gettingText = DirectLabel( parent=self.frame, relief=None, text='', text_wordwrap=10, pos=(0.0, 0.0, 0.32), scale=0.09, ) self.gettingText.hide() # label describing who the item is from self.giftTagPanel = DirectLabel( parent=self.frame, relief=None, text='Gift TAG!!', text_wordwrap=16, pos=(0.0, 0.0, 0.01), scale=0.06, ) self.giftTagPanel.hide() # description of the item. For invites, this might be the body of the # invite. self.itemText = DirectLabel( parent=self.frame, relief=None, text='', text_wordwrap=16, pos=(0.0, 0.0, -0.022), scale=0.07, ) self.itemText.hide() acceptUp = model.find('**/bu_check_up') acceptDown = model.find('**/bu_check_down') acceptRollover = model.find('**/bu_check_rollover') acceptUp.setP(-90) acceptDown.setP(-90) acceptRollover.setP(-90) # click this button to accept an item self.acceptButton = DirectButton( parent=self.frame, relief=None, image=(acceptUp, acceptDown, acceptRollover, acceptUp), image3_color=(0.8, 0.8, 0.8, 0.6), pos=(-0.01, 1.0, -0.16), scale=0.048, text=("", TTLocalizer.MailboxAcceptButton, TTLocalizer.MailboxAcceptButton, ""), text_scale=1.0, text_pos=(0, -0.09), textMayChange=1, command=self.__handleAccept, state=DGG.DISABLED, ) nextUp = model.find("**/bu_next_up") nextUp.setP(-90) nextDown = model.find("**/bu_next_down") nextDown.setP(-90) nextRollover = model.find("**/bu_next_rollover") nextRollover.setP(-90) # click this button to go to the next item in my mailbox self.nextButton = DirectButton( parent=self.frame, relief=None, image=(nextUp, nextDown, nextRollover, nextUp), image3_color=(0.8, 0.8, 0.8, 0.6), pos=(0.31, 1.0, -0.26), scale=0.05, text=("", TTLocalizer.MailboxItemNext, TTLocalizer.MailboxItemNext, ""), text_scale=1, text_pos=(-0.2, 0.3), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), textMayChange=0, command=self.__nextItem, state=DGG.DISABLED, ) prevUp = model.find("**/bu_previous_up") prevUp.setP(-90) prevDown = model.find("**/bu_previous_down") prevDown.setP(-90) prevRollover = model.find("**/bu_previous_rollover") prevRollover.setP(-90) # click this button to go to the previous item in my mailbox self.prevButton = DirectButton( parent=self.frame, relief=None, image=(prevUp, prevDown, prevRollover, prevUp), pos=(-0.35, 1, -0.26), scale=0.05, image3_color=(0.8, 0.8, 0.8, 0.6), text=("", TTLocalizer.MailboxItemPrev, TTLocalizer.MailboxItemPrev, ""), text_scale=1, text_pos=(0, 0.3), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), textMayChange=0, command=self.__prevItem, state=DGG.DISABLED, ) self.currentItem = None self.partyInviteVisual = InviteVisual(self.frame) self.partyInviteVisual.setScale(0.73) self.partyInviteVisual.setPos(0.0, 0.0, 0.48) self.partyInviteVisual.stash() def unload(self): assert (MailboxScreen.notify.debug("unload")) self.__clearCurrentItem() if hasattr(self, "frame"): self.frame.destroy() del self.frame self.frameDelStackTrace = StackTrace() else: self.notify.warning("unload, no self.frame") if hasattr(self, "mailbox"): del self.mailbox else: self.notify.warning("unload, no self.mailbox") if self.dialogBox: self.dialogBox.cleanup() self.dialogBox = None # Clean up all the items also. for item in self.items: if isinstance(item, CatalogItem.CatalogItem): item.acceptItemCleanup() self.ignoreAll() # button handlers def justExit(self): assert (MailboxScreen.notify.debug("justExit")) #self.__handleExit() self.__acceptExit() def __handleExit(self): assert (MailboxScreen.notify.debug("__handleExit")) if self.numAtticAccepted == 0: self.__acceptExit() elif self.numAtticAccepted == 1: self.dialogBox = TTDialog.TTDialog( style=TTDialog.Acknowledge, text=TTLocalizer.CatalogAcceptInAttic, text_wordwrap=15, command=self.__acceptExit, ) self.dialogBox.show() else: self.dialogBox = TTDialog.TTDialog( style=TTDialog.Acknowledge, text=TTLocalizer.CatalogAcceptInAtticP, text_wordwrap=15, command=self.__acceptExit, ) self.dialogBox.show() def __acceptExit(self, buttonValue=None): assert (MailboxScreen.notify.debug("__acceptExit")) if hasattr(self, 'frame'): self.hide() self.unload() messenger.send(self.doneEvent) def __handleAccept(self): assert (MailboxScreen.notify.debug("__handleAccept")) if self.acceptingIndex != None: # Ignore an extraneous click. return item = self.items[self.itemIndex] isAward = False if isinstance(item, CatalogItem.CatalogItem): isAward = item.isAward() if not base.cr.isPaid() and not (isinstance(item, InviteInfoBase) or isAward): # make sure free players can accept party invites or awards TeaserPanel(pageName='clothing') else: self.acceptingIndex = self.itemIndex self.acceptButton['state'] = DGG.DISABLED self.__showCurrentItem() item = self.items[self.itemIndex] item.acceptItem(self.mailbox, self.acceptingIndex, self.__acceptItemCallback) def __handleDiscard(self, buttonValue=None): assert (MailboxScreen.notify.debug("__handleDiscard")) #print ("Discard Button Value:%s " % (buttonValue)) if self.acceptingIndex != None: # Ignore an extraneous click. return elif buttonValue == -1: if self.dialogBox: self.dialogBox.cleanup() self.dialogBox = None self.__showCurrentItem() else: self.acceptingIndex = self.itemIndex self.acceptButton['state'] = DGG.DISABLED self.__showCurrentItem() item = self.items[self.itemIndex] item.discardItem(self.mailbox, self.acceptingIndex, self.__discardItemCallback) def __discardItemCallback(self, retcode, item, index): assert (MailboxScreen.notify.debug("__discardItemCallback")) if not hasattr(self, "frame"): # The gui might have been closed down already by an # impatient user. If so, we quietly ignore the callback. return if self.dialogBox: self.dialogBox.cleanup() self.dialogBox = None self.acceptingIndex = None self.__updateItems() if isinstance(item, InviteInfoBase): callback = self.__incIndexRemoveDialog self.dialogBox = TTDialog.TTDialog( style=TTDialog.Acknowledge, text=item.getDiscardItemErrorText(retcode), text_wordwrap=15, command=callback, ) self.dialogBox.show() #self.__acceptOk(index) def __makeDiscardInterface(self): assert (MailboxScreen.notify.debug("__makeDiscardInterface")) if self.itemIndex >= 0 and self.itemIndex < len( self.items ): #check to see if index is within range, should help with button mashing item = self.items[self.itemIndex] if isinstance(item, InviteInfoBase): itemText = (TTLocalizer.MailBoxRejectVerify % (self.getItemName(item))) yesText = TTLocalizer.MailboxReject else: itemText = (TTLocalizer.MailBoxDiscardVerify % (self.getItemName(item))) yesText = TTLocalizer.MailboxDiscard #self.notify.info("Could not take item %s: retcode %s" % (item, retcode)) self.dialogBox = TTDialog.TTDialog( style=TTDialog.TwoChoiceCustom, #TwoChoice YesNo text= itemText, #what happens when you try to take chat from the mailbox text_wordwrap=15, command=self.__handleDiscard, buttonText=[yesText, TTLocalizer.MailboxLeave], ) self.dialogBox.show() def __acceptItemCallback(self, retcode, item, index): assert (MailboxScreen.notify.debug("__acceptItemCallback")) needtoUpdate = 0 if self.acceptingIndex == None: needtoUpdate = 1 #if the setMailboxContents call won the race back here then #we need to update our current item list if not hasattr(self, "frame"): # The gui might have been closed down already by an # impatient user. If so, we quietly ignore the callback. return if retcode == ToontownGlobals.P_UserCancelled: print("mailbox screen user canceled") #user canceled probably for a chatitem self.acceptingIndex = None self.__updateItems() #self.__acceptOk(index+1) return if self.acceptingIndex != index: self.notify.warning( "Got unexpected callback for index %s, expected %s." % (index, self.acceptingIndex)) return self.acceptingIndex = None if retcode < 0: # There was some error with the accept. Pop up an # appropriate dialog. self.notify.info("Could not take item %s: retcode %s" % (item, retcode)) self.dialogBox = TTDialog.TTDialog( style=TTDialog.TwoChoiceCustom, #TwoChoice YesNo text=item.getAcceptItemErrorText( retcode ), #what happens when you try to take chat from the mailbox text_wordwrap=15, command=self.__handleDiscard, buttonText=[ TTLocalizer.MailboxDiscard, TTLocalizer.MailboxLeave ]) """ #buttonText = [TTLocalizer.MailboxOverflowButtonDicard, #TTLocalizer.MailboxOverflowButtonLeave] """ #import pdb; pdb.set_trace() self.dialogBox.show() else: # The item was accepted successfully. if hasattr(item, 'storedInAttic') and item.storedInAttic(): # It's an attic item; collect these messages to # display just one dialog box at the end. self.numAtticAccepted += 1 self.itemIndex += 1 #self.__acceptOk(index) if needtoUpdate == 1: self.__updateItems() else: # It's some other kind of item; display the accept # dialog immediately. #callback = PythonUtil.Functor(self.__acceptOk, index) # TODO force it to just discard the item when appropriate # e.g. invites to cancelled parties if isinstance(item, InviteInfoBase): self.__updateItems() callback = self.__incIndexRemoveDialog # tell player that the party's host got their response self.dialogBox = TTDialog.TTDialog( style=TTDialog.Acknowledge, text=item.getAcceptItemErrorText(retcode), text_wordwrap=15, command=callback, ) self.dialogBox.show() def __acceptError(self, buttonValue=None): assert (MailboxScreen.notify.debug("__acceptError")) self.dialogBox.cleanup() self.dialogBox = None self.__showCurrentItem() def __incIndexRemoveDialog(self, junk=0): assert (MailboxScreen.notify.debug("__incIndexRemoveDialog")) self.__incIndex() self.dialogBox.cleanup() self.dialogBox = None self.__showCurrentItem() def __incIndex(self, junk=0): assert (MailboxScreen.notify.debug("__incIndex")) self.itemIndex += 1 def __acceptOk(self, index, buttonValue=None): assert (MailboxScreen.notify.debug("__acceptOk")) self.acceptingIndex = None if self.dialogBox: self.dialogBox.cleanup() self.dialogBox = None # We have a new set of items now. self.items = self.getItems() if self.itemIndex > index or self.itemIndex >= len(self.items): print("adjusting item index -1") self.itemIndex -= 1 if len(self.items) < 1: #print("exiting due to lack of items") # No more items in the mailbox. self.__handleExit() return # Show the next item in the mailbox. self.itemCountLabel['text'] = self.__getNumberOfItemsText(), self.__showCurrentItem() def __refreshItems(self): assert (MailboxScreen.notify.debug("__refreshItems")) self.acceptingIndex = None self.__updateItems() def __updateItems(self): assert (MailboxScreen.notify.debug("__updateItems")) if self.dialogBox: self.dialogBox.cleanup() self.dialogBox = None # We have a new set of items now. self.items = self.getItems() if self.itemIndex >= len(self.items): print("adjusting item index -1") self.itemIndex = len(self.items) - 1 if len(self.items) == 0: print("exiting due to lack of items") # No more items in the mailbox. self.__handleExit() return # Show the current item in the mailbox. self.itemCountLabel['text'] = self.__getNumberOfItemsText(), self.__showCurrentItem() def __getNumberOfItemsText(self): assert (MailboxScreen.notify.debug("__getNumberOfItemsText")) # Returns the string displayed across the top of the panel: # how many items remain in the mailbox. if len(self.items) == 1: return TTLocalizer.MailboxOneItem else: return TTLocalizer.MailboxNumberOfItems % (len(self.items)) def __clearCurrentItem(self): assert (MailboxScreen.notify.debug("__clearCurrentItem")) if self.itemPanel: self.itemPanel.destroy() self.itemPanel = None if self.ival: self.ival.finish() self.ival = None if not self.gettingText.isEmpty(): self.gettingText.hide() if not self.itemText.isEmpty(): self.itemText.hide() if not self.giftTagPanel.isEmpty(): self.giftTagPanel.hide() if not self.acceptButton.isEmpty(): self.acceptButton['state'] = DGG.DISABLED if (self.currentItem): if isinstance(self.currentItem, CatalogItem.CatalogItem): self.currentItem.cleanupPicture() self.currentItem = None def checkFamily(self, doId): assert (MailboxScreen.notify.debug("checkFamily")) for familyMember in base.cr.avList: #print ("Family %s %s" % (familyMember.name, familyMember.id)) if familyMember.id == doId: #print("found it") #import pdb; pdb.set_trace() return familyMember return None def __showCurrentItem(self): assert (MailboxScreen.notify.debug("__showCurrentItem")) self.__clearCurrentItem() if len(self.items) < 1: # No more items in the mailbox. self.__handleExit() return self.partyInviteVisual.stash() if (self.itemIndex + 1) > len(self.items): self.itemIndex = len(self.items) - 1 item = self.items[self.itemIndex] if self.itemIndex == self.acceptingIndex: # We are currently waiting on the AI to accept this item. self.gettingText['text'] = TTLocalizer.MailboxGettingItem % ( self.getItemName(item)) self.gettingText.show() return # This item is available to be accepted. self.itemText['text'] = self.getItemName(item) assert (self.itemPanel == None and self.ival == None) self.currentItem = item # giftTag is the senders do Id # giftCode is the type of tag to use (added after giftTag or I would have named them differently) if isinstance(item, CatalogItem.CatalogItem): self.acceptButton['text'] = ("", TTLocalizer.MailboxAcceptButton, TTLocalizer.MailboxAcceptButton, "") self.DiscardButton['text'] = ("", TTLocalizer.MailBoxDiscard, TTLocalizer.MailBoxDiscard, "") if item.isAward(): self.giftTagPanel[ 'text'] = TTLocalizer.SpecialEventMailboxStrings[ item.specialEventId] elif item.giftTag != None: # if it's a gift add the tag nameOfSender = self.getSenderName(item.giftTag) if item.giftCode == ToontownGlobals.GIFT_RAT: self.giftTagPanel[ 'text'] = TTLocalizer.CatalogAcceptRATBeans elif item.giftCode == ToontownGlobals.GIFT_partyrefund: self.giftTagPanel[ 'text'] = TTLocalizer.CatalogAcceptPartyRefund else: self.giftTagPanel['text'] = (TTLocalizer.MailboxGiftTag % (nameOfSender)) else: self.giftTagPanel['text'] = "" self.itemPanel, self.ival = item.getPicture(base.localAvatar) elif isinstance(item, SimpleMailBase): self.acceptButton['text'] = ("", TTLocalizer.MailboxAcceptButton, TTLocalizer.MailboxAcceptButton, "") self.DiscardButton['text'] = ("", TTLocalizer.MailBoxDiscard, TTLocalizer.MailBoxDiscard, "") senderId = item.senderId nameOfSender = self.getSenderName(senderId) self.giftTagPanel['text'] = (TTLocalizer.MailFromTag % (nameOfSender)) self.itemText['text'] = item.body elif isinstance(item, InviteInfoBase): self.acceptButton['text'] = ("", TTLocalizer.MailboxAcceptInvite, TTLocalizer.MailboxAcceptInvite, "") self.DiscardButton['text'] = ("", TTLocalizer.MailBoxRejectInvite, TTLocalizer.MailBoxRejectInvite, "") partyInfo = None for party in self.avatar.partiesInvitedTo: if party.partyId == item.partyId: partyInfo = party break else: # could not find party info MailboxScreen.notify.error( "Unable to find party with id %d to match invitation %s" % (item.partyId, item)) if self.mailbox: if item.status == PartyGlobals.InviteStatus.NotRead: self.mailbox.sendInviteReadButNotReplied(item.inviteKey) senderId = partyInfo.hostId nameOfSender = self.getSenderName(senderId) self.giftTagPanel['text'] = "" self.itemText['text'] = "" self.partyInviteVisual.updateInvitation(nameOfSender, partyInfo) self.partyInviteVisual.unstash() self.itemPanel = None self.ival = None else: self.acceptButton['text'] = ("", TTLocalizer.MailboxAcceptButton, TTLocalizer.MailboxAcceptButton, "") self.DiscardButton['text'] = ("", TTLocalizer.MailBoxDiscard, TTLocalizer.MailBoxDiscard, "") self.giftTagPanel['text'] = " " self.itemPanel = None self.ival = None self.itemText.show() self.giftTagPanel.show() if self.itemPanel and (item.getTypeName() != TTLocalizer.ChatTypeName): # Ensure the item panel is behind any other text. self.itemPanel.reparentTo(self.itemBoard, -1) self.itemPanel.setPos(0, 0, 0.40) self.itemPanel.setScale(0.21) self.itemText['text_wordwrap'] = 16 self.itemText.setPos(0.0, 0.0, 0.075) elif isinstance(item, CatalogItem.CatalogItem) and \ (item.getTypeName() == TTLocalizer.ChatTypeName): # Ensure the item panel is behind any other text. self.itemPanel.reparentTo(self.itemBoard, -1) self.itemPanel.setPos(0, 0, 0.35) self.itemPanel.setScale(0.21) # Scooch the item text into the chat bubble self.itemText['text_wordwrap'] = 10 self.itemText.setPos(0, 0, 0.30) else: # There's no picture for this item. Scooch the item text # up to fill up the space. self.itemText.setPos(0, 0, 0.3) if self.ival: self.ival.loop() if self.acceptingIndex == None: self.acceptButton['state'] = DGG.NORMAL if self.itemIndex > 0: self.prevButton['state'] = DGG.NORMAL else: self.prevButton['state'] = DGG.DISABLED if self.itemIndex + 1 < len(self.items): self.nextButton['state'] = DGG.NORMAL else: self.nextButton['state'] = DGG.DISABLED def __nextItem(self): assert (MailboxScreen.notify.debug("__nextItem")) messenger.send('wakeup') if self.itemIndex + 1 < len(self.items): self.itemIndex += 1 self.__showCurrentItem() def __prevItem(self): assert (MailboxScreen.notify.debug("__prevItem")) messenger.send('wakeup') if self.itemIndex > 0: self.itemIndex -= 1 self.__showCurrentItem() def getItemName(self, item): """Return the name of the item.""" assert (MailboxScreen.notify.debug("getItemName")) if isinstance(item, CatalogItem.CatalogItem): return item.getName() elif isinstance(item, str): return TTLocalizer.MailSimpleMail elif isinstance(item, InviteInfoBase): return TTLocalizer.InviteInvitation else: return '' def getItems(self): """Return the mailbox items which can be of multiple types.""" assert (MailboxScreen.notify.debug("getItems")) result = [] result = self.avatar.awardMailboxContents[:] result += self.avatar.mailboxContents[:] if self.avatar.mail: result += self.avatar.mail mailboxInvites = self.avatar.getInvitesToShowInMailbox() if mailboxInvites: result += mailboxInvites return result def getNumberOfAwardItems(self): """Return the number of award items in self.items.""" # since award items go first, the index being sent to ai needs to be adjusted result = 0 for item in self.items: if isinstance(item, CatalogItem.CatalogItem) and item.specialEventId > 0: result += 1 else: break return result def getSenderName(self, avId): """Return the name of the toon that matches avId.""" assert (MailboxScreen.notify.debug("getSenderName")) sender = base.cr.identifyFriend(avId) nameOfSender = "" if sender: nameOfSender = sender.getName() else: sender = self.checkFamily(avId) # check family if sender: nameOfSender = sender.name # careful a family member returns a PotentialAvatar not a handle elif hasattr(base.cr, "playerFriendsManager"): # check transient toons sender = base.cr.playerFriendsManager.getAvHandleFromId(avId) if sender: nameOfSender = sender.getName() if GMUtils.testGMIdentity(nameOfSender): nameOfSender = GMUtils.handleGMName(nameOfSender) if not sender: nameOfSender = TTLocalizer.MailboxGiftTagAnonymous if hasattr(base.cr, "playerFriendsManager"): # request the info base.cr.playerFriendsManager.requestAvatarInfo(avId) self.accept('friendsListChanged', self.__showCurrentItem ) # accepts this as long as it stays up return nameOfSender