Ejemplo n.º 1
0
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'))
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
class DisplaySettingsTab(Tab, framework.TabFriendlyCompoundElement):
    def __init__(self, app, onClose=None):
        super(DisplaySettingsTab, self).__init__(app, 'Display')

        self.onClose = Event()
        if onClose is not None:
            self.onClose.addListener(onClose)

        font = self.app.screenManager.fonts.bigMenuFont
        smallNoteFont = self.app.screenManager.fonts.smallNoteFont

        colour = self.app.theme.colours.headingColour

        def mkText(text, x, y, textFont=font, anchor='topright'):
            return TextElement(self.app, text, textFont,
                               ScaledLocation(x, y, anchor), colour)

        self.text = [
            mkText('X', 640, 280),
            mkText('Screen resolution', 430, 280),
            mkText('Fullscreen mode', 430, 360),
            mkText('Graphics detail', 430, 440),
            mkText('low', 460, 475, textFont=smallNoteFont, anchor='midtop'),
            mkText('high', 845, 475, textFont=smallNoteFont, anchor='midtop'),
            mkText('Show timings', 430, 525),
        ]

        self.invalidInputText = TextElement(self.app, '', font,
                                            ScaledLocation(512, 230, 'midtop'),
                                            (192, 0, 0))

        self.widthInput = prompt.InputBox(self.app,
                                          ScaledArea(460, 265, 150, 60),
                                          initValue=str(
                                              self.app.screenManager.size[0]),
                                          font=font,
                                          maxLength=4,
                                          validator=prompt.intValidator)

        self.widthInput.onEnter.addListener(lambda sender: self.saveSettings())
        self.widthInput.onClick.addListener(self.setFocus)
        self.widthInput.onTab.addListener(self.tabNext)

        self.heightInput = prompt.InputBox(self.app,
                                           ScaledArea(652, 265, 150, 60),
                                           initValue=str(
                                               self.app.screenManager.size[1]),
                                           font=font,
                                           maxLength=4,
                                           validator=prompt.intValidator)

        self.heightInput.onEnter.addListener(
            lambda sender: self.saveSettings())
        self.heightInput.onClick.addListener(self.setFocus)
        self.heightInput.onTab.addListener(self.tabNext)

        self.tabOrder = [self.widthInput, self.heightInput]

        self.fullscreenBox = CheckBox(
            self.app,
            ScaledLocation(460, 365),
            text='',
            font=font,
            colour=(192, 192, 192),
            initValue=self.app.screenManager.isFullScreen(),
        )
        self.fullscreenBox.onValueChanged.addListener(self.fullscreenChanged)

        displaySettings = app.displaySettings

        self.detailSlider = Slider(
            self.app,
            ScaledArea(460, 430, 390, 40),
            bounds=(0, len(displaySettings.DETAIL_LEVELS) - 1),
            snap=True)
        self.detailSlider.setVal(
            displaySettings.DETAIL_LEVELS.index(displaySettings.detailLevel))
        self.detailSlider.onValueChanged.addListener(self.detailChanged)

        self.showTimingsBox = CheckBox(
            self.app,
            ScaledLocation(460, 530),
            text='',
            font=font,
            colour=(192, 192, 192),
            initValue=displaySettings.showTimings,
        )

        self.input = [
            self.widthInput, self.heightInput, self.widthInput,
            self.fullscreenBox, self.detailSlider, self.showTimingsBox
        ]

        self.elements = self.text + self.input + [
            self.invalidInputText,
            button(app,
                   'save',
                   self.saveSettings, (-100, -75),
                   'midbottom',
                   secondColour=app.theme.colours.white),
            button(app,
                   'cancel',
                   self.cancelMenu, (100, -75),
                   'midbottom',
                   secondColour=app.theme.colours.white),
        ]
        self.setFocus(self.widthInput)

    def detailChanged(self, newLevel):
        pass

    def cancelMenu(self):
        self.fullscreenBox.setValue(self.app.screenManager.isFullScreen())
        self.showTimingsBox.setValue(self.app.displaySettings.showTimings)
        self.heightInput.setValue(str(self.app.screenManager.size[1]))
        self.widthInput.setValue(str(self.app.screenManager.size[0]))

        self.onClose.execute()

    def saveSettings(self):
        displaySettings = self.app.displaySettings

        height = self.getInt(self.heightInput.value)
        width = self.getInt(self.widthInput.value)
        fullScreen = self.fullscreenBox.value
        detailLevel = displaySettings.DETAIL_LEVELS[self.detailSlider.getVal()]
        showTimings = self.showTimingsBox.value

        # The resolutionList is used when fullScreen is true.
        resolutionList = pygame.display.list_modes()
        resolutionList.sort()
        minResolution = resolutionList[0]
        maxResolution = resolutionList[-1]

        if not fullScreen:
            minResolution = (320, 240)

        # These values are used when fullScreen is false.
        widthRange = (minResolution[0], maxResolution[0])
        heightRange = (minResolution[1], maxResolution[1])

        if not widthRange[0] <= width <= widthRange[1]:
            self.incorrectInput('Screen width must be between %d and %d' %
                                (widthRange[0], widthRange[1]))
            width = None
            return
        if not heightRange[0] <= height <= heightRange[1]:
            self.incorrectInput('Screen height must be between %d and %d' %
                                (heightRange[0], heightRange[1]))
            height = None
            return
        if fullScreen:
            selectedResolution = (width, height)
            if selectedResolution not in resolutionList:
                self.incorrectInput('Selected resolution is not valid for '
                                    'this display')
                height = width = None
                return

        self.incorrectInput('')

        # Save these values.
        displaySettings.fullScreen = fullScreen
        displaySettings.detailLevel = detailLevel
        displaySettings.showTimings = showTimings
        if fullScreen:
            displaySettings.fsSize = (width, height)
        else:
            displaySettings.size = (width, height)

        # Write to file and apply.
        displaySettings.save()
        displaySettings.apply()

        self.onClose.execute()

    def getInt(self, value):
        if value == '':
            return 0
        return int(value)

    def incorrectInput(self, string):
        self.invalidInputText.setText(string)
        self.invalidInputText.setFont(self.app.screenManager.fonts.bigMenuFont)

    def fullscreenChanged(self, element):
        # If the resolution boxes haven't been touched, swap their values to
        # the appropriate resolution for the new mode.

        height = self.getInt(self.heightInput.value)
        width = self.getInt(self.widthInput.value)
        fullScreen = self.fullscreenBox.value

        if fullScreen:
            # Going to full screen mode.
            if (width, height) != self.app.displaySettings.size:
                return
            width, height = self.app.displaySettings.fsSize
        else:
            # Going from full screen mode.
            if (width, height) != self.app.displaySettings.fsSize:
                return
            width, height = self.app.displaySettings.size

        self.heightInput.setValue(str(height))
        self.widthInput.setValue(str(width))
