class Nametag: TEXT_WORD_WRAP = 8 TEXT_Y_OFFSET = -0.05 CHAT_TEXT_WORD_WRAP = 12 PANEL_X_PADDING = 0.2 PANEL_Z_PADDING = 0.2 CHAT_BALLOON_ALPHA = 1 def __init__(self): self.avatar = None self.panel = None self.icon = None self.chatBalloon = None self.chatButton = NametagGlobals.noButton self.chatReversed = False self.font = None self.chatFont = None self.chatType = NametagGlobals.CHAT self.chatBalloonType = NametagGlobals.CHAT_BALLOON self.nametagColor = NametagGlobals.NametagColors[ NametagGlobals.CCOtherPlayer] self.chatColor = NametagGlobals.ChatColors[ NametagGlobals.CCOtherPlayer] self.speedChatColor = self.chatColor[0][1] self.nametagHidden = False self.chatHidden = False self.thoughtHidden = False # Create our TextNodes: self.textNode = TextNode('text') self.textNode.setWordwrap(self.TEXT_WORD_WRAP) self.textNode.setAlign(TextNode.ACenter) self.chatTextNode = TextNode('chatText') self.chatTextNode.setWordwrap(self.CHAT_TEXT_WORD_WRAP) self.chatTextNode.setGlyphScale(ChatBalloon.TEXT_GLYPH_SCALE) self.chatTextNode.setGlyphShift(ChatBalloon.TEXT_GLYPH_SHIFT) # Add the tick task: self.tickTaskName = self.getUniqueName() + '-tick' self.tickTask = taskMgr.add(self.tick, self.tickTaskName, sort=45) def destroy(self): if self.tickTask is not None: taskMgr.remove(self.tickTask) self.tickTask = None self.chatTextNode = None self.textNode = None self.chatFont = None self.font = None self.chatButton = NametagGlobals.noButton if self.chatBalloon is not None: self.chatBalloon.removeNode() self.chatBalloon = None if self.icon is not None: self.icon.removeAllChildren() self.icon = None if self.panel is not None: self.panel.removeNode() self.panel = None self.avatar = None def getUniqueName(self): return 'Nametag-' + str(id(self)) def getChatBalloonModel(self): pass # Inheritors should override this method. def getChatBalloonWidth(self): pass # Inheritors should override this method. def getChatBalloonHeight(self): pass # Inheritors should override this method. def tick(self, task): return Task.done # Inheritors should override this method. def updateClickRegion(self): pass # Inheritors should override this method. def drawChatBalloon(self, model, modelWidth, modelHeight): pass # Inheritors should override this method. def drawNametag(self): pass # Inheritors should override this method. def setAvatar(self, avatar): self.avatar = avatar def getAvatar(self): return self.avatar def setIcon(self, icon): self.icon = icon def getIcon(self): return self.icon def setChatButton(self, chatButton): self.chatButton = chatButton def getChatButton(self): return self.chatButton def hasChatButton(self): if (self.chatBalloonType == NametagGlobals.CHAT_BALLOON) and self.chatHidden: return False if (self.chatBalloonType == NametagGlobals.THOUGHT_BALLOON) and self.thoughtHidden: return False return self.chatButton != NametagGlobals.noButton def setChatReversed(self, chatReversed): self.chatReversed = chatReversed def getChatReversed(self): return self.chatReversed def setFont(self, font): self.font = font if self.font is not None: self.textNode.setFont(self.font) self.update() def getFont(self): return self.font def setChatFont(self, chatFont): self.chatFont = chatFont if self.chatFont is not None: self.chatTextNode.setFont(self.chatFont) self.update() def getChatFont(self): return self.chatFont def setChatType(self, chatType): self.chatType = chatType def getChatType(self): return self.chatType def setChatBalloonType(self, chatBalloonType): self.chatBalloonType = chatBalloonType def getChatBalloonType(self): return self.chatBalloonType def setNametagColor(self, nametagColor): self.nametagColor = nametagColor def getNametagColor(self): return self.nametagColor def setChatColor(self, chatColor): self.chatColor = chatColor def getChatColor(self): return self.chatColor def setSpeedChatColor(self, speedChatColor): self.speedChatColor = speedChatColor def getSpeedChatColor(self): return self.speedChatColor def hideNametag(self): self.nametagHidden = True def showNametag(self): self.nametagHidden = False def hideChat(self): self.chatHidden = True def showChat(self): self.chatHidden = False def hideThought(self): self.thoughtHidden = True def showThought(self): self.thoughtHidden = False def applyClickState(self, clickState): if self.chatBalloon is not None: foreground, background = self.chatColor[clickState] if self.chatType == NametagGlobals.SPEEDCHAT: background = self.speedChatColor if background[3] > self.CHAT_BALLOON_ALPHA: background = VBase4(background[0], background[1], background[2], self.CHAT_BALLOON_ALPHA) self.chatBalloon.setForeground(foreground) self.chatBalloon.setBackground(background) self.chatBalloon.setButton(self.chatButton[clickState]) elif self.panel is not None: foreground, background = self.nametagColor[clickState] self.setForeground(foreground) self.setBackground(background) def setText(self, text): self.textNode.setText(text) def getText(self): return self.textNode.getText() def setChatText(self, chatText): self.chatTextNode.setText(chatText) def getChatText(self): return self.chatTextNode.getText() def setWordWrap(self, wordWrap): if wordWrap is None: wordWrap = self.TEXT_WORD_WRAP self.textNode.setWordwrap(wordWrap) self.update() def getWordWrap(self): return self.textNode.getWordwrap() def setChatWordWrap(self, chatWordWrap): if (chatWordWrap is None) or (chatWordWrap > self.CHAT_TEXT_WORD_WRAP): chatWordWrap = self.CHAT_TEXT_WORD_WRAP self.chatTextNode.setWordwrap(chatWordWrap) self.update() def getChatWordWrap(self): return self.chatTextNode.getWordwrap() def setForeground(self, foreground): self.textNode.setTextColor(foreground) def setBackground(self, background): if self.panel is not None: self.panel.setColor(background) def setShadow(self, shadow): self.textNode.setShadow(shadow) def getShadow(self): return self.textNode.getShadow() def clearShadow(self): self.textNode.clearShadow() def update(self): if self.chatBalloon is not None: self.chatBalloon.removeNode() self.chatBalloon = None if self.panel is not None: self.panel.removeNode() self.panel = None if self.getChatText(): if self.chatBalloonType == NametagGlobals.CHAT_BALLOON: if not self.chatHidden: model = self.getChatBalloonModel() modelWidth = self.getChatBalloonWidth() modelHeight = self.getChatBalloonHeight() self.drawChatBalloon(model, modelWidth, modelHeight) return elif self.chatBalloonType == NametagGlobals.THOUGHT_BALLOON: if not self.thoughtHidden: model = NametagGlobals.thoughtBalloonModel modelWidth = NametagGlobals.thoughtBalloonWidth modelHeight = NametagGlobals.thoughtBalloonHeight self.drawChatBalloon(model, modelWidth, modelHeight) return if self.getText() and (not self.nametagHidden): self.drawNametag()
class Avatar(Actor, ShadowCaster): notify = DirectNotifyGlobal.directNotify.newCategory('Avatar') def __init__(self, other=None): Actor.__init__(self, None, None, other, flattenable=0, setFinal=1) ShadowCaster.__init__(self) self.collTube = None self.scale = 1.0 self.height = 0.0 self.style = None self.hpText = None self.hpTextGenerator = TextNode('HpTextGenerator') def delete(self): try: self.Avatar_deleted except: Actor.cleanup(self) self.Avatar_deleted = 1 self.style = None self.collTube = None self.hpText = None self.hpTextGenerator = None ShadowCaster.delete(self) Actor.delete(self) def uniqueName(self, name): return 'Avatar-{0}-{1}'.format(id(self), name) def getCollisionId(self): return self.uniqueName('bodyColl') def getAvatarScale(self): return self.scale def setAvatarScale(self, scale): if self.scale != scale: self.scale = scale self.getGeomNode().setScale(scale) self.setHeight(self.height) def getHeight(self): return self.height def setHeight(self, height): self.height = height if not self.collTube: self.initializeBodyCollisions() self.collTube.setPointB(0, 0, height - self.getRadius()) if self.collNodePath: self.collNodePath.forceRecomputeBounds() def getRadius(self): return GameGlobals.AvatarDefaultRadius def getStyle(self): return self.style def setStyle(self, style): self.style = style def getAirborneHeight(self): height = self.getPos(self.shadowPlacer.shadowNodePath) return height.getZ() + 0.025 def initializeBodyCollisions(self): self.collTube = CollisionTube(0, 0, 0.5, 0, 0, self.height - self.getRadius(), self.getRadius()) self.collNode = CollisionNode(self.getCollisionId()) self.collNode.addSolid(self.collTube) self.collNodePath = self.attachNewNode(self.collNode) self.collNode.setCollideMask(BitmaskGlobals.WallBitmask) def showNodePathColl(self): self.collNodePath.show() def stashBodyCollisions(self): if hasattr(self, 'collNodePath'): self.collNodePath.stash() def unstashBodyCollisions(self): if hasattr(self, 'collNodePath'): self.collNodePath.unstash() def disableBodyCollisions(self): if hasattr(self, 'collNodePath'): self.collNodePath.removeNode() del self.collNodePath self.collTube = None def showHpText(self, number, bonus=0, scale=1.75): if number == 0: return if self.hpText: self.hideHpText() self.hpTextGenerator.setFont(GameGlobals.getSignFont()) if number < 0: text = str(number) if random.randrange(0, 100) < SILLY_SURGE_CHANCE: text += '\n' text += random.choice(GameLocalizer.SillySurgeTerms) else: text = '+' + str(number) self.hpTextGenerator.setText(text) self.hpTextGenerator.clearShadow() self.hpTextGenerator.setAlign(TextNode.ACenter) if bonus == 1: color = [1, 1, 0, 1] elif bonus == 2: color = [1, 0.5, 0, 1] elif number < 0: color = [0.9, 0, 0, 1] else: color = [0, 0.9, 0, 1] self.hpTextGenerator.setTextColor(*color) self.hpTextNode = self.hpTextGenerator.generate() self.hpText = self.attachNewNode(self.hpTextNode) self.hpText.setScale(scale) self.hpText.setBillboardPointEye() self.hpText.setBin('fixed', 100) self.hpText.setPos(0, 0, self.height / 2) color[3] = 0 Sequence( self.hpText.posInterval(1.0, (0, 0, self.height + 0.75), blendType='easeOut'), Wait(0.85), self.hpText.colorInterval(0.1, Vec4(*color), 0.1), Func(self.hideHpText)).start() def hideHpText(self): if self.hpText: taskMgr.remove(self.uniqueName('hpText')) self.hpText.removeNode() self.hpText = None
class Nametag: TEXT_WORD_WRAP = 8 TEXT_Y_OFFSET = -0.05 CHAT_TEXT_WORD_WRAP = 12 PANEL_X_PADDING = 0.2 PANEL_Z_PADDING = 0.2 CHAT_BALLOON_ALPHA = 1 def __init__(self): self.avatar = None self.panel = None self.icon = None self.chatBalloon = None self.chatButton = NametagGlobals.noButton self.chatReversed = False self.font = None self.chatFont = None self.chatType = NametagGlobals.CHAT self.chatBalloonType = NametagGlobals.CHAT_BALLOON self.nametagColor = NametagGlobals.NametagColors[NametagGlobals.CCNormal] self.arrowColor = NametagGlobals.NametagColors[NametagGlobals.CCNormal] self.chatColor = NametagGlobals.ChatColors[NametagGlobals.CCNormal] self.speedChatColor = self.chatColor[0][1] self.nametagHidden = False self.chatHidden = False self.thoughtHidden = False # Create our TextNodes: self.textNode = TextNode('text') self.textNode.setWordwrap(self.TEXT_WORD_WRAP) self.textNode.setAlign(TextNode.ACenter) self.chatTextNode = TextNode('chatText') self.chatTextNode.setWordwrap(self.CHAT_TEXT_WORD_WRAP) self.chatTextNode.setGlyphScale(ChatBalloon.TEXT_GLYPH_SCALE) self.chatTextNode.setGlyphShift(ChatBalloon.TEXT_GLYPH_SHIFT) # Add the tick task: self.tickTaskName = self.getUniqueName() + '-tick' self.tickTask = taskMgr.add(self.tick, self.tickTaskName, sort=45) def destroy(self): if self.tickTask is not None: taskMgr.remove(self.tickTask) self.tickTask = None self.chatTextNode = None self.textNode = None self.chatFont = None self.font = None self.chatButton = NametagGlobals.noButton if self.chatBalloon is not None: self.chatBalloon.removeNode() self.chatBalloon = None if self.icon is not None: self.icon.removeAllChildren() self.icon = None if self.panel is not None: self.panel.removeNode() self.panel = None self.avatar = None def getUniqueName(self): return 'Nametag-' + str(id(self)) def getChatBalloonModel(self): pass # Inheritors should override this method. def getChatBalloonWidth(self): pass # Inheritors should override this method. def getChatBalloonHeight(self): pass # Inheritors should override this method. def tick(self, task): return Task.done # Inheritors should override this method. def updateClickRegion(self): pass # Inheritors should override this method. def drawChatBalloon(self, model, modelWidth, modelHeight): pass # Inheritors should override this method. def drawNametag(self): pass # Inheritors should override this method. def setAvatar(self, avatar): self.avatar = avatar def getAvatar(self): return self.avatar def setIcon(self, icon): self.icon = icon def getIcon(self): return self.icon def setChatButton(self, chatButton): self.chatButton = chatButton def getChatButton(self): return self.chatButton def hasChatButton(self): if (self.chatBalloonType == NametagGlobals.CHAT_BALLOON) and self.chatHidden: return False if (self.chatBalloonType == NametagGlobals.THOUGHT_BALLOON) and self.thoughtHidden: return False return self.chatButton != NametagGlobals.noButton def setChatReversed(self, chatReversed): self.chatReversed = chatReversed def getChatReversed(self): return self.chatReversed def setFont(self, font): self.font = font if self.font is not None: self.textNode.setFont(self.font) self.update() def getFont(self): return self.font def setChatFont(self, chatFont): self.chatFont = chatFont if self.chatFont is not None: self.chatTextNode.setFont(self.chatFont) self.update() def getChatFont(self): return self.chatFont def setChatType(self, chatType): self.chatType = chatType def getChatType(self): return self.chatType def setChatBalloonType(self, chatBalloonType): self.chatBalloonType = chatBalloonType def getChatBalloonType(self): return self.chatBalloonType def setNametagColor(self, nametagColor): self.nametagColor = nametagColor def getNametagColor(self): return self.nametagColor def setArrowColor(self, arrowColor): self.arrowColor = arrowColor def getArrowColor(self): return self.arrowColor def setChatColor(self, chatColor): self.chatColor = chatColor def getChatColor(self): return self.chatColor def setSpeedChatColor(self, speedChatColor): self.speedChatColor = speedChatColor def getSpeedChatColor(self): return self.speedChatColor def hideNametag(self): self.nametagHidden = True def showNametag(self): self.nametagHidden = False def hideChat(self): self.chatHidden = True def showChat(self): self.chatHidden = False def hideThought(self): self.thoughtHidden = True def showThought(self): self.thoughtHidden = False def applyClickState(self, clickState): if self.chatBalloon is not None: foreground, background = self.chatColor[clickState] if self.chatType == NametagGlobals.SPEEDCHAT: background = self.speedChatColor if background[3] > self.CHAT_BALLOON_ALPHA: background = VBase4( background[0], background[1], background[2], self.CHAT_BALLOON_ALPHA) self.chatBalloon.setForeground(foreground) self.chatBalloon.setBackground(background) self.chatBalloon.setButton(self.chatButton[clickState]) elif self.panel is not None: foreground, background = self.nametagColor[clickState] self.setForeground(foreground) self.setBackground(background) def setText(self, text): self.textNode.setText(text) def getText(self): return self.textNode.getText() def setChatText(self, chatText): self.chatTextNode.setText(chatText) def getChatText(self): return self.chatTextNode.getText() def setWordWrap(self, wordWrap): if wordWrap is None: wordWrap = self.TEXT_WORD_WRAP self.textNode.setWordwrap(wordWrap) self.update() def getWordWrap(self): return self.textNode.getWordwrap() def setChatWordWrap(self, chatWordWrap): if (chatWordWrap is None) or (chatWordWrap > self.CHAT_TEXT_WORD_WRAP): chatWordWrap = self.CHAT_TEXT_WORD_WRAP self.chatTextNode.setWordwrap(chatWordWrap) self.update() def getChatWordWrap(self): return self.chatTextNode.getWordwrap() def setForeground(self, foreground): self.textNode.setTextColor(foreground) def setBackground(self, background): if self.panel is not None: self.panel.setColor(background) def setShadow(self, shadow): self.textNode.setShadow(shadow) def getShadow(self): return self.textNode.getShadow() def clearShadow(self): self.textNode.clearShadow() def update(self): if self.chatBalloon is not None: self.chatBalloon.removeNode() self.chatBalloon = None if self.panel is not None: self.panel.removeNode() self.panel = None if self.getChatText(): if self.chatBalloonType == NametagGlobals.CHAT_BALLOON: if not self.chatHidden: model = self.getChatBalloonModel() modelWidth = self.getChatBalloonWidth() modelHeight = self.getChatBalloonHeight() self.drawChatBalloon(model, modelWidth, modelHeight) return elif self.chatBalloonType == NametagGlobals.THOUGHT_BALLOON: if not self.thoughtHidden: model = NametagGlobals.thoughtBalloonModel modelWidth = NametagGlobals.thoughtBalloonWidth modelHeight = NametagGlobals.thoughtBalloonHeight self.drawChatBalloon(model, modelWidth, modelHeight) return if self.getText() and (not self.nametagHidden): self.drawNametag()
class Sprite(NodePath, DirectObject): #- Just constant identifiers MouseLeftDown = 'left-down' MouseLeftUp = 'left-up' MouseLeftClick = 'left-click' MouseCenterDown = 'center-down' MouseCenterUp = 'center-up' MouseCenterClick = 'center-click' MouseRightDown = 'right-down' MouseRightUp = 'right-up' MouseRightClick = 'right-click' MouseFourDown = 'four-down' MouseFourUp = 'four-up' MouseFourClick = 'four-click' MouseFiveDown = 'five-down' MouseFiveUp = 'five-up' MouseFiveClick = 'five-click' MouseScrollUp = 'scroll-up' MouseScrollDown = 'scroll-down' MouseEnter = 'enter' MouseExit = 'exit' MouseWithin = 'within' MouseWithout = 'without' StateDefault = 'state-default' StateHover = 'state-hover' StateClick = 'state-click' StateFocus = 'state-focus' StateDisabled = 'state-disabled' def __init__(self, name): NodePath.__init__(self, name) DirectObject.__init__(self) self.setPythonTag('Sprite', self) global SpriteCounter SpriteCounter += 1 self.__id = int(SpriteCounter) #- Use PGItem to detect mouse and keyboard input via PGTop (eg, aspect2d, pixel2d, etc) self.__pgItem = PGItem(name) self.__pgItem.setActive(True) self.__pgItemNp = self.attachNewNode(self.__pgItem) #- Use TextNode to generate both text and cards for displaying background images self.__textNode = TextNode(name) self.__textNodeNp = None #self.__textNodeNp = self.attachNewNode(self.__textNode) #self.__textNode.setCardDecal(True) #- This is what we would do, should Sprite support being non-under PGTop self.accept(self.__pgItem.getPressEvent(MouseButton.one()), self.__onMouse, [Sprite.MouseLeftDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.two()), self.__onMouse, [Sprite.MouseCenterDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.three()), self.__onMouse, [Sprite.MouseRightDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.four()), self.__onMouse, [Sprite.MouseFourDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.five()), self.__onMouse, [Sprite.MouseFiveDown]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.one()), self.__onMouse, [Sprite.MouseLeftUp]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.two()), self.__onMouse, [Sprite.MouseCenterUp]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.three()), self.__onMouse, [Sprite.MouseRightUp]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.four()), self.__onMouse, [Sprite.MouseFourUp]) self.accept(self.__pgItem.getReleaseEvent(MouseButton.five()), self.__onMouse, [Sprite.MouseFiveUp]) self.accept(self.__pgItem.getPressEvent(MouseButton.wheelDown()), self.__onMouse, [Sprite.MouseScrollDown]) self.accept(self.__pgItem.getPressEvent(MouseButton.wheelUp()), self.__onMouse, [Sprite.MouseScrollUp]) self.accept(self.__pgItem.getEnterEvent(), self.__onMouse, [Sprite.MouseEnter]) self.accept(self.__pgItem.getExitEvent(), self.__onMouse, [Sprite.MouseExit]) self.accept(self.__pgItem.getWithinEvent(), self.__onMouse, [Sprite.MouseWithin]) self.accept(self.__pgItem.getWithoutEvent(), self.__onMouse, [Sprite.MouseWithout]) self.__beastDebug = ConfigVariableBool('beast-debug', False).getValue() self.__mouseInside = False self.__disabled = False #- Setup state configuration self.__lastStateOptions = None self.__state = None self.__states = { 'default': SpriteOptions(), 'hover': SpriteOptions(), 'click': SpriteOptions(), 'focus': SpriteOptions(), 'disabled': SpriteOptions(), } self.updateToState('default') def setDirty(self, dirty=True): if dirty: self.setTag('dirty', '') else: self.clearTag('dirty') def setDisabled(self, disabled): self.__disabled = disabled if self.__disabled: self.updateToState('disabled') else: #- FIXME! Account for focus? self.updateToState('default') def isDisabled(self): return self.__disabled def bind(self, event, method, extraArgs=[], onlyOnce=False): actualEvent = self.getEvent(event) if onlyOnce: self.acceptOnce(event, method, extraArgs=extraArgs) else: self.accept(event, method, extraArgs=extraArgs) def unbind(self, event): actualEvent = self.getEvent(event) self.ignore(actualEvent) def getEvent(self, event): return 'Sprite-' + str(self.__id) + '-' + self.getName() + '-' + event def __onMouse(self, event, mwr): if event == Sprite.MouseEnter: self.__mouseInside = True elif event == Sprite.MouseExit: self.__mouseInside = False actualEvents = [] actualEvents.append(event) if self.__mouseInside: if event == Sprite.MouseLeftUp: actualEvents.append(Sprite.MouseLeftClick) elif event == Sprite.MouseCenterUp: actualEvents.append(Sprite.MouseCenterClick) elif event == Sprite.MouseRightUp: actualEvents.append(Sprite.MouseRightClick) elif event == Sprite.MouseFourUp: actualEvents.append(Sprite.MouseFourClick) elif event == Sprite.MouseFiveUp: actualEvents.append(Sprite.MouseFiveClick) #- Handle state changing for event in actualEvents: if self.__state == 'default': if event == Sprite.MouseEnter: self.updateToState('hover') elif self.__state == 'hover': if event == Sprite.MouseExit: self.updateToState('default') if event == Sprite.MouseLeftDown: self.updateToState('click') elif self.__state == 'click': if event == Sprite.MouseLeftClick: # self.updateToState('focus') self.updateToState('hover') if event == Sprite.MouseLeftUp and self.__mouseInside == False: # self.updateToState('focus') self.updateToState('default') #- Finally, we can send out user events for event in actualEvents: messenger.send(self.getEvent(event)) def updateToState(self, newState=None): if newState == self.__state: return if newState: self.__state = newState if self.__beastDebug: print self.__state, globalClock.getFrameCount() messenger.send(self.getEvent('state-' + self.__state)) defaultOptions = self.__states['default'] hoverOptions = self.__states['hover'] clickOptions = self.__states['click'] focusOptions = self.__states['focus'] disabledOptions = self.__states['disabled'] if self.__state == 'default': self._applySpriteOptions(SpriteOptions.combine(defaultOptions)) elif self.__state == 'hover': self._applySpriteOptions( SpriteOptions.combine(defaultOptions, hoverOptions)) elif self.__state == 'click': self._applySpriteOptions( SpriteOptions.combine(defaultOptions, hoverOptions, clickOptions)) elif self.__state == 'focus': self._applySpriteOptions( SpriteOptions.combine(defaultOptions, focusOptions)) elif self.__state == 'disabled': self._applySpriteOptions( SpriteOptions.combine(defaultOptions, disabledOptions)) def _applySpriteOptions(self, options): dirty = False if options.options.values() == self.__lastStateOptions: return else: self.__lastStateOptions = options.options.values() self.setDirty() dirty = True #- First we do checks for size if options.hasSize(): self.__pgItem.setActive(True) #- It has a size, so it's active x, y = options.getSize() self.__pgItem.setFrame(0, x, -y, 0) #- Set both the card and frame bounds to match the size specified self.__textNode.setCardActual(0, x, -y, 0) if options.hasBorderColor(): #- They want a border, no matter what self.__textNode.setFrameActual(0, x, -y, 0) if options.hasBorderWidth(): self.__textNode.setFrameLineWidth(options.getBorderWidth()) else: self.__textNode.setFrameLineWidth(1) else: #- They want no border self.__textNode.clearFrame() self.__textNode.setFrameLineWidth(0) #- Unimportant I think else: self.__pgItem.setActive(False) #- It has no size, it's un active self.__pgItem.setFrame(0, 0, 0, 0) self.__textNode.clearCard() self.__textNode.clearFrame() if options.hasFont(): self.__textNode.setFont(options.getFont()) else: self.__textNode.clearFont() if options.hasFontSize(): #- FIXME! change for point2d later textNodeScale = 1.0 / options.getFontSize() #- Applied later # #self.__textNodeNp.setScale(1.0 / options.getFontSize()) # FIXME? Make sure it's 4 spaces self.__textNode.setTabWidth(options.getFontSize() * 4.0) else: textNodeScale = 1.0 # #self.__textNodeNp.setScale(1.0) if options.hasBackgroundColor(): color = options.getBackgroundColor().getAsFloat() self.__textNode.setCardColor(*color) else: if options.hasSize(): self.__textNode.setCardColor(1, 1, 1, 1) #- White else: self.__textNode.setCardColor(0, 0, 0, 0) #- Clear if options.hasBorderColor(): color = options.getBorderColor().getAsFloat() self.__textNode.setFrameColor(*color) else: self.__textNode.setFrameColor(0, 0, 0, 0) #- Clear if options.hasText(): text = options.getText() self.__textNode.setWtext(options.getText()) if options.hasTextPadding(): px, py = options.getTextPadding() else: px, py = (0, 0) #- Set sizes, even if they have no color self.__textNode.setCardAsMargin(px, px, py, py) self.__textNode.setFrameAsMargin(px, px, py, py) l, r, b, t = self.__textNode.getCardActual() #- Offset the TextNode so it only extends right and down #- FIXME! change for point2d later? (Does scale apply there even haha?) s = textNodeScale l, r, b, t = l * s, r * s, b * s, t * s textNodeX = -l #- Applied later textNodeZ = -t #- Applied later #self.__textNodeNp.setX(-l) #self.__textNodeNp.setZ(-t) self.__pgItem.setActive(True) #- It has a size now, it's active self.__pgItem.setFrame(0, -l + r, -t + b, 0) else: self.__textNode.setWtext( u' ' ) #- It's important to have a space, otherwise no card is rendered! textNodeX = 0 #- Applied later textNodeZ = 0 #- Applied later #self.__textNodeNp.setX(0) #self.__textNodeNp.setZ(0) if not options.hasSize(): self.__pgItem.setFrame(0, 0, 0, 0) if options.hasTextAlign(): align = options.getTextAlign() if align == 'left': self.__textNode.setAlign(TextNode.ALeft) elif align == 'center': self.__textNode.setAlign(TextNode.ACenter) elif align == 'right': self.__textNode.setAlign(TextNode.ARight) else: self.__textNode.clearAlign() if options.hasTextColor(): color = options.getTextColor().getAsFloat() self.__textNode.setTextColor(*color) #self.__textNodeNp.setColor(*color) #else: self.__textNode.setTextColor(0, 0, 0, 1) #- Black # self.__textNodeNp.clearColor() if options.hasTextSmallCaps(): self.__textNode.setSmallCaps(options.getTextSmallCaps()) else: self.__textNode.clearSmallCaps() if options.hasTextSmallCapsScale(): self.__textNode.setSmallCapsScale(options.getTextSmallCapsScale()) else: self.__textNode.clearSmallCapsScale() if options.hasTextSlant(): self.__textNode.setSlant(options.getTextSlant()) else: self.__textNode.clearSlant() if options.hasTextUnderline(): self.__textNode.setUnderscore(options.getTextUnderline()) else: self.__textNode.clearUnderscore() if options.hasTextShadow(): self.__textNode.setShadow(*options.getTextShadow()) else: self.__textNode.clearShadow() if options.hasTextShadowColor(): color = options.getTextShadowColor().getAsFloat() self.__textNode.setShadowColor(*color) else: self.__textNode.clearShadowColor() if self.__textNodeNp: self.__textNodeNp.remove() self.__textNodeNp = self.attachNewNode(self.__textNode.generate()) self.__textNodeNp.setScale(textNodeScale) self.__textNodeNp.setX(textNodeX) self.__textNodeNp.setZ(textNodeZ) ''' def setup(self, textNodeScale, textNodeX, textNodeZ): print 'getting lock...' base.textThreadLock.acquire() print 'Got lock' if self.__textNodeNp: self.__textNodeNp.remove() self.__textNodeNp = self.attachNewNode('foobar') #textNode.generate() print 'yes, it generated' base.textThreadLock.release() ''' #self.__textNodeNp = self.attachNewNode(self.__textNode.generate()) #self.__textNodeNp.setScale(textNodeScale) #self.__textNodeNp.setX(textNodeX) #self.__textNodeNp.setZ(textNodeZ) ''' import direct.stdpy.threading t = threading.Thread(target=setup, args=(self, textNodeScale, textNodeX, textNodeZ)) t.start() ''' if dirty: messenger.send('beastCollectionUpdate') def getOptions(self, state): return self.__states[state] def getCurrentOptions(self): return self.__states[self.__state] def getCurrentState(self): return self.__state def getPgItem(self): return self.__pgItem def getPgItemNp(self): return self.__pgItemNp def getTextNode(self): return self.__textNode def getTextNodeNp(self): return self.__textNodeNp @staticmethod def destroyChildren(np): for child in np.getChildren(): if child.hasPythonTag('Sprite'): sprite = child.getPythonTag('Sprite') sprite.destroy() def destroy(self): self.clearPythonTag('Sprite') self.ignoreAll() Sprite.destroyChildren(self) self.remove()