from pandac.PandaModules import TextNode, PlaneNode, Plane from direct.gui.DirectGui import DirectFrame, DirectLabel, DirectButton, DirectScrolledList, DGG from direct.gui import DirectGuiGlobals from toontown.ai import HolidayGlobals from toontown.toonbase import TTLocalizer, ToontownGlobals from toontown.parties.PartyInfo import PartyInfo from toontown.parties import PartyGlobals import datetime def myStrftime(myTime): result = '' result = myTime.strftime('%I') if result[0] == '0': result = result[1:] result += myTime.strftime(':%M %p') return result class CalendarGuiDay(DirectFrame): ScrollListTextSize = 0.03 def __init__(self, parent, myDate, startDate, dayClickCallback = None, onlyFutureDaysClickable = False): self.origParent = parent self.startDate = startDate self.myDate = myDate self.dayClickCallback = dayClickCallback self.onlyFutureDaysClickable = onlyFutureDaysClickable DirectFrame.__init__(self, parent=parent) self.filter = ToontownGlobals.CalendarFilterShowAll self.load() self.createGuiObjects() self.update() def load(self): dayAsset = loader.loadModel('phase_4/models/parties/tt_m_gui_sbk_calendar_box') dayAsset.reparentTo(self) self.dayButtonLocator = self.find('**/loc_origin') self.numberLocator = self.find('**/loc_number') self.scrollLocator = self.find('**/loc_topLeftList') self.selectedLocator = self.find('**/loc_origin') self.todayBox = self.find('**/boxToday') self.todayBox.hide() self.selectedFrame = self.find('**/boxHover') self.selectedFrame.hide() self.defaultBox = self.find('**/boxBlank') self.scrollBottomRightLocator = self.find('**/loc_bottomRightList') self.scrollDownLocator = self.find('**/loc_scrollDown') self.scrollUpLocator = self.find('**/loc_scrollUp') def createGuiObjects(self): self.dayButton = DirectButton(parent=self.dayButtonLocator, image=self.selectedFrame, relief=None, command=self.__clickedOnDay, pressEffect=1, rolloverSound=None, clickSound=None) self.numberWidget = DirectLabel(parent=self.numberLocator, relief=None, text=str(self.myDate.day), text_scale=0.04, text_align=TextNode.ACenter, text_font=ToontownGlobals.getInterfaceFont(), text_fg=(110 / 255.0, 126 / 255.0, 255 / 255.0, 1)) self.listXorigin = 0 self.listFrameSizeX = self.scrollBottomRightLocator.getX() - self.scrollLocator.getX() self.scrollHeight = self.scrollLocator.getZ() - self.scrollBottomRightLocator.getZ() self.listZorigin = self.scrollBottomRightLocator.getZ() self.listFrameSizeZ = self.scrollLocator.getZ() - self.scrollBottomRightLocator.getZ() self.arrowButtonXScale = 1 self.arrowButtonZScale = 1 self.itemFrameXorigin = 0 self.itemFrameZorigin = 0 self.buttonXstart = self.itemFrameXorigin + 0.21 self.gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui') buttonOffSet = -0.01 incButtonPos = (0.0, 0, 0) decButtonPos = (0.0, 0, 0) itemFrameMinZ = self.listZorigin itemFrameMaxZ = self.listZorigin + self.listFrameSizeZ arrowUp = self.find('**/downScroll_up') arrowDown = self.find('**/downScroll_down') arrowHover = self.find('**/downScroll_hover') self.scrollList = DirectScrolledList(parent=self.scrollLocator, relief=None, pos=(0, 0, 0), incButton_image=(arrowUp, arrowDown, arrowHover, arrowUp), incButton_relief=None, incButton_scale=(self.arrowButtonXScale, 1, self.arrowButtonZScale), incButton_pos=incButtonPos, incButton_image3_color=(1, 1, 1, 0.2), decButton_image=(arrowUp, arrowDown, arrowHover, arrowUp), decButton_relief=None, decButton_scale=(self.arrowButtonXScale, 1, -self.arrowButtonZScale), decButton_pos=decButtonPos, decButton_image3_color=(1, 1, 1, 0.2), itemFrame_pos=(self.itemFrameXorigin, 0, -0.03), numItemsVisible=4, incButtonCallback=self.scrollButtonPressed, decButtonCallback=self.scrollButtonPressed) itemFrameParent = self.scrollList.itemFrame.getParent() self.scrollList.incButton.reparentTo(self.scrollDownLocator) self.scrollList.decButton.reparentTo(self.scrollUpLocator) arrowUp.removeNode() arrowDown.removeNode() arrowHover.removeNode() clipper = PlaneNode('clipper') clipper.setPlane(Plane((-1, 0, 0), (0.23, 0, 0))) clipNP = self.scrollList.component('itemFrame').attachNewNode(clipper) self.scrollList.component('itemFrame').setClipPlane(clipNP) def scrollButtonPressed(self): self.__clickedOnDay() def adjustForMonth(self): curServerDate = base.cr.toontownTimeManager.getCurServerDateTime() if self.onlyFutureDaysClickable: if self.myDate.year < curServerDate.year or self.myDate.year == curServerDate.year and self.myDate.month < curServerDate.month or self.myDate.year == curServerDate.year and self.myDate.month == curServerDate.month and self.myDate.day < curServerDate.day: self.numberWidget.setColorScale(0.5, 0.5, 0.5, 0.5) self.numberWidget['state'] = DirectGuiGlobals.DISABLED else: self.numberWidget.setColorScale(1, 1, 1, 1) if self.myDate.month != self.startDate.month: self.setColorScale(0.75, 0.75, 0.75, 1.0) if self.dayClickCallback is not None: self.numberWidget['state'] = DirectGuiGlobals.DISABLED else: self.setColorScale(1, 1, 1, 1) if self.myDate.date() == curServerDate.date(): self.defaultBox.hide() self.todayBox.show() else: self.defaultBox.show() self.todayBox.hide() def destroy(self): if self.dayClickCallback is not None: self.numberWidget.destroy() self.dayClickCallback = None try: for item in self.scrollList['items']: if hasattr(item, 'description') and item.description and hasattr(item.description, 'destroy'): item.unbind(DGG.ENTER) item.unbind(DGG.EXIT) item.description.destroy() except e: pass self.scrollList.removeAndDestroyAllItems() self.scrollList.destroy() self.dayButton.destroy() DirectFrame.destroy(self) def updateArrowButtons(self): numItems = 0 try: numItems = len(self.scrollList['items']) except e: numItems = 0 if numItems <= self.scrollList.numItemsVisible: self.scrollList.incButton.hide() self.scrollList.decButton.hide() else: self.scrollList.incButton.show() self.scrollList.decButton.show() def collectTimedEvents(self): if self.filter == ToontownGlobals.CalendarFilterShowAll or self.filter == ToontownGlobals.CalendarFilterShowOnlyParties: for party in localAvatar.partiesInvitedTo: if party.startTime.date() == self.myDate.date(): self.addPartyToScrollList(party) for party in localAvatar.hostedParties: if party.startTime.date() == self.myDate.date(): self.addPartyToScrollList(party) if self.filter == ToontownGlobals.CalendarFilterShowAll or self.filter == ToontownGlobals.CalendarFilterShowOnlyHolidays: for id, holiday in HolidayGlobals.Holidays.iteritems(): title, description = TTLocalizer.HolidayNamesInCalendar[id] if 'weekDay' in holiday: if self.myDate.weekday() == holiday['weekDay']: self.addTitleAndDescToScrollList(title, description) elif 'startMonth' in holiday or 'startDay' in holiday: startDate = HolidayGlobals.getStartDate(holiday, self.myDate) endDate = HolidayGlobals.getEndDate(holiday, self.myDate) if self.isDateMatch(self.myDate, startDate): if self.isDateMatch(startDate, endDate): description = '%s. %s' % (title, description) else: description = '%s. %s %s %s' % (title, description, TTLocalizer.CalendarEndsAt, endDate.strftime('%b %d')) self.addTitleAndDescToScrollList(title, description) elif self.isDateMatch(self.myDate, endDate): title = '%s %s' % (TTLocalizer.CalendarEndOf, title) description = '%s. %s %s' % (title, TTLocalizer.CalendarStartedOn, startDate.strftime('%b %d')) self.addTitleAndDescToScrollList(title, description) def isDateMatch(self, date1, date2): return date1.day == date2.day and date1.month == date2.month def addTitleAndDescToScrollList(self, title, desc): textSize = self.ScrollListTextSize descTextSize = 0.05 newItem = DirectButton(relief=None, text=title, text_scale=textSize, text_align=TextNode.ALeft, rolloverSound=None, clickSound=None, pressEffect=0, command=self.__clickedOnScrollItem) scrollItemHeight = newItem.getHeight() descUnderItemZAdjust = scrollItemHeight * descTextSize / textSize descUnderItemZAdjust = max(0.0534, descUnderItemZAdjust) descUnderItemZAdjust = -descUnderItemZAdjust descZAdjust = descUnderItemZAdjust newItem.description = DirectLabel(parent=newItem, pos=(0.115, 0, descZAdjust), text='', text_wordwrap=15, pad=(0.02, 0.02), text_scale=descTextSize, text_align=TextNode.ACenter, textMayChange=0) newItem.description.checkedHeight = False newItem.description.setBin('gui-popup', 0) newItem.description.hide() newItem.bind(DGG.ENTER, self.enteredTextItem, extraArgs=[newItem, desc, descUnderItemZAdjust]) newItem.bind(DGG.EXIT, self.exitedTextItem, extraArgs=[newItem]) self.scrollList.addItem(newItem) def exitedTextItem(self, newItem, mousepos): newItem.description.hide() def enteredTextItem(self, newItem, descText, descUnderItemZAdjust, mousePos): if not newItem.description.checkedHeight: newItem.description.checkedHeight = True newItem.description['text'] = descText bounds = newItem.description.getBounds() descHeight = newItem.description.getHeight() scrollItemHeight = newItem.getHeight() descOverItemZAdjust = descHeight - scrollItemHeight / 2.0 descZPos = self.getPos(aspect2d)[2] + descUnderItemZAdjust - descHeight if descZPos < -1.0: newItem.description.setZ(descOverItemZAdjust) descWidth = newItem.description.getWidth() brightFrame = loader.loadModel('phase_4/models/parties/tt_m_gui_sbk_calendar_popUp_bg') newItem.description['geom'] = brightFrame newItem.description['geom_scale'] = (descWidth, 1, descHeight) descGeomZ = (bounds[2] - bounds[3]) / 2.0 descGeomZ += bounds[3] newItem.description['geom_pos'] = (0, 0, descGeomZ) newItem.description.show() def addPartyToScrollList(self, party): textSize = self.ScrollListTextSize descTextSize = 0.05 partyTitle = myStrftime(party.startTime) partyTitle = partyTitle + ' ' + TTLocalizer.EventsPageCalendarTabParty textSize = self.ScrollListTextSize descTextSize = 0.05 newItem = DirectButton(relief=None, text=partyTitle, text_scale=textSize, text_align=TextNode.ALeft, rolloverSound=None, clickSound=None, pressEffect=0, command=self.__clickedOnScrollItem) scrollItemHeight = newItem.getHeight() descUnderItemZAdjust = scrollItemHeight * descTextSize / textSize descUnderItemZAdjust = max(0.0534, descUnderItemZAdjust) descUnderItemZAdjust = -descUnderItemZAdjust descZAdjust = descUnderItemZAdjust self.scrollList.addItem(newItem) newItem.description = MiniInviteVisual(newItem, party) newItem.description.setBin('gui-popup', 0) newItem.description.hide() newItem.bind(DGG.ENTER, self.enteredTextItem, extraArgs=[newItem, newItem.description, descUnderItemZAdjust]) newItem.bind(DGG.EXIT, self.exitedTextItem, extraArgs=[newItem]) def __clickedOnScrollItem(self): self.__clickedOnDay() def __clickedOnDay(self): acceptClick = True if self.onlyFutureDaysClickable: curServerDate = base.cr.toontownTimeManager.getCurServerDateTime() if self.myDate.date() < curServerDate.date(): acceptClick = False if not acceptClick: return if self.dayClickCallback: self.dayClickCallback(self) messenger.send('clickedOnDay', [self.myDate.date()]) def updateSelected(self, selected): multiplier = 1.1 if selected: self.selectedFrame.show() self.setScale(multiplier) self.setPos(-0.01, 0, 0.01) grandParent = self.origParent.getParent() self.origParent.reparentTo(grandParent) else: self.selectedFrame.hide() self.setScale(1.0) self.setPos(0, 0, 0) def changeDate(self, startDate, myDate): self.startDate = startDate self.myDate = myDate self.scrollList.removeAndDestroyAllItems() self.update() def update(self): self.numberWidget['text'] = str(self.myDate.day) self.adjustForMonth() self.collectTimedEvents() self.updateArrowButtons() def changeFilter(self, filter): oldFilter = self.filter self.filter = filter if self.filter != oldFilter: self.scrollList.removeAndDestroyAllItems() self.update() class MiniInviteVisual(DirectFrame): def __init__(self, parent, partyInfo): DirectFrame.__init__(self, parent, pos=(0.1, 0, -0.018)) self.checkedHeight = True self.partyInfo = partyInfo self.parent = parent self.inviteBackgrounds = loader.loadModel('phase_4/models/parties/partyStickerbook') backgrounds = ['calendar_popup_birthday', 'calendar_popup_fun', 'calendar_popup_cupcake', 'tt_t_gui_sbk_calendar_popup_racing', 'tt_t_gui_sbk_calendar_popup_valentine1', 'tt_t_gui_sbk_calendar_popup_victoryParty', 'tt_t_gui_sbk_calendar_popup_winter1'] self.background = DirectFrame(parent=self, relief=None, geom=self.inviteBackgrounds.find('**/%s' % backgrounds[self.partyInfo.inviteTheme]), scale=(0.7, 1.0, 0.23), pos=(0.0, 0.0, -0.1)) self.whosePartyLabel = DirectLabel(parent=self, relief=None, pos=(0.07, 0.0, -0.04), text=' ', text_scale=0.04, text_wordwrap=8, textMayChange=True) self.whenTextLabel = DirectLabel(parent=self, relief=None, text=' ', pos=(0.07, 0.0, -0.13), text_scale=0.04, textMayChange=True) self.partyStatusLabel = DirectLabel(parent=self, relief=None, text=' ', pos=(0.07, 0.0, -0.175), text_scale=0.04, textMayChange=True) def show(self): self.reparentTo(self.parent) self.setPos(0.1, 0, -0.018) newParent = self.parent.getParent().getParent() self.wrtReparentTo(newParent) if self.whosePartyLabel['text'] == ' ': host = base.cr.identifyAvatar(self.partyInfo.hostId) if host: name = host.getName() self.whosePartyLabel['text'] = name if self.whenTextLabel['text'] == ' ': time = myStrftime(self.partyInfo.startTime) self.whenTextLabel['text'] = time if self.partyStatusLabel['text'] == ' ': if self.partyInfo.status == PartyGlobals.PartyStatus.Cancelled: self.partyStatusLabel['text'] = TTLocalizer.CalendarPartyCancelled elif self.partyInfo.status == PartyGlobals.PartyStatus.Finished: self.partyStatusLabel['text'] = TTLocalizer.CalendarPartyFinished elif self.partyInfo.status == PartyGlobals.PartyStatus.Started: self.partyStatusLabel['text'] = TTLocalizer.CalendarPartyGo elif self.partyInfo.status == PartyGlobals.PartyStatus.NeverStarted: self.partyStatusLabel['text'] = TTLocalizer.CalendarPartyNeverStarted else: self.partyStatusLabel['text'] = TTLocalizer.CalendarPartyGetReady DirectFrame.show(self) def destroy(self): del self.checkedHeight del self.partyInfo del self.parent del self.background del self.whosePartyLabel del self.whenTextLabel del self.partyStatusLabel DirectFrame.destroy(self)