Ejemplo n.º 4
0
class KeymapTab(Tab):
    def __init__(self, app, onClose=None):
        super(KeymapTab, self).__init__(app, 'Controls')
        self.font = app.screenManager.fonts.bigMenuFont

        self.onClose = Event()
        if onClose is not None:
            self.onClose.addListener(onClose)

        # Break things up into categories
        movement = ['jump', 'down', 'left', 'right']
        menus = ['menu', 'more actions']
        actions = [
            'respawn', 'select upgrade', 'activate upgrade', 'change nickname',
            'ready'
        ]
        misc = ['chat', 'follow']
        upgrades = [
            upgradeClass.action for upgradeClass in sorted(
                allUpgrades, key=lambda upgradeClass: upgradeClass.order)
        ]
        upgrades.append('no upgrade')

        display = ['leaderboard', 'toggle interface', 'toggle terminal']

        actionNames = {
            'select upgrade': 'Select upgrade',
            'activate upgrade': 'Activate upgrade',
            'change nickname': 'Change nickname',
            'chat': 'Chat',
            'down': 'Drop down',
            'follow': 'Auto pan (replay)',
            'jump': 'Jump',
            'leaderboard': 'Show leaderboard',
            'left': 'Move left',
            'menu': 'Main menu',
            'more actions': 'Advanced',
            'no upgrade': 'Deselect upgrade',
            'ready': 'Toggle ready',
            'respawn': 'Respawn',
            'right': 'Move right',
            'status bar': 'Status bar',
            'timer': 'Show timer',
            'toggle interface': 'Toggle HUD',
            'toggle terminal': 'Toggle terminal',
            'zone progress': 'Show zone bar',
        }
        actionNames.update((upgradeClass.action, upgradeClass.name)
                           for upgradeClass in allUpgrades)

        # Organise the categories by column
        self.layout = [
            [movement, menus],
            [actions, display],
            [upgrades, misc],
        ]

        self.errorInfo = TextElement(self.app, '', self.font,
                                     ScaledLocation(512, 580, 'center'))
        self.text = [self.errorInfo]
        self.inputLookup = {}
        xPos = 190

        # Lay everything out automatically.
        keymapFont = self.app.screenManager.fonts.keymapFont
        keymapInputFont = self.app.screenManager.fonts.keymapInputFont
        for column in self.layout:  # Each column
            yPos = 200
            for category in column:  # Each category
                for action in category:  # Each action
                    # Draw action name (eg. Respawn)
                    self.text.append(
                        TextElement(self.app, actionNames[action], keymapFont,
                                    ScaledLocation(xPos, yPos + 6, 'topright'),
                                    self.app.theme.colours.headingColour))

                    # Create input box
                    box = prompt.KeycodeBox(self.app,
                                            ScaledArea(xPos + 10, yPos, 100,
                                                       30),
                                            font=keymapInputFont)
                    box.onClick.addListener(self.setFocus)
                    box.onChange.addListener(self.inputChanged)
                    box.__action = action
                    self.inputLookup[action] = box

                    yPos += 35  # Between items
                yPos += 35  # Between categories
            xPos += 320  # Between columns

        self.elements = self.text + self.inputLookup.values() + [
            button(app,
                   'restore default controls',
                   self.restoreDefaults, (0, -125),
                   'midbottom',
                   secondColour=app.theme.colours.white),
            button(app,
                   'save',
                   self.saveSettings, (-100, -75),
                   'midbottom',
                   secondColour=app.theme.colours.white),
            button(app,
                   'cancel',
                   self.cancel, (100, -75),
                   'midbottom',
                   secondColour=app.theme.colours.white),
        ]

        self.populateInputs()

    def inputChanged(self, box):
        # Remove the old key.
        try:
            oldKey = self.keyMapping.getkey(box.__action)
        except KeyError:
            pass
        else:
            del self.keyMapping[oldKey]

        # Set the new key.
        self.keyMapping[box.value] = box.__action

        # Refresh the display.
        self.refreshInputs()

    def populateInputs(self):
        # Set up the keyboard mapping.
        self.keyMapping = keyboard.KeyboardMapping(keymap.default_game_keys)

        try:
            # Try to load keyboard mappings from the user's personal settings.
            config = open(getPath(user, 'keymap'), 'rU').read()
            self.keyMapping.load(config)
        except IOError:
            pass

        # Refresh the display.
        self.refreshInputs()

    def refreshInputs(self):
        for column in self.layout:
            for category in column:
                for action in category:
                    # Get the current key and put it in the box.
                    try:
                        key = self.keyMapping.getkey(action)
                    except KeyError:
                        key = None
                    self.inputLookup[action].value = key

                    # Make the box white
                    self.inputLookup[action].backColour = (255, 255, 255)

    def restoreDefaults(self):
        self.keyMapping = keyboard.KeyboardMapping(keymap.default_game_keys)
        self.refreshInputs()

        self.incorrectInput(
            "Default controls restored: press 'save' to "
            "confirm", (0, 128, 0))

    def clearBackgrounds(self):
        for action in self.inputLookup:
            self.inputLookup[action].backColour = (255, 255, 255)
        self.setFocus(None)

    def saveSettings(self):
        # Perform the save.
        open(getPath(user, 'keymap'), 'w').write(self.keyMapping.save())

        emptyBoxes = []

        for box in self.inputLookup.itervalues():
            if box.value is None:
                emptyBoxes.append(box)

        if len(emptyBoxes) > 0:
            self.populateInputs()
            for box in emptyBoxes:
                box.backColour = self.app.theme.colours.invalidDataColour

            self.incorrectInput('Warning: some actions have no key',
                                (192, 0, 0))
        else:
            self.mainMenu()

    def incorrectInput(self, string, colour):
        self.errorInfo.setColour(colour)
        self.errorInfo.setText(string)
        self.errorInfo.setFont(self.font)

    def cancel(self):
        self.populateInputs()
        self.mainMenu()

    def mainMenu(self):
        self.incorrectInput('', (0, 0, 0))
        self.clearBackgrounds()
        self.onClose.execute()
