class TextCell(Cell): def __init__(self, app, row, column): super(TextCell, self).__init__(app, row, column) textAlign = self.styleGet('textAlign') self.textElement = TextElement( self.app, '', self.styleGet('font'), Location(CellAttachedPoint((0, 0), self, textAlign), textAlign), colour=self.styleGet('foreColour')) self.elements = [self.textElement] self._oldText = '' def setText(self, text): if text != self._oldText: self.textElement.setText(text) self._styleChanged = True self._oldText = text def _update(self): self.textElement.setFont(self.styleGet('font')) self.textElement.setColour(self.styleGet('foreColour')) textAlign = self.styleGet('textAlign') self.textElement.pos.anchor = textAlign self.textElement.pos.point.attachedAt = textAlign self.textElement.setShadow(self.styleGet('hasShadow')) self.textElement.setShadowColour(self.styleGet('shadowColour'))
def __init__(self, app): size = Canvas(512, 384) DialogBox.__init__(self, app, size, 'Please authenticate') self._deferred = None self._host = None font = app.screenManager.fonts.defaultTextBoxFont btnColour = app.theme.colours.dialogButtonColour highlightColour = app.theme.colours.black errorTextColour = app.theme.colours.errorColour self.tabContainer = TabContainer(app, Region(topleft=self.Relative(0, 0), size=self.Relative(1, 0.75)), font, app.theme.colours.tabContainerColour) self.tabContainer.addTab(LoginTab(app)) self.tabContainer.addTab(CreateAccountTab(app)) self.errorText = TextElement(app, '', font, Location(self.Relative(0.5, 0.8), 'center'), errorTextColour) font = app.screenManager.fonts.bigMenuFont self.elements = [ self.tabContainer, self.errorText, TextButton(app, Location(self.Relative(0.3, 0.9), 'center'), 'Ok', font, btnColour, highlightColour, onClick=self.okClicked), TextButton(app, Location(self.Relative(0.7, 0.9), 'center'), 'Cancel', font, btnColour, highlightColour, onClick=self.cancelClicked), ] self.cancelled = False
class ConnectingScreen(framework.CompoundElement): def __init__(self, app, serverName='server', onCancel=None): super(ConnectingScreen, self).__init__(app) colours = app.theme.colours self.text = TextElement(self.app, 'Connecting to %s...' % serverName, self.app.screenManager.fonts.bigMenuFont, ScaledLocation(512, 384, 'center'), colour=colours.connectingColour) button = TextButton( self.app, Location(ScaledScreenAttachedPoint(ScaledSize(0, 300), 'center'), 'center'), 'cancel', self.app.screenManager.fonts.bigMenuFont, colours.mainMenuColour, colours.white, onClick=onCancel) self.onCancel = button.onClick self.elements = [button, self.text] def setServer(self, serverName): self.text.setText('Connecting to %s...' % serverName) self.text.setFont(self.app.screenManager.fonts.bigMenuFont)
def __init__(self, app): Tab.__init__(self, app, 'Sign in') framework.TabFriendlyCompoundElement.__init__(self, app) font = app.screenManager.fonts.defaultTextBoxFont labelColour = app.theme.colours.dialogBoxTextColour inputColour = app.theme.colours.grey self.usernameField = prompt.InputBox(app, Region(topleft=self.Relative(0.1, 0.16), bottomright=self.Relative(0.9, 0.32)), font=font, colour=inputColour, validator=usernameValidator, onClick=self.setFocus, onTab=self.tabNext) self.passwordField = prompt.PasswordBox(app, Region(topleft=self.Relative(0.1, 0.48), bottomright=self.Relative(0.9, 0.64)), font=font, colour=inputColour, onClick=self.setFocus, onTab=self.tabNext) self.elements = [ TextElement(app, 'Username', font, Location(self.Relative(0.1, 0.11), 'midleft'), labelColour), self.usernameField, TextElement(app, 'Password', font, Location(self.Relative(0.1, 0.43), 'midleft'), labelColour), self.passwordField, ] self.tabOrder = [self.usernameField, self.passwordField]
def __init__(self, app, row, column): super(TextCell, self).__init__(app, row, column) textAlign = self.styleGet('textAlign') self.textElement = TextElement( self.app, '', self.styleGet('font'), Location(CellAttachedPoint((0, 0), self, textAlign), textAlign), colour=self.styleGet('foreColour')) self.elements = [self.textElement] self._oldText = ''
def __init__(self, app): super(UpgradeDisplay, self).__init__(app) self.player = None self.upgrade = None self.coinsText = TextElement( self.app, '', self.app.screenManager.fonts.coinsDisplayFont, Location(Screen(0.65, 0.01), 'midtop'), self.app.theme.colours.coinsDisplayColour, shadow=True) self.elements = [self.coinsText]
def __init__(self, app): super(WinnerMsg, self).__init__(app) self.winnerMsg = TextElement(app, '', app.screenManager.fonts.winMessageFont, Location(Screen(0.5, 0.05), 'midtop'), (64, 64, 64)) self.background = SolidRect( app, (128, 128, 128), 150, PaddedRegion(self.winnerMsg, ScaledScalar(15))) self.elements = []
def refresh(self): if not self.isOpen(): return self.elements = [self.sayToTeam, self.input] initialY = 470 count = 0 for text, nick, colour, firstLine in reversed(self.messageBuffer): currentY = initialY - count * self.MESSAGE_GAP if currentY < 200 or count >= 10: break if firstLine and nick is not None: person = TextElement( self.app, text=nick, font=self.font, pos=Location( FullScreenAttachedPoint((20, currentY), 'topleft'), 'topleft'), colour=colour, shadow=True, ) xOffset = person._getRect().width self.elements.append(person) text = text[len(nick):] else: xOffset = 0 if nick is None: colour = self.app.theme.colours.serverChat else: colour = self.textColour message = TextElement( self.app, text=text, font=self.font, pos=Location( FullScreenAttachedPoint((20 + xOffset, currentY), 'topleft'), 'topleft'), colour=colour, shadow=True, ) self.elements.append(message) count += 1
class UpgradeDisplay(framework.CompoundElement): def __init__(self, app): super(UpgradeDisplay, self).__init__(app) self.player = None self.upgrade = None self.coinsText = TextElement( self.app, '', self.app.screenManager.fonts.coinsDisplayFont, Location(Screen(0.65, 0.01), 'midtop'), self.app.theme.colours.coinsDisplayColour, shadow=True) self.elements = [self.coinsText] def refresh(self): self.setUpgrade(self.upgrade, self.player) def tick(self, deltaT): super(UpgradeDisplay, self).tick(deltaT) if self.player: self.coinsText.setText('${}'.format(self.player.coins)) else: self.coinsText.setText('') def setUpgrade(self, upgradeType, player): self.player = player self.upgrade = upgradeType if player is None or upgradeType is None: self.elements = [self.coinsText] else: pos = Location(Screen(0.6, 0), 'midtop') image = self.app.theme.sprites.upgradeImage(upgradeType) area = Area( RelativePoint(Screen(0.6, 0), (0, 52)), ScaledSize(50, 10), 'midtop') self.elements = [ PictureElement(self.app, image, pos), self.coinsText, ] if upgradeType.enabled: self.elements.append( CoinGauge(self.app, area, player, upgradeType)) else: self.elements.append( TextElement(self.app, 'DISABLED', self.app.screenManager.fonts.ingameMenuFont, Location(CanvasX(620, 68), 'midbottom'), self.app.theme.colours.errorMessageColour))
def __init__(self, app): size = Canvas(384, 150) DialogBox.__init__(self, app, size, 'Host game?') self._deferred = None font = app.screenManager.fonts.defaultTextBoxFont btnColour = app.theme.colours.dialogButtonColour highlightColour = app.theme.colours.black labelColour = app.theme.colours.dialogBoxTextColour btnFont = app.screenManager.fonts.bigMenuFont self.elements = [ TextElement(app, 'No games found. Host a game?', font, Location(self.Relative(0.5, 0.4), 'center'), labelColour), TextButton(app, Location(self.Relative(0.3, 0.85), 'center'), 'Yes', btnFont, btnColour, highlightColour, onClick=self.yesClicked), TextButton(app, Location(self.Relative(0.7, 0.85), 'center'), 'No', btnFont, btnColour, highlightColour, onClick=self.noClicked), ]
def setUpgrade(self, upgradeType, player): self.player = player self.upgrade = upgradeType if player is None or upgradeType is None: self.elements = [self.coinsText] else: pos = Location(Screen(0.6, 0), 'midtop') image = self.app.theme.sprites.upgradeImage(upgradeType) area = Area( RelativePoint(Screen(0.6, 0), (0, 52)), ScaledSize(50, 10), 'midtop') self.elements = [ PictureElement(self.app, image, pos), self.coinsText, ] if upgradeType.enabled: self.elements.append( CoinGauge(self.app, area, player, upgradeType)) else: self.elements.append( TextElement(self.app, 'DISABLED', self.app.screenManager.fonts.ingameMenuFont, Location(CanvasX(620, 68), 'midbottom'), self.app.theme.colours.errorMessageColour))
def __init__(self, app, world, interface): super(ChatBox, self).__init__(app) self.world = world self.app = app self.interface = interface self.font = self.app.screenManager.fonts.newChatFont self.frameColour = self.app.theme.colours.chatFrameColour self.insideColour = self.app.theme.colours.chatInsideColour self.textColour = self.app.theme.colours.chatNormalColour self.sayToTeam = TextElement( self.app, text="Say to team:", font=self.font, pos=Location(FullScreenAttachedPoint((20, 501), 'topleft'), 'topleft'), colour=self.textColour, shadow=True, ) self.inputPosition = Area( FullScreenAttachedPoint((145, 500), 'topleft'), (370, 20), 'topleft') self.input = InputBox(self.app, self.inputPosition, font=self.font) self.input.onEnter.addListener( lambda sender: self.hitEnter(sender.value)) self.input.onEsc.addListener(lambda sender: self.close()) self.input.onClick.addListener(self.setFocus) self.messages = MessageBank( self.app, 10, 100, Location(FullScreenAttachedPoint((20, 470), 'topleft'), 'topleft'), 'left', 'bottom', self.font) self._chatOpen = False self.teamChat = True self.player = None self.messageBuffer = [] self.MESSAGE_GAP = self.font.getHeight(self.app) self.elements = [self.messages]
def __init__(self, app, player, achievementId): super(AchievementBox, self).__init__(app) self.app = app self.player = player self.achievements = [achievementId] self.width = 453 self.height = 75 self._setColours() self.area = Area( FullScreenAttachedPoint(ScaledSize(0, -100), 'midbottom'), ScaledSize(self.width, self.height), 'midbottom') self.smlBox = Area( FullScreenAttachedPoint(ScaledSize(-self.width / 2 + 6, -104), 'midbottom'), ScaledSize(66, 66), 'bottomleft') self.titleText = TextElement( self.app, "ACHIEVEMENT UNLOCKED!", self.fonts.achievementTitleFont, Location( FullScreenAttachedPoint( ScaledSize(73 / 2, -100 - self.height + 10), 'midbottom'), 'midtop'), self.borderColour) self.nameText = TextElement( self.app, self.achievementDefs.getAchievementDetails(achievementId)[0], self.fonts.achievementNameFont, Location( FullScreenAttachedPoint(ScaledSize(73 / 2, -100 - 13), 'midbottom'), 'midbottom'), self.colours.black) self.elements = [self.titleText, self.nameText] self._updateImage() self.cycler = WeakLoopingCall(self, 'cycleAchievements') self.cycler.start(5.0, now=False)
class WinnerMsg(framework.CompoundElement): def __init__(self, app): super(WinnerMsg, self).__init__(app) self.winnerMsg = TextElement(app, '', app.screenManager.fonts.winMessageFont, Location(Screen(0.5, 0.05), 'midtop'), (64, 64, 64)) self.background = SolidRect( app, (128, 128, 128), 150, PaddedRegion(self.winnerMsg, ScaledScalar(15))) self.elements = [] def show(self, text, colour): self.winnerMsg.setText(text) self.background.colour = colour self.background.border = colour self.background.refresh() self.elements = [self.background, self.winnerMsg] def hide(self): self.elements = []
def __init__(self, app, nick, head): title = 'Player settings' DialogBox.__init__(self, app, Canvas(400, 290), title) labelFont = app.screenManager.fonts.bigMenuFont labelColour = app.theme.colours.dialogBoxTextColour btnFont = app.screenManager.fonts.bigMenuFont btnColour = app.theme.colours.dialogButtonColour highlightColour = app.theme.colours.black inputFont = app.screenManager.fonts.defaultTextBoxFont inputColour = app.theme.colours.grey self.inputBox = InputBox( app, Region(topleft=self.Relative(0.1, 0.25), bottomright=self.Relative(0.9, 0.45)), nick, font=inputFont, colour=inputColour, onClick=self.setFocus, onEnter=self.ok_clicked, onEsc=self.cancel_clicked, ) self.heads = HeadSelector( app, Region(topleft=self.Relative(0.1, 0.5), bottomright=self.Relative(0.9, 0.8))) self.heads.selected(head) self.elements = [ TextElement(app, 'Nickname:', labelFont, Location(self.Relative(0.1, 0.15), 'midleft'), labelColour), self.inputBox, self.heads, TextButton(app, Location(self.Relative(0.3, 0.9), 'center'), 'Ok', btnFont, btnColour, highlightColour, onClick=self.ok_clicked), TextButton(app, Location(self.Relative(0.7, 0.9), 'center'), 'Cancel', btnFont, btnColour, highlightColour, onClick=self.cancel_clicked), ] self.setFocus(self.inputBox)
def __init__(self, app): super(TrosnothBackdrop, self).__init__(app) backdropPath = app.theme.getPath('startupMenu', 'blackdrop.png') backdrop = Backdrop(app, backdropPath, app.theme.colours.backgroundFiller) # Things that will be part of the backdrop of the entire startup menu # system. verFont = self.app.screenManager.fonts.versionFont self.elements = [ backdrop, TextElement(self.app, titleVersion, verFont, Location(FullScreenAttachedPoint(ScaledSize(-10,-10), 'bottomright'), 'bottomright'), app.theme.colours.versionColour), ]
def __init__(self, app, message, font, area, buttonPos, textPos, url=None, textColour=(0, 0, 0), closeColour=(0, 0, 0), hoverColour=(255, 255, 255), backColour=(255, 150, 150), textAnchor='center'): super(NotificationBar, self).__init__(app) self.area = area self.url = url self.backColour = backColour self.rect = pygame.Rect(0, 0, 0, 0) self.background = pygame.Surface(self.rect.size) self.visible = False self.onClick = Event() self.onClose = Event() self.elements = [ # A blank rectangle. SizedPicture(app, self.background, area, area.size), # The text. TextElement(app, message, font, textPos, textColour, anchor=textAnchor), # A button to dismiss it. TextButton(app, pos=buttonPos, text='[close]', font=font, stdColour=closeColour, hvrColour=hoverColour, onClick=self._doHide) ]
def __init__(self, app): size = Canvas(512, 384) DialogBox.__init__(self, app, size, 'Select arena') self._deferred = None self._games = None font = app.screenManager.fonts.defaultTextBoxFont btnColour = app.theme.colours.dialogButtonColour highlightColour = app.theme.colours.black labelColour = app.theme.colours.dialogBoxTextColour btnFont = app.screenManager.fonts.bigMenuFont listboxFont = app.screenManager.fonts.serverListFont listboxColour = app.theme.colours.mainMenuColour listboxHighlight = app.theme.colours.mainMenuHighlight self.gameList = ListBox( self.app, Region(topleft=self.Relative(0.05, 0.15), size=self.Relative(0.9, 0.65)), [], listboxFont, listboxColour, listboxHighlight, ) self.elements = [ TextElement(app, 'Please select:', font, Location(self.Relative(0.05, 0.05), 'topleft'), labelColour), self.gameList, TextButton(app, Location(self.Relative(0.3, 0.9), 'center'), 'Ok', btnFont, btnColour, highlightColour, onClick=self.okClicked), TextButton(app, Location(self.Relative(0.7, 0.9), 'center'), 'Cancel', btnFont, btnColour, highlightColour, onClick=self.cancelClicked), ]
def __init__(self, app, title, label, validator=None): DialogBox.__init__(self, app, Canvas(400, 230), title) labelFont = app.screenManager.fonts.bigMenuFont labelColour = app.theme.colours.dialogBoxTextColour btnFont = app.screenManager.fonts.bigMenuFont btnColour = app.theme.colours.dialogButtonColour highlightColour = app.theme.colours.black inputFont = app.screenManager.fonts.defaultTextBoxFont inputColour = app.theme.colours.grey self.inputBox = InputBox(app, Region(topleft=self.Relative(0.1, 0.4), bottomright=self.Relative(0.9, 0.6)), font=inputFont, colour=inputColour, onClick=self.setFocus, onEnter=self.okClicked, onEsc=self.cancelClicked, validator=validator) self.elements = [ TextElement(app, label, labelFont, Location(self.Relative(0.1, 0.2), 'midleft'), labelColour), self.inputBox, TextButton(app, Location(self.Relative(0.3, 0.9), 'center'), 'Ok', btnFont, btnColour, highlightColour, onClick=self.okClicked), TextButton(app, Location(self.Relative(0.7, 0.9), 'center'), 'Cancel', btnFont, btnColour, highlightColour, onClick=self.cancelClicked), ] self.setFocus(self.inputBox)
def __init__(self, app, reason): width = app.screenManager.scaleFactor * absoluteWidth font = app.fonts.connectionFailedFont boundary = app.screenManager.scaleFactor * 20 lines = wrapWords(app, reason, font, width - 2 * boundary) x = boundary elements = [] colours = app.theme.colours for text in lines: elements.append( TextElement(app, text, font, Location( DialogBoxAttachedPoint(self, (0, x), 'midtop'), 'midtop'), colour=colours.errorColour)) x += font.getHeight(app) # Boundary * 3 for top, bottom, and middle height = boundary * 3 + font.getHeight(app) * (len(lines) + 1) size = ScaledSize(absoluteWidth, height) super(ConnectionFailedDialog, self).__init__(app, size, 'Connection Failed') self.elements = elements self.elements.append( TextButton(app, Location( DialogBoxAttachedPoint(self, (0, -boundary), 'midbottom'), 'midbottom'), 'OK', font, colours.dialogButtonColour, colours.radioMouseover, onClick=lambda sender: self.close())) self.onEnter = Event() self.onEnter.addListener(self.close)
def __init__(self, app, text, area, image, value=None): super(ImageRadioButton, self).__init__(app) textLoc = Location(AttachedPoint((0, 0), self._getRect, 'midbottom'), 'midbottom') font = app.screenManager.fonts.smallNoteFont self.text = TextElement(app, text, font, textLoc, (0, 0, 0)) picLoc = Location(AttachedPoint((0, 0), self._getRect, 'midtop'), 'midtop') self.area = area self.value = value self._selected = False self.group = None self.bg = self.IRB_background(app, self) self.elements = [self.bg, self.text] if image is not None: self.image = PictureElement(app, image, picLoc) self.elements.insert(1, self.image)
class AchievementBox(framework.CompoundElement): achievementDefs = availableAchievements def __init__(self, app, player, achievementId): super(AchievementBox, self).__init__(app) self.app = app self.player = player self.achievements = [achievementId] self.width = 453 self.height = 75 self._setColours() self.area = Area( FullScreenAttachedPoint(ScaledSize(0, -100), 'midbottom'), ScaledSize(self.width, self.height), 'midbottom') self.smlBox = Area( FullScreenAttachedPoint(ScaledSize(-self.width / 2 + 6, -104), 'midbottom'), ScaledSize(66, 66), 'bottomleft') self.titleText = TextElement( self.app, "ACHIEVEMENT UNLOCKED!", self.fonts.achievementTitleFont, Location( FullScreenAttachedPoint( ScaledSize(73 / 2, -100 - self.height + 10), 'midbottom'), 'midtop'), self.borderColour) self.nameText = TextElement( self.app, self.achievementDefs.getAchievementDetails(achievementId)[0], self.fonts.achievementNameFont, Location( FullScreenAttachedPoint(ScaledSize(73 / 2, -100 - 13), 'midbottom'), 'midbottom'), self.colours.black) self.elements = [self.titleText, self.nameText] self._updateImage() self.cycler = WeakLoopingCall(self, 'cycleAchievements') self.cycler.start(5.0, now=False) def addAchievement(self, achievementId): self.achievements.append(achievementId) self.titleText.setText("%d ACHIEVEMENTS UNLOCKED!" % len(self.achievements)) def _updateImage(self): try: filepath = self.app.theme.getPath('achievements', '%s.png' % self.achievements[0]) except IOError: filepath = self.app.theme.getPath('achievements', 'default.png') image = pygame.image.load(filepath).convert() image = pygame.transform.smoothscale( image, ScaledSize(64, 64).getSize(self.app)) if type(self.elements[-1]) == PictureElement: self.elements.pop() self.image = PictureElement( self.app, image, Location( FullScreenAttachedPoint(ScaledSize(-self.width / 2 + 7, -105), 'midbottom'), 'bottomleft')) self.elements.append(self.image) def cycleAchievements(self): del self.achievements[0] if len(self.achievements) == 0: self.cycler.stop() return elif len(self.achievements) == 1: self.titleText.setText("ACHIEVEMENT UNLOCKED!") else: self.titleText.setText("%d ACHIEVEMENTS UNLOCKED!" % len(self.achievements)) self.nameText.setText( self.achievementDefs.getAchievementDetails( self.achievements[0])[0]) self._updateImage() def _setColours(self): self.colours = self.app.theme.colours self.fonts = self.app.screenManager.fonts if self.player.teamId == 'A': self.borderColour = self.colours.achvBlueBorder self.bgColour = self.colours.achvBlueBackground else: self.borderColour = self.colours.achvRedBorder self.bgColour = self.colours.achvRedBackground def _getRect(self, area): return area.getRect(self.app) def draw(self, surface): mainRect = self._getRect(self.area) boxRect = self._getRect(self.smlBox) surface.fill(self.bgColour, mainRect) pygame.draw.rect(surface, self.borderColour, mainRect, 2) surface.fill(self.colours.white, boxRect) pygame.draw.rect(surface, self.borderColour, boxRect, 1) super(AchievementBox, self).draw(surface)
class PasswordGUI(DialogBox): def __init__(self, app): size = Canvas(512, 384) DialogBox.__init__(self, app, size, 'Please authenticate') self._deferred = None self._host = None font = app.screenManager.fonts.defaultTextBoxFont btnColour = app.theme.colours.dialogButtonColour highlightColour = app.theme.colours.black errorTextColour = app.theme.colours.errorColour self.tabContainer = TabContainer( app, Region(topleft=self.Relative(0, 0), size=self.Relative(1, 0.75)), font, app.theme.colours.tabContainerColour) self.tabContainer.addTab(LoginTab(app)) self.tabContainer.addTab(CreateAccountTab(app)) self.errorText = TextElement( app, '', font, Location(self.Relative(0.5, 0.8), 'center'), errorTextColour) font = app.screenManager.fonts.bigMenuFont self.elements = [ self.tabContainer, self.errorText, TextButton(app, Location(self.Relative(0.3, 0.9), 'center'), 'Ok', font, btnColour, highlightColour, onClick=self.okClicked), TextButton(app, Location(self.Relative(0.7, 0.9), 'center'), 'Cancel', font, btnColour, highlightColour, onClick=self.cancelClicked), ] self.cancelled = False def setCancelled(self, cancelled): self.cancelled = cancelled def processEvent(self, event): if event.type == pygame.KEYDOWN and event.key in (pygame.K_KP_ENTER, pygame.K_RETURN): self.okClicked() return None else: return DialogBox.processEvent(self, event) def cancelClicked(self, element=None): self.close() self._deferred.callback(None) def okClicked(self, element=None): if self.tabContainer.selectedIndex == 1: create = True # Check that passwords match. tab = self.tabContainer.tabs[1] if tab.passwordField.value != tab.passwordField2.value: self.setErrorText('Passwords do not match!') return else: create = False tab = self.tabContainer.tabs[0] username = tab.usernameField.value password = tab.passwordField.value if len(username) == 0: self.setErrorText('You must give a username!') return if len(password) == 0: self.setErrorText('Password cannot be blank!') return self.close() self.app.identitySettings.usernames[self._host] = username self._deferred.callback((create, username, password)) def getPassword(self, host, errorMsg=''): if self.showing: raise PasswordGUIError('PasswordGUI already showing') if self.cancelled: self.cancelled = False result = self._deferred = defer.Deferred() WeakCallLater(0.1, result, 'callback', None) return result self.setCaption(host) self.tabContainer.tabs[0].reset(host) self.tabContainer.tabs[1].reset() self.setErrorText(errorMsg) self.show() self._host = host result = self._deferred = defer.Deferred() return result def setErrorText(self, text): self.errorText.setText(text)
def draw(self, surface): if not self.world.map: return self.calculateSize() super(GameProgressBar, self).draw(surface) if self.disrupt and random.random() < 0.2: disrupt = True else: disrupt = False # Automatically generated constants yTop = self.yTop yBottom = self.yBottom yText = yTop xFarLeft = self.xFarLeft xFarRight = self.xFarRight xLeft = self.xLeft xRight = self.xRight # Define the coordinates for the static shapes border = [ (xFarLeft, yTop), (xFarRight, yTop), (xRight, yBottom), (xLeft, yBottom), ] blueTriangle = [ (xFarLeft, yTop), (xLeft, yTop), (xLeft, yBottom), ] redTriangle = [ (xFarRight, yTop), (xRight, yTop), (xRight, yBottom), ] # Get the information we need blueScore = self.getBlueScore() blueProportion = self.getBlueProportion() redScore = self.getRedScore() redProportion = self.getRedProportion() neutralScore = self.getNeutralScore() neutralProportion = self.getNeutralProportion() gameOver = self.isGameOver() # Define the coordinates for the dynamic shapes mutableBarLength = xRight - xLeft if redProportion > 0: blueBarLength = int(round(mutableBarLength * blueProportion)) else: blueBarLength = mutableBarLength if blueProportion > 0: redBarLength = int(round(mutableBarLength * redProportion)) else: redBarLength = mutableBarLength xNeutral = ((xLeft + blueBarLength) + (xRight - redBarLength)) / 2 xFirstBar = xLeft + blueBarLength xSecondBar = xRight - redBarLength blueBar = [ (xLeft, yTop), (xLeft + blueBarLength, yTop), (xLeft + blueBarLength, yBottom), (xLeft, yBottom), ] redBar = [ (xRight - redBarLength, yTop), (xRight, yTop), (xRight, yBottom), (xRight - redBarLength, yBottom), ] greyBar = [ (xLeft + blueBarLength + 1, yTop), (xRight - redBarLength - 1, yTop), (xRight - redBarLength - 1, yBottom), (xLeft + blueBarLength + 1, yBottom), ] # Draw the two triangles on the sides if blueProportion > 0: pygame.draw.polygon(surface, self.blue, blueTriangle, 0) elif redProportion > 0: pygame.draw.polygon(surface, self.red, blueTriangle, 0) else: pygame.draw.polygon(surface, self.grey, blueTriangle, 0) if redProportion > 0: pygame.draw.polygon(surface, self.red, redTriangle, 0) elif blueProportion > 0: pygame.draw.polygon(surface, self.blue, redTriangle, 0) else: pygame.draw.polygon(surface, self.grey, redTriangle, 0) # Draw the team colours if blueProportion > 0: pygame.draw.polygon(surface, self.blue, blueBar, 0) if redProportion > 0: pygame.draw.polygon(surface, self.red, redBar, 0) if neutralProportion > 0 and (blueScore > 0) == (redScore > 0): allNeutral = True pygame.draw.polygon(surface, self.grey, greyBar, 0) else: allNeutral = False # Draw the black seperator line(s) if not gameOver: pygame.draw.line(surface, self.black, (xFirstBar, yTop), (xFirstBar, yBottom), self.width) if neutralScore != 0: pygame.draw.line(surface, self.black, (xSecondBar, yTop), (xSecondBar, yBottom), self.width) # Draw the disruption if disrupt: surface.blit(self.disruptAnimation.getImage(), (self.xFarLeft, self.yTop)) # Draw the border last so that it goes on top colours = self.app.theme.colours pygame.draw.polygon(surface, self.black, border, self.width) pygame.draw.line(surface, colours.minimapBorder, (self.mapLeft, self.mapBottom - 1), (self.mapRight, self.mapBottom - 1), 2) # Define the necessary text self.blueText = TextElement(self.app, '', self.barFont, Location((xFirstBar - 5, yText), 'topright'), colour=colours.black) self.neutralText = TextElement(self.app, '', self.barFont, Location((xNeutral, yText), 'midtop'), colour=colours.black) self.redText = TextElement(self.app, '', self.barFont, Location((xSecondBar + 7, yText), 'topleft'), colour=colours.black) if not disrupt: blueString = self.getScoreText(blueScore) redString = self.getScoreText(redScore) if xSecondBar - xFirstBar > self.neutralTextSpace or allNeutral: neutralString = self.getScoreText(neutralScore) else: neutralString = '' self.blueText.setText(blueString) self.redText.setText(redString) self.neutralText.setText(neutralString) else: self.blueText.setText('') self.redText.setText('') self.neutralText.setText('') # Draw the text self.blueText.draw(surface) self.redText.draw(surface) self.neutralText.draw(surface)
class GameProgressBar(framework.CompoundElement): def __init__(self, app, world, gameViewer): super(GameProgressBar, self).__init__(app) self.world = world self.gameViewer = gameViewer self.app = app self.disrupt = False self.disruptTick = 0 colours = app.theme.colours self.black = colours.black self.blue = colours.team1Mn_zone self.red = colours.team2Mn_zone self.grey = colours.zoneBarNeutral self.barFont = app.screenManager.fonts.zoneBarFont # Define a few constants to make things easier self.triangleLength = 25 self.sideDistance = 0 self.barHeight = self.gameViewer.zoneBarHeight self.textSpace = 130 self.neutralTextSpace = 15 self._oldRect = None self._oldScale = None self.width = None self.mapLeft = None self.mapRight = None self.mapBottom = None self.xFarLeft = None self.xFarRight = None self.xLeft = None self.xRight = None self.yTop = None self.yBottom = None self.disruptAnimation = None self.calculateSize() def calculateSize(self): minimapRect = self.gameViewer.miniMap.getRect() scaleFactor = self.app.screenManager.scaleFactor if minimapRect == self._oldRect and scaleFactor == self._oldScale: return self._oldRect = minimapRect self._oldScale = scaleFactor # Width will always be between 1 and 2 inclusive self.width = min(max(int(3 * scaleFactor), 1), 2) self.mapLeft = minimapRect.left self.mapRight = minimapRect.right self.mapBottom = minimapRect.bottom self.xFarLeft = self.mapLeft + self.sideDistance self.xFarRight = self.mapRight - self.sideDistance self.xLeft = self.xFarLeft + self.triangleLength self.xRight = self.xFarRight - self.triangleLength self.yTop = self.mapBottom - 1 self.yBottom = self.yTop + self.barHeight # Create the disrupted animation self.disruptAnimation = self.createDisrupted() def draw(self, surface): if not self.world.map: return self.calculateSize() super(GameProgressBar, self).draw(surface) if self.disrupt and random.random() < 0.2: disrupt = True else: disrupt = False # Automatically generated constants yTop = self.yTop yBottom = self.yBottom yText = yTop xFarLeft = self.xFarLeft xFarRight = self.xFarRight xLeft = self.xLeft xRight = self.xRight # Define the coordinates for the static shapes border = [ (xFarLeft, yTop), (xFarRight, yTop), (xRight, yBottom), (xLeft, yBottom), ] blueTriangle = [ (xFarLeft, yTop), (xLeft, yTop), (xLeft, yBottom), ] redTriangle = [ (xFarRight, yTop), (xRight, yTop), (xRight, yBottom), ] # Get the information we need blueScore = self.getBlueScore() blueProportion = self.getBlueProportion() redScore = self.getRedScore() redProportion = self.getRedProportion() neutralScore = self.getNeutralScore() neutralProportion = self.getNeutralProportion() gameOver = self.isGameOver() # Define the coordinates for the dynamic shapes mutableBarLength = xRight - xLeft if redProportion > 0: blueBarLength = int(round(mutableBarLength * blueProportion)) else: blueBarLength = mutableBarLength if blueProportion > 0: redBarLength = int(round(mutableBarLength * redProportion)) else: redBarLength = mutableBarLength xNeutral = ((xLeft + blueBarLength) + (xRight - redBarLength)) / 2 xFirstBar = xLeft + blueBarLength xSecondBar = xRight - redBarLength blueBar = [ (xLeft, yTop), (xLeft + blueBarLength, yTop), (xLeft + blueBarLength, yBottom), (xLeft, yBottom), ] redBar = [ (xRight - redBarLength, yTop), (xRight, yTop), (xRight, yBottom), (xRight - redBarLength, yBottom), ] greyBar = [ (xLeft + blueBarLength + 1, yTop), (xRight - redBarLength - 1, yTop), (xRight - redBarLength - 1, yBottom), (xLeft + blueBarLength + 1, yBottom), ] # Draw the two triangles on the sides if blueProportion > 0: pygame.draw.polygon(surface, self.blue, blueTriangle, 0) elif redProportion > 0: pygame.draw.polygon(surface, self.red, blueTriangle, 0) else: pygame.draw.polygon(surface, self.grey, blueTriangle, 0) if redProportion > 0: pygame.draw.polygon(surface, self.red, redTriangle, 0) elif blueProportion > 0: pygame.draw.polygon(surface, self.blue, redTriangle, 0) else: pygame.draw.polygon(surface, self.grey, redTriangle, 0) # Draw the team colours if blueProportion > 0: pygame.draw.polygon(surface, self.blue, blueBar, 0) if redProportion > 0: pygame.draw.polygon(surface, self.red, redBar, 0) if neutralProportion > 0 and (blueScore > 0) == (redScore > 0): allNeutral = True pygame.draw.polygon(surface, self.grey, greyBar, 0) else: allNeutral = False # Draw the black seperator line(s) if not gameOver: pygame.draw.line(surface, self.black, (xFirstBar, yTop), (xFirstBar, yBottom), self.width) if neutralScore != 0: pygame.draw.line(surface, self.black, (xSecondBar, yTop), (xSecondBar, yBottom), self.width) # Draw the disruption if disrupt: surface.blit(self.disruptAnimation.getImage(), (self.xFarLeft, self.yTop)) # Draw the border last so that it goes on top colours = self.app.theme.colours pygame.draw.polygon(surface, self.black, border, self.width) pygame.draw.line(surface, colours.minimapBorder, (self.mapLeft, self.mapBottom - 1), (self.mapRight, self.mapBottom - 1), 2) # Define the necessary text self.blueText = TextElement(self.app, '', self.barFont, Location((xFirstBar - 5, yText), 'topright'), colour=colours.black) self.neutralText = TextElement(self.app, '', self.barFont, Location((xNeutral, yText), 'midtop'), colour=colours.black) self.redText = TextElement(self.app, '', self.barFont, Location((xSecondBar + 7, yText), 'topleft'), colour=colours.black) if not disrupt: blueString = self.getScoreText(blueScore) redString = self.getScoreText(redScore) if xSecondBar - xFirstBar > self.neutralTextSpace or allNeutral: neutralString = self.getScoreText(neutralScore) else: neutralString = '' self.blueText.setText(blueString) self.redText.setText(redString) self.neutralText.setText(neutralString) else: self.blueText.setText('') self.redText.setText('') self.neutralText.setText('') # Draw the text self.blueText.draw(surface) self.redText.draw(surface) self.neutralText.draw(surface) def createDisrupted(self): screens = [] for a in range(0, 4): screen = (pygame.surface.Surface((self.xFarRight - self.xFarLeft, self.gameViewer.zoneBarHeight))) x = y = 0 xL = 1 xR = self.xFarRight - self.xFarLeft - 1 rect = pygame.rect.Rect(0, 0, 2, 2) disruptColours = [self.red, self.blue] while y < self.gameViewer.zoneBarHeight: while x < xR: rect.left = x rect.top = y pygame.draw.rect(screen, random.choice(disruptColours), rect, 0) x += 2 xL += 2 xR -= 2 x = xL y += 2 screen.set_colorkey((0, 0, 0)) screens.append(screen) return Animation(0.1, timeNow, *screens) def getScoreText(self, score): raise NotImplementedError def getBlueScore(self): raise NotImplementedError def getRedScore(self): raise NotImplementedError def getNeutralScore(self): raise NotImplementedError def getBlueProportion(self): raise NotImplementedError def getNeutralProportion(self): raise NotImplementedError def getRedProportion(self): raise NotImplementedError def isGameOver(self): raise NotImplementedError
def __init__(self, app, onClose=None): super(SoundSettingsTab, self).__init__(app, 'Sounds') self.onClose = Event() if onClose is not None: self.onClose.addListener(onClose) font = self.app.screenManager.fonts.bigMenuFont colours = app.theme.colours text = [ TextElement(self.app, 'Music Volume', font, ScaledLocation(400, 285, 'topright'), colours.headingColour), TextElement(self.app, 'Enable Music', font, ScaledLocation(400, 355, 'topright'), colours.headingColour), TextElement(self.app, 'Sound Volume', font, ScaledLocation(400, 425, 'topright'), colours.headingColour), TextElement(self.app, 'Enable Sound', font, ScaledLocation(400, 495, 'topright'), colours.headingColour), ] initVolume = app.soundSettings.musicVolume musicVolumeLabel = TextElement(self.app, '%d' % (initVolume, ), font, ScaledLocation(870, 280, 'topleft'), colours.headingColour) self.musicVolumeSlider = Slider(self.app, ScaledArea(450, 280, 400, 40)) onSlide = lambda volume: musicVolumeLabel.setText('%d' % volume) self.musicVolumeSlider.onSlide.addListener(onSlide) self.musicVolumeSlider.onValueChanged.addListener(onSlide) self.musicVolumeSlider.setVal(initVolume) self.musicBox = CheckBox(self.app, ScaledLocation(450, 360), text='', font=font, colour=(192, 192, 192), initValue=app.soundSettings.musicEnabled) initSndVolume = app.soundSettings.soundVolume soundVolumeLabel = TextElement(self.app, '%d' % (initSndVolume, ), font, ScaledLocation(870, 420, 'topleft'), colours.headingColour) self.soundVolumeSlider = Slider(self.app, ScaledArea(450, 420, 400, 40)) onSlide = lambda volume: soundVolumeLabel.setText('%d' % volume) self.soundVolumeSlider.onSlide.addListener(onSlide) self.soundVolumeSlider.onValueChanged.addListener(onSlide) self.soundVolumeSlider.setVal(initSndVolume) self.soundBox = CheckBox(self.app, ScaledLocation(450, 500), text='', font=font, colour=(192, 192, 192), initValue=app.soundSettings.soundEnabled) self.buttons = [ button(app, 'save', self.saveSettings, (-100, -75), 'midbottom', secondColour=app.theme.colours.white), button(app, 'cancel', self.onClose.execute, (100, -75), 'midbottom', secondColour=app.theme.colours.white) ] self.elements = text + [ musicVolumeLabel, self.musicVolumeSlider, self.musicBox, soundVolumeLabel, self.soundVolumeSlider, self.soundBox ] + self.buttons
def __init__(self, app, onClose=None, onRestart=None): super(ThemeTab, self).__init__(app, 'Themes') self.onClose = Event() if onClose is not None: self.onClose.addListener(onClose) self.onRestart = Event() if onRestart is not None: self.onRestart.addListener(onRestart) font = self.app.screenManager.fonts.menuFont colours = self.app.theme.colours self.inactiveTheme = False self.originalTheme = app.theme.name # Static text self.staticText = [ TextElement(self.app, 'theme information:', font, ScaledLocation(960, 250, 'topright'), colours.headingColour), TextElement(self.app, 'theme contents:', font, ScaledLocation(960, 390, 'topright'), colours.headingColour) ] # Dynamic text self.feedbackText = TextElement( self.app, 'Your current theme: %s' % (app.theme.name, ), font, ScaledLocation(512, 200, 'midtop'), colours.startButton) self.listHeaderText = TextElement(self.app, 'available themes:', font, ScaledLocation(70, 250), colours.headingColour) self.themeNameText = TextElement(self.app, 'Default Theme', font, ScaledLocation(960, 290, 'topright'), colours.startButton) self.themeAuthorText = TextElement( self.app, 'created by: Trosnoth Team', font, ScaledLocation(960, 330, 'topright'), colours.startButton) self.contents = [] numContents = 4 for yPos in range(430, 430 + numContents * 40 + 1, 40): self.contents.append( TextElement(self.app, '', font, ScaledLocation(960, yPos, 'topright'), colours.startButton)) self.dynamicText = [ self.feedbackText, self.listHeaderText, self.themeNameText, self.themeAuthorText ] + self.contents # Theme list self.themeList = ListBox(self.app, ScaledArea(70, 290, 400, 290), [], font, colours.listboxButtons) self.themeList.onValueChanged.addListener(self.updateSidebar) # Text buttons self.useThemeButton = button(app, 'use selected theme', self.applyTheme, (0, -125), 'midbottom') self.refreshButton = button(app, 'refresh', self.populateList, (-100, -75), 'midbottom') self.cancelButton = button(app, 'cancel', self.backToMain, (100, -75), 'midbottom') self.restartButton = button(app, 'restart Trosnoth', self.restart, (0, -125), 'midbottom') self.buttons = [ self.useThemeButton, self.refreshButton, self.cancelButton, self.restartButton ] # Combine the elements self.elements = self.staticText + self.dynamicText + self.buttons + [ self.themeList ] self.contentTypes = { "sprites": "sprite", "blocks": "map block", "fonts": "font", "startupMenu": "backdrop" } # Populate the list of replays self.populateList()
def __init__(self, app, width=2, height=1): super(MapSizeBox, self).__init__(app, ScaledSize(400, 230), "Custom Size") labelFont = app.screenManager.fonts.bigMenuFont labelColour = app.theme.colours.dialogBoxTextColour btnFont = app.screenManager.fonts.bigMenuFont btnColour = app.theme.colours.dialogButtonColour highlightColour = app.theme.colours.black inputFont = app.screenManager.fonts.defaultTextBoxFont inputColour = app.theme.colours.grey self.widthBox = InputBox(app, Region(midleft=self.Relative(0.65, 0.25), size=self.Relative(0.15, 0.2)), str(width), font=inputFont, colour=inputColour, onClick=self.setFocus, onEnter=self.okClicked, validator=intValidator, maxLength=2) self.heightBox = InputBox(app, Region(midleft=self.Relative(0.65, 0.55), size=self.Relative(0.15, 0.2)), str(height), font=inputFont, colour=inputColour, onClick=self.setFocus, onEnter=self.okClicked, validator=intValidator, maxLength=2) # Add elements to screen self.elements = [ TextElement(app, 'Half Width:', labelFont, Location(self.Relative(0.6, 0.25), 'midright'), labelColour), self.widthBox, TextElement(app, 'Height:', labelFont, Location(self.Relative(0.6, 0.55), 'midright'), labelColour), self.heightBox, TextButton(app, Location(self.Relative(0.3, 0.9), 'center'), 'Ok', btnFont, btnColour, highlightColour, onClick=self.okClicked), TextButton(app, Location(self.Relative(0.7, 0.9), 'center'), 'Cancel', btnFont, btnColour, highlightColour, onClick=self.cancelClicked), ] self.tabOrder = [self.widthBox, self.heightBox] self.setFocus(self.widthBox)
class ThemeTab(Tab, framework.TabFriendlyCompoundElement): def __init__(self, app, onClose=None, onRestart=None): super(ThemeTab, self).__init__(app, 'Themes') self.onClose = Event() if onClose is not None: self.onClose.addListener(onClose) self.onRestart = Event() if onRestart is not None: self.onRestart.addListener(onRestart) font = self.app.screenManager.fonts.menuFont colours = self.app.theme.colours self.inactiveTheme = False self.originalTheme = app.theme.name # Static text self.staticText = [ TextElement(self.app, 'theme information:', font, ScaledLocation(960, 250, 'topright'), colours.headingColour), TextElement(self.app, 'theme contents:', font, ScaledLocation(960, 390, 'topright'), colours.headingColour) ] # Dynamic text self.feedbackText = TextElement( self.app, 'Your current theme: %s' % (app.theme.name, ), font, ScaledLocation(512, 200, 'midtop'), colours.startButton) self.listHeaderText = TextElement(self.app, 'available themes:', font, ScaledLocation(70, 250), colours.headingColour) self.themeNameText = TextElement(self.app, 'Default Theme', font, ScaledLocation(960, 290, 'topright'), colours.startButton) self.themeAuthorText = TextElement( self.app, 'created by: Trosnoth Team', font, ScaledLocation(960, 330, 'topright'), colours.startButton) self.contents = [] numContents = 4 for yPos in range(430, 430 + numContents * 40 + 1, 40): self.contents.append( TextElement(self.app, '', font, ScaledLocation(960, yPos, 'topright'), colours.startButton)) self.dynamicText = [ self.feedbackText, self.listHeaderText, self.themeNameText, self.themeAuthorText ] + self.contents # Theme list self.themeList = ListBox(self.app, ScaledArea(70, 290, 400, 290), [], font, colours.listboxButtons) self.themeList.onValueChanged.addListener(self.updateSidebar) # Text buttons self.useThemeButton = button(app, 'use selected theme', self.applyTheme, (0, -125), 'midbottom') self.refreshButton = button(app, 'refresh', self.populateList, (-100, -75), 'midbottom') self.cancelButton = button(app, 'cancel', self.backToMain, (100, -75), 'midbottom') self.restartButton = button(app, 'restart Trosnoth', self.restart, (0, -125), 'midbottom') self.buttons = [ self.useThemeButton, self.refreshButton, self.cancelButton, self.restartButton ] # Combine the elements self.elements = self.staticText + self.dynamicText + self.buttons + [ self.themeList ] self.contentTypes = { "sprites": "sprite", "blocks": "map block", "fonts": "font", "startupMenu": "backdrop" } # Populate the list of replays self.populateList() def populateList(self): defaultTheme = { "name": "Default Theme", "filename": "default", "author": "Trosnoth Team", "content": None, "source": "internal" } # Clear out the sidebar self.themeNameText.setText('') self.themeAuthorText.setText('') for element in self.contents: element.setText('') self.useThemeButton.setText('') self.restartButton.setText('') self.listHeaderText.setText('available themes:') self.themeList.index = -1 userThemeDir = getPath(user, 'themes') internalThemeDir = getPath(themes) makeDirs(userThemeDir) themeList = [] # Get a list of internal themes for dirName in os.listdir(internalThemeDir): if os.path.isdir(os.path.join(internalThemeDir, dirName)): themeList.append("i/%s" % dirName) # Get a list of user-defined themes for dirName in os.listdir(userThemeDir): if os.path.isdir(os.path.join(userThemeDir, dirName)): # Internal themes overrule user-defined themes if "i/" + dirName not in themeList and dirName != "default": themeList.append("u/%s" % dirName) # Assume all themes are valid for now validThemes = themeList[:] self.themeInfo = {} for themeName in themeList: themeInfo = {"content": {}} if themeName.startswith("i/"): themeInfo['source'] = 'internal' directory = internalThemeDir else: themeInfo['source'] = 'user-defined' directory = userThemeDir themeNameList = themeName themeName = themeName[2:] themeInfo['filename'] = themeName[2:] anyContent = False for contentType in list(self.contentTypes.keys()): if themeInfo['source'] == 'internal': contentDir = os.path.join(directory, themeName, contentType) else: contentDir = os.path.join(directory, themeName, contentType) if not os.path.isdir(contentDir): continue else: fileCount = len([ f for f in os.listdir(contentDir) if os.path.isfile(os.path.join(contentDir, f)) ]) if fileCount > 0: anyContent = True themeInfo["content"][contentType] = fileCount if not anyContent: validThemes.remove(themeNameList) continue infoFile = os.path.join(directory, themeName, "info.txt") if os.path.isfile(infoFile): infoFile = open(infoFile) infoContents = infoFile.readlines() else: infoContents = [] if len(infoContents) >= 2: themeInfo["author"] = infoContents[1].strip() else: themeInfo["author"] = None if len(infoContents) >= 1: themeInfo["name"] = infoContents[0].strip() else: themeInfo["name"] = themeName self.themeInfo[themeName] = themeInfo self.themeInfo["default"] = defaultTheme # Sort the themes alphabetically items = [(v['filename'], n) for n, v in self.themeInfo.items()] items.sort() items = [n for v, n in items] self.themeList.setItems(items) if len(self.themeInfo) == 1: self.listHeaderText.setText("1 available theme:") self.themeList.index = 0 self.updateSidebar(0) else: self.listHeaderText.setText("%d available themes:" % len(self.themeInfo)) def updateSidebar(self, listID): # Update the details on the sidebar displayName = self.themeList.getItem(listID) themeInfo = self.themeInfo[displayName] if themeInfo['source'] == "internal": self.themeNameText.setText(themeInfo['name'] + " (built-in)") else: self.themeNameText.setText(themeInfo['name']) if themeInfo['author'] is not None: self.themeAuthorText.setText("by " + themeInfo['author']) else: self.themeAuthorText.setText("(creator unknown)") if themeInfo['content'] is None: for element in self.contents: element.setText('') self.contents[0].setText('N/A') else: count = 0 for k, v in themeInfo['content'].items(): suffix = "" if v != 1: suffix = "s" text = "%d %s%s" % (v, self.contentTypes[k], suffix) self.contents[count].setText(text) count += 1 self.restartButton.setText("") if self.app.displaySettings.theme != displayName: if displayName == self.originalTheme: self.useThemeButton.setText("revert back to this theme") else: self.useThemeButton.setText("use this theme") else: self.useThemeButton.setText("") if self.inactiveTheme: self.restartButton.setText('restart Trosnoth') def applyTheme(self): themeName = self.themeList.getItem(self.themeList.index) self.app.displaySettings.theme = themeName self.app.displaySettings.save() self.useThemeButton.setText("") if themeName != self.originalTheme: self.feedbackText.setText("You must restart Trosnoth for the " "'%s' theme to take effect." % themeName) self.restartButton.setText('restart Trosnoth') self.inactiveTheme = True else: self.feedbackText.setText('Your current theme: %s' % (self.app.theme.name, )) self.restartButton.setText("") self.inactiveTheme = False def restart(self): self.onRestart.execute() def backToMain(self): if self.inactiveTheme: self.feedbackText.setText("Your current theme: %s " "(restart required)" % self.app.displaySettings.theme) self.onClose.execute() def draw(self, surface): super(ThemeTab, self).draw(surface) width = max(int(3 * self.app.screenManager.scaleFactor), 1) scalePoint = self.app.screenManager.placePoint pygame.draw.line(surface, self.app.theme.colours.mainMenuColour, scalePoint((512, 260)), scalePoint((512, 580)), width)
class ChatBox(framework.CompoundElement): def __init__(self, app, world, interface): super(ChatBox, self).__init__(app) self.world = world self.app = app self.interface = interface self.font = self.app.screenManager.fonts.newChatFont self.frameColour = self.app.theme.colours.chatFrameColour self.insideColour = self.app.theme.colours.chatInsideColour self.textColour = self.app.theme.colours.chatNormalColour self.sayToTeam = TextElement( self.app, text="Say to team:", font=self.font, pos=Location(FullScreenAttachedPoint((20, 501), 'topleft'), 'topleft'), colour=self.textColour, shadow=True, ) self.inputPosition = Area( FullScreenAttachedPoint((145, 500), 'topleft'), (370, 20), 'topleft') self.input = InputBox(self.app, self.inputPosition, font=self.font) self.input.onEnter.addListener( lambda sender: self.hitEnter(sender.value)) self.input.onEsc.addListener(lambda sender: self.close()) self.input.onClick.addListener(self.setFocus) self.messages = MessageBank( self.app, 10, 100, Location(FullScreenAttachedPoint((20, 470), 'topleft'), 'topleft'), 'left', 'bottom', self.font) self._chatOpen = False self.teamChat = True self.player = None self.messageBuffer = [] self.MESSAGE_GAP = self.font.getHeight(self.app) self.elements = [self.messages] def setPlayer(self, player): self.player = player if self.player.team is None: self.refreshMode() def canTeamChat(self): return self.player and self.player.team is not None def switchModes(self): self.teamChat = not self.teamChat self.refreshMode() def refreshMode(self): self.teamChat = self.teamChat and self.canTeamChat() if self.teamChat: self.sayToTeam.setText('Say to team:') else: self.sayToTeam.setText('Say to all:') def hitEnter(self, senderValue): if senderValue.strip() != '': self.sendChat(senderValue) self.input.clear() def sendChat(self, senderValue): # Interpret lines with initial hash. if senderValue.startswith('#'): i = 1 while senderValue[i:i + 1].isdigit(): i += 1 try: playerId = bytes([int(senderValue[1:i])]) except ValueError: pass else: self.interface.sendPrivateChat(self.player, playerId, senderValue[i:].lstrip()) return if self.teamChat: self.interface.sendTeamChat(self.player, senderValue) else: self.interface.sendPublicChat(self.player, senderValue) def refresh(self): if not self.isOpen(): return self.elements = [self.sayToTeam, self.input] initialY = 470 count = 0 for text, nick, colour, firstLine in reversed(self.messageBuffer): currentY = initialY - count * self.MESSAGE_GAP if currentY < 200 or count >= 10: break if firstLine and nick is not None: person = TextElement( self.app, text=nick, font=self.font, pos=Location( FullScreenAttachedPoint((20, currentY), 'topleft'), 'topleft'), colour=colour, shadow=True, ) xOffset = person._getRect().width self.elements.append(person) text = text[len(nick):] else: xOffset = 0 if nick is None: colour = self.app.theme.colours.serverChat else: colour = self.textColour message = TextElement( self.app, text=text, font=self.font, pos=Location( FullScreenAttachedPoint((20 + xOffset, currentY), 'topleft'), 'topleft'), colour=colour, shadow=True, ) self.elements.append(message) count += 1 def open(self): self._chatOpen = True self.refresh() self.setFocus(self.input) self.input.clear() def close(self): self._chatOpen = False self.elements = [self.messages] pygame.key.set_repeat() def isOpen(self): return self._chatOpen def newMessage(self, message, nick, colour): message = nick + message wrappedMessage = wrapline(message, self.font._getFont(self.app), 480) # Update the "box open" message elements firstLine = True for line in wrappedMessage: self.messageBuffer.append((line, nick, colour, firstLine)) firstLine = False while len(self.messageBuffer) > 100: self.messageBuffer.pop(0) # Update the "box closed" message elements firstLine = wrappedMessage.pop(0)[len(nick):] parts = [(nick, colour), (firstLine, self.textColour)] self.messages.newColourMessage(parts) for line in wrappedMessage: self.messages.newMessage(line, self.textColour) self.refresh() def newServerMessage(self, message): '''Server messages don't follow the format of normal messages and require special attention to display.''' colour = self.app.theme.colours.serverChat wrappedMessage = wrapline("SERVER" + message, self.font._getFont(self.app), 480) # Update the "box open" message elements firstLine = True for line in wrappedMessage: self.messageBuffer.append((line, None, colour, firstLine)) firstLine = False while len(self.messageBuffer) > 100: self.messageBuffer.remove(0) # Update the "box closed" message elements for line in wrappedMessage: self.messages.newMessage(line, colour) self.refresh() def _getRect(self): return self.area.getRect(self.app) def draw(self, surface): if self._chatOpen: pointX = 5 pointY = 300 # Draw the frame first frame = pygame.Surface((520, 230)) frame.fill(self.frameColour) mainBox = pygame.Surface((500, 180)) mainBox.fill(self.insideColour) sayBox = pygame.Surface((120, 20)) sayBox.fill(self.insideColour) if self.app.displaySettings.alphaOverlays: mainBox.set_alpha(128) sayBox.set_alpha(128) frame.set_alpha(128) surface.blit(frame, (pointX, pointY)) surface.blit(mainBox, (pointX + 10, pointY + 10)) surface.blit(sayBox, (pointX + 10, pointY + 200)) super(ChatBox, self).draw(surface) def processEvent(self, event): if not self.isOpen(): return event if event.type == pygame.KEYDOWN and event.key in (pygame.K_LCTRL, pygame.K_RCTRL): self.switchModes() else: return self.input.processEvent(event)