Ejemplo n.º 5
0
class KeymapTab(Tab):
    def __init__(self, app, onClose=None):
        super(KeymapTab, self).__init__(app, 'Controls')
        self.font = app.screenManager.fonts.bigMenuFont

        self.onClose = Event()
        if onClose is not None:
            self.onClose.addListener(onClose)

        # Break things up into categories
        movement = [
            ACTION_JUMP, ACTION_DOWN, ACTION_LEFT, ACTION_RIGHT, ACTION_HOOK
        ]
        menus = [ACTION_MAIN_MENU, ACTION_MORE_MENU]
        actions = [
            ACTION_UPGRADE_MENU, ACTION_USE_UPGRADE, ACTION_EDIT_PLAYER_INFO,
            ACTION_READY, ACTION_SHOW_TRAJECTORY, ACTION_EMOTE
        ]
        misc = [ACTION_CHAT, ACTION_FOLLOW]
        upgrades = [
            upgradeClass.action for upgradeClass in sorted(
                allUpgrades, key=lambda upgradeClass: upgradeClass.order)
        ]
        upgrades.append(ACTION_CLEAR_UPGRADE)

        display = [
            ACTION_LEADERBOARD_TOGGLE, ACTION_HUD_TOGGLE,
            ACTION_TERMINAL_TOGGLE
        ]

        actionNames = {
            ACTION_EDIT_PLAYER_INFO: 'Change nick / hat',
            ACTION_CHAT: 'Chat',
            ACTION_CLEAR_UPGRADE: 'Deselect upgrade',
            ACTION_DOWN: 'Drop down',
            ACTION_FOLLOW: 'Auto pan (replay)',
            ACTION_HOOK: 'Grappling hook',
            ACTION_HUD_TOGGLE: 'Toggle HUD',
            ACTION_JUMP: 'Jump',
            ACTION_LEADERBOARD_TOGGLE: 'Show leaderboard',
            ACTION_LEFT: 'Move left',
            ACTION_MAIN_MENU: 'Main menu',
            ACTION_MORE_MENU: 'Advanced',
            ACTION_READY: 'Toggle ready',
            ACTION_RIGHT: 'Move right',
            ACTION_TERMINAL_TOGGLE: 'Toggle terminal',
            ACTION_UPGRADE_MENU: 'Select upgrade',
            ACTION_USE_UPGRADE: 'Activate upgrade',
            ACTION_SHOW_TRAJECTORY: 'Show trajectory',
            ACTION_EMOTE: 'Emote',
        }
        actionNames.update((upgradeClass.action, upgradeClass.name)
                           for upgradeClass in allUpgrades)

        # Organise the categories by column
        self.layout = [
            [movement, menus],
            [actions, display],
            [upgrades, misc],
        ]

        self.errorInfo = TextElement(self.app, '', self.font,
                                     ScaledLocation(512, 580, 'center'))
        self.text = [self.errorInfo]
        self.inputLookup = {}
        xPos = 210

        # Lay everything out automatically.
        keymapFont = self.app.screenManager.fonts.keymapFont
        keymapInputFont = self.app.screenManager.fonts.keymapInputFont
        for column in self.layout:  # Each column
            yPos = 200
            for category in column:  # Each category
                for action in category:  # Each action
                    # Draw action name (eg. Respawn)
                    self.text.append(
                        TextElement(self.app, actionNames[action], keymapFont,
                                    ScaledLocation(xPos, yPos + 6, 'topright'),
                                    self.app.theme.colours.headingColour))

                    # Create input box
                    box = prompt.KeycodeBox(self.app,
                                            ScaledArea(xPos + 10, yPos, 100,
                                                       30),
                                            font=keymapInputFont,
                                            acceptMouse=True)
                    box.onClick.addListener(self.setFocus)
                    box.onChange.addListener(self.inputChanged)
                    box.__action = action
                    self.inputLookup[action] = box

                    yPos += 35  # Between items
                yPos += 35  # Between categories
            xPos += 310  # Between columns

        self.elements = self.text + list(self.inputLookup.values()) + [
            button(app,
                   'restore default controls',
                   self.restoreDefaults, (0, -125),
                   'midbottom',
                   secondColour=app.theme.colours.white),
            button(app,
                   'save',
                   self.saveSettings, (-100, -75),
                   'midbottom',
                   secondColour=app.theme.colours.white),
            button(app,
                   'cancel',
                   self.cancel, (100, -75),
                   'midbottom',
                   secondColour=app.theme.colours.white),
        ]

        self.populateInputs()

    def inputChanged(self, box):
        # Remove the old key.
        try:
            oldKey = self.keyMapping.getkey(box.__action)
        except KeyError:
            pass
        else:
            del self.keyMapping[oldKey]

        # Set the new key.
        self.keyMapping[box.value] = box.__action

        # Refresh the display.
        self.refreshInputs()

    def populateInputs(self):
        # Set up the keyboard mapping.
        self.keyMapping = keyboard.KeyboardMapping(keymap.default_game_keys)

        try:
            # Try to load keyboard mappings from the user's personal settings.
            with open(getPath(user, 'keymap'), 'r') as f:
                config = f.read()
            self.keyMapping.load(config)
        except IOError:
            pass

        # Refresh the display.
        self.refreshInputs()

    def refreshInputs(self):
        for column in self.layout:
            for category in column:
                for action in category:
                    # Get the current key and put it in the box.
                    try:
                        key = self.keyMapping.getkey(action)
                    except KeyError:
                        key = None
                    self.inputLookup[action].value = key

                    # Make the box white
                    self.inputLookup[action].backColour = (255, 255, 255)

    def restoreDefaults(self):
        self.keyMapping = keyboard.KeyboardMapping(keymap.default_game_keys)
        self.refreshInputs()

        self.showMessage(
            "Default controls restored: press 'save' to "
            "confirm", (0, 128, 0))

    def clearBackgrounds(self):
        for action in self.inputLookup:
            self.inputLookup[action].backColour = (255, 255, 255)
        self.setFocus(None)

    def saveSettings(self):
        # Perform the save.
        open(getPath(user, 'keymap'), 'w').write(self.keyMapping.save())
        self.mainMenu()

    def showMessage(self, string, colour):
        self.errorInfo.setColour(colour)
        self.errorInfo.setText(string)
        self.errorInfo.setFont(self.font)

    def cancel(self):
        self.populateInputs()
        self.mainMenu()

    def mainMenu(self):
        self.showMessage('', (0, 0, 0))
        self.clearBackgrounds()
        self.onClose.execute()