Beispiel #1
0
    def effectHook(self):
        """ we need to manipulate the two selected items """
        if len(self.selected) != 2:
            msg = "You have to select the two objects to join together."
            log.outMsg(msg)
            return False

        # check that the objects are paths or rectangles
        for node in self.selected.values():
            if node.tag not in [addNS('path', 'svg'), addNS('rect', 'svg')]:
                msg = "You need to select path and rectangle only."
                log.outMsg(msg)
                return False
            label = XmNode(node).getParsedLabel()
            createIfAbsent(label, 'position')
            if 'physics' not in label['position']:
                msg = "The selected objects has to be Xmoto physics blocks."
                log.outMsg(msg)
                return False

        block1Id = self.options.ids[0]
        block2Id = self.options.ids[1]

        anchorId = block1Id + block2Id + '_joint_' + self.jointType
        parentNode = self.selected[block1Id].getparent()
        anchorNode = self.createJointNode(parentNode, anchorId,
                                          self.selected[block1Id],
                                          self.selected[block2Id])

        label, style = self.getLabelAndStyle(block1Id, block2Id)
        self.updateNodeSvgAttributes(anchorNode, label, style)

        return False
Beispiel #2
0
    def parse(self, svgFile):
        document = etree.parse(svgFile)

        # there is a main svg node in a svg file
        dom_svg = document.getroot()

        # the main svg node has width and height attributes
        attrs = dom_svg.attrib
        width = UnitsConvertor(attrs['width']).convert('px')
        height = UnitsConvertor(attrs['height']).convert('px')

        levelOptions = dom_svg.xpath('//dc:description', namespaces=NSS)
        if levelOptions is not None and len(levelOptions) > 0:
            description = self.getNodeText(levelOptions[0])
        else:
            description = None

        labelParser = Factory().create('label_parser')
        options = labelParser.parse(description)
        createIfAbsent(options, 'svg')
        options['svg']['width'] = width
        options['svg']['height'] = height

        rootLayer = self.scanLayers(dom_svg, None)

        return Level(options, rootLayer, document)
Beispiel #3
0
    def fillResults(self, dict_):
        import gtk

        if self.widgetsInfos is None:
            return

        self.fillResultsPreHook()

        for widgetName in self.widgetsInfos.keys():
            widget = self.get(widgetName)
            (ns, key, default, accessors, items, dontDel) = self.widgetsInfos[widgetName].get()
            createIfAbsent(dict_, ns)

            if widget.__class__ == gtk.CheckButton:
                # CheckButton
                bool_ = widget.get_active()
                self.setOrDelBool(ns, key, bool_, dontDel)
            elif widget.__class__ == gtk.HScale:
                # HScale
                value = widget.get_value()
                if accessors is not None:
                    (setter, getter) = accessors
                    value = getter(value)
                self.setOrDelValue(ns, key, value, default)
            elif widget.__class__ == gtk.Button:
                # Button
                label = self.get(widgetName+'Label')
                if label is not None:
                    bitmap = label.get_text()
                    self.setOrDelBitmap(ns, key, bitmap)
            elif widget.__class__ == gtk.ColorButton:
                # ColorButton
                color = widget.get_color()
                (r, g, b) = (conv16to8(color.red),
                             conv16to8(color.green),
                             conv16to8(color.blue))
                a = conv16to8(widget.get_alpha())
                self.setOrDelColor(ns, key, (r, g, b, a))
            elif widget.__class__ == gtk.Entry:
                # Entry
                text = widget.get_text()
                self.setOrDelValue(ns, key, text, default)
            elif widget.__class__ == gtk.FileChooserButton:
                # FileChooserButton
                fileName = widget.get_filename()
                self.setOrDelValue(ns, key, fileName, default)
            elif widget.__class__ == gtk.ComboBox:
                # ComboBox
                # call get_active to record it (if in a session recording)
                # as there's no set_active_text method
                musicIdx = widget.get_active()
                music = widget.get_active_text()
                self.setOrDelValue(ns, key, music, default)

        self.removeUnusedNs(dict_)
Beispiel #4
0
    def __init__(self, options, rootLayer, document):
        self.options = options
        self.rootLayer = rootLayer
        self.elements = []
        self.layersType = []
        self.layerBlock2Level = []
        self.content = []

        self.svg = SvgDoc(document)

        # the xmoto width of the level is the width of svg in pixel
        # divided by 20.0
        ratio = Conf()['SVG2LVL_RATIO']
        lvlWidth = self.options['svg']['width'] * ratio
        lvlHeight = self.options['svg']['height'] * ratio

        createIfAbsent(self.options, 'lvl')
        self.options['lvl']['width'] = lvlWidth
        self.options['lvl']['height'] = lvlHeight
        self.options['lvl']['ratio'] = ratio

        self.limits = {}
        self.limits['left'] = -lvlWidth / 2.0
        self.limits['right'] = lvlWidth / 2.0
        self.limits['top'] = lvlHeight / 2.0
        self.limits['bottom'] = -lvlHeight / 2.0

        smooth = float(getValue(self.options, 'level', 'smooth', default='9'))
        # now, smooth is from 1 to 10 in the tkinter window,
        # but it is still from 1 to 100 in svg2lvl
        smooth += 90
        self.options['lvl']['smooth'] = smooth

        numLayers = len(self.rootLayer.children)
        self.createLayerInfos(numLayers)

        numLayers = 0
        self.rootLayer.elements = []
        for child in self.rootLayer.children:
            if (len(self.layersType) > 0
                    and self.layersType[numLayers] != 'unused'):
                self.createEntitiesAndBlocksFromSvg(child, numLayers)
            else:
                child.unused = True
            numLayers += 1

        self.options['lvl']['rversion'] = self.getRequiredXmotoVersion()
Beispiel #5
0
    def updateContent(self, element):
        _id = element.get('id', '')

        if _id in self.originalValues:
            savedLabel = self.label.copy()
            for namespace, namespaceDic in self.originalValues[_id].iteritems():
                createIfAbsent(self.label, namespace)
                for var, value in namespaceDic.iteritems():
                    self.label[namespace][var] = value

        style = self.generateStyle(self.label)

        self.updateNodeSvgAttributes(element, self.label, style)

        # restore the label before unloading it in the default values
        if _id in self.originalValues:
            self.label = savedLabel.copy()
Beispiel #6
0
    def writeContent(self, options, level):
        """
        - entity:
          * typeid=[PlayerStart|EndOfLevel|Strawberry|Wrecker|ParticleSource|Sprite]
          * size=float_number (the entity colision radius)
          * param_name=param_value
          ** available params are (there's more of them):
             z     (for Sprite)
             name  (for Sprite)
             type  (for ParticleSource)
        """
        self.newWidth = options['width']
        self.newHeight = options['height']
        self.ratio = options['ratio']
        self.level = level

        self.preProcessVertex()
        head = "\t<entity id=\"%s\" typeid=\"%s\">"
        self.content.append(head % (self._id, self.typeid))

        createIfAbsent(self.infos, 'size')

        if 'r' not in self.infos['size']:
            self.infos['size']['r'] = self.radius

        createIfAbsent(self.infos, 'position')

        if ('x' not in self.infos['position']
                or 'y' not in self.infos['position']):
            x, y = self.getEntityPos()
            self.infos['position']['x'] = str(x)
            self.infos['position']['y'] = str(y)

        createIfAbsent(self.level.options, 'remplacement')
        self.calculateNewDimensions()

        self.addElementParams()
        self.content.append("\t</entity>")

        return self.content
Beispiel #7
0
    def addPath(self, path):
        # put None if a value is different in at least two path
        label = path.get(addNS('xmoto_label', 'xmoto'), '')
        label = LabelParser().parse(label)

        self.defVals.addElementLabel(label)

        elementId = path.get('id', '')
        for name, value in label.iteritems():
            if type(value) == dict:
                namespace    = name
                namespaceDic = value

                # save original xmotoLabel to put back parameters not
                # modified by this extension
                if (self.namespacesInCommon is not None
                    and namespace not in self.namespacesInCommon):
                    createIfAbsent(self.originalValues, elementId)
                    createIfAbsent(self.originalValues[elementId], namespace)
                    for var, value in namespaceDic.iteritems():
                        self.originalValues[elementId][namespace][var] = value
                    continue

                createIfAbsent(self.comVals, namespace)

                for (name, value) in namespaceDic.iteritems():
                    if name in self.comVals[namespace]:
                        if self.comVals[namespace][name] != value:
                            self.comVals[namespace][name] = None
                    else:
                        self.comVals[namespace][name] = value
            else:
                if name in self.comVals:
                    if self.comVals[name] != value:
                        self.comVals[name] = None
                else:
                    self.comVals[name] = value
Beispiel #8
0
    def writeContent(self, options, level):
        """
        - block:
          * background
          * dynamic
          * usetexture=texture_name
        """
        def removeNonNormal(posParams, keys):
            """ only static blocks in layers other than main """
            for key in keys:
                if key in posParams:
                    del posParams[key]

        def removeNonMain(posParams):
            removeNonNormal(posParams, ['background', 'physics'])

        def removeForLayer(posParams):
            removeNonNormal(posParams, ['background', 'dynamic', 'physics'])

        def getEdgeColorAndScale(prefix):
            r = int(getValue(self.infos, 'edge', '%s_r' % prefix, default=255))
            g = int(getValue(self.infos, 'edge', '%s_g' % prefix, default=255))
            b = int(getValue(self.infos, 'edge', '%s_b' % prefix, default=255))
            a = int(getValue(self.infos, 'edge', '%s_a' % prefix, default=255))
            scale = getValue(self.infos, 'edge', '%s_scale' % prefix)
            if scale is not None:
                scale = float(scale)
            depth = getValue(self.infos, 'edge', '%s_depth' % prefix)
            if depth is not None:
                depth = float(depth)
                # ugly hack because xmoto 0.5.2 non set value for depth is -1.0f
                if depth == -1.0:
                    depth += 0.0001
            return ((r, g, b, a), scale, depth)

        self.curBlockCounter = 0
        self.curBlock = self._id
        self.ratio = options['ratio']
        self.newWidth = options['width']
        self.newHeight = options['height']
        self.smooth = options['smooth']
        useSmooth = getBoolValue(self.infos, 'position', '_usesmooth')
        if useSmooth == True:
            (present, smooth) = getIfPresent(self.infos, 'position', '_smooth')
            if present == True:
                self.smooth = 90.0 + float(smooth)

        createIfAbsent(self.infos, 'position')

        if ('x' not in self.infos['position']
                or 'y' not in self.infos['position']):
            self.infos['position']['x'] = '%f' % (-self.newWidth / 2.0)
            self.infos['position']['y'] = '%f' % (self.newHeight / 2.0)

        layerNumber = self.infos['layerid']
        del self.infos['layerid']
        layerLevel = level.getLayersType()[layerNumber]
        if layerLevel == 'static':
            pass
        elif layerLevel == '2ndStatic':
            self.infos['position']['islayer'] = "true"
            removeNonMain(self.infos['position'])
        else:
            self.infos['position']['islayer'] = "true"
            lid = str(level.getLayerBlock2Level()[layerNumber])
            self.infos['position']['layerid'] = lid
            removeForLayer(self.infos['position'])

        if 'usetexture' not in self.infos:
            self.infos['usetexture'] = {'id': 'default'}

        self.edgeTexture = getValue(self.infos, 'edge', 'texture', '')
        self.downEdgeTexture = getValue(self.infos, 'edge', 'downtexture', '')
        for prefix in ['u', 'd']:
            ((r, g, b, a), scale, depth) = getEdgeColorAndScale(prefix)
            if (r != 255 or g != 255 or b != 255 or scale is not None
                    or depth is not None):
                setattr(self, '%s_material' % prefix,
                        ((r, g, b, a), scale, depth))
            else:
                setattr(self, '%s_material' % prefix, None)
        self.edgeAngle = float(getValue(self.infos, 'edges', 'angle', 270.0))
        delWoExcept(self.infos, 'edge')

        if 'physics' in self.infos:
            if 'infinitemass' in self.infos['physics']:
                if self.infos['physics']['infinitemass'] == 'true':
                    self.infos['physics']['mass'] = 'INFINITY'
                    del self.infos['physics']['infinitemass']

        self.preProcessVertex()

        for vertex in self.blocks:
            self.writeBlockHead()
            self.writeBlockVertex(vertex)
            self.content.append("\t</block>")

            self.curBlockCounter += 1
            self.curBlock = self._id + str(self.curBlockCounter)

        return self.content
Beispiel #9
0
    def updateNodeSvgAttributes(self, node, label, style):
        node = convertToXmNode(node, self.svg)
        labelValue = LabelParser().unparse(label)
        styleValue = StyleParser().unparse(style)

        # if the user select the an element in the sublayer using the
        # 'circle tool' for example, the selected node will be that
        # element, not the sublayer (the sublayer is selected when you
        # use the 'selection tool').
        # in this case, use the sublayer instead of the selected child
        if node.belongsToSubLayer() == True:
            node = convertToXmNode(node.getparent())

        # update node shape
        # ugly and clumsy but will be refactored with xmObjects later
        if 'typeid' in label:
            # entity or zone
            typeid = label['typeid']

            if typeid in [
                    'PlayerStart', 'EndOfLevel', 'Strawberry', 'Wrecker',
                    'Checkpoint'
            ]:
                if typeid == 'EndOfLevel':
                    typeid = 'Flower'

                metadata = self.svg.getMetaDataValue()
                metadata = LabelParser().parse(metadata)

                if typeid == 'Checkpoint':
                    # the checkpoint sprite is called with _1
                    createIfAbsent(metadata, 'remplacement')
                    metadata['remplacement']['Checkpoint'] = 'Checkpoint_1'

                texName = getValue(metadata,
                                   'remplacement',
                                   typeid,
                                   default=typeid)
                scale = float(
                    getValue(metadata, 'remplacement', typeid + 'Scale', 1.0))
                _reversed = getBoolValue(label, 'position', 'reversed')
                rotation = float(getValue(label, 'position', 'angle', 0.0))
                radius = ENTITY_RADIUS[typeid] / SVG2LVL_RATIO

                node.setNodeAsBitmap(self.svg, texName, radius, SPRITES,
                                     labelValue, styleValue, scale, _reversed,
                                     rotation)

            elif typeid == 'ParticleSource':
                texName = getValue(label, 'param', 'type', '')
                radius = ENTITY_RADIUS[typeid] / SVG2LVL_RATIO

                node.setNodeAsBitmap(self.svg, texName, radius,
                                     PARTICLESOURCES, labelValue, styleValue)

            elif typeid == 'Sprite':
                texName = getValue(label, 'param', 'name', '')
                scale = float(getValue(label, 'size', 'scale', 1.0))
                _reversed = getBoolValue(label, 'position', 'reversed')
                rotation = float(getValue(label, 'position', 'angle', 0.0))
                radius = ENTITY_RADIUS['Sprite'] / SVG2LVL_RATIO

                node.setNodeAsBitmap(self.svg, texName, radius, SPRITES,
                                     labelValue, styleValue, scale, _reversed,
                                     rotation)

            elif typeid == 'Zone':
                (node, aabb) = node.subLayerElementToSingleNode()
                node.setNodeAsRectangle(aabb)
                # we may have set the label and still to a child of
                # 'g', and now node is the 'g', so we have to set it
                # to it too.
                node.setStyleLabel(labelValue, styleValue)

            elif typeid == 'Joint':
                # the addJoint extension already create the joints
                # with the right shape
                pass

            else:
                raise Exception("typeid=%s not handled by \
updateNodeSvgAttributes" % typeid)

        else:
            # block
            if node.isSubLayer(type=XmNode.BITMAP) == True:
                log.outMsg("Can't convert an entity to a block")
                return
#            elif (getValue(label, 'usetexture', 'color_r', 255) != 255
#                or getValue(label, 'usetexture', 'color_g', 255) != 255
#                or getValue(label, 'usetexture', 'color_b', 255) != 255):
#                # a color is not 255, we have to set two blocks, one
#                # textured and one colored
#                coloredStyle = self.generateStyle(label, coloredBlock=True)
#                coloredStyleValue = StyleParser().unparse(coloredStyle)
#
#                g = node.getSubLayerNode()
#                g.addColoredChildren(node, labelValue, styleValue, coloredStyleValue)
            else:
                if node.isSubLayer(type=XmNode.BLOCK) == True:
                    # remove sublayer and colored block
                    node.removeColoredChildren(labelValue, styleValue)
                else:
                    # nothing to do
                    pass

        node.setStyleLabel(labelValue, styleValue)
Beispiel #10
0
    def generateStyle(self, label, coloredBlock=False):
        def generateElementColor(color):
            """ randomly change the color to distinguish between
            adjacent elements """
            from random import randint
            # r, g and b must not be 'f' before adding the random int
            # or it could became '0'
            r = (hex2dec(color[0]) + randint(0, 1)) % 16
            g = (hex2dec(color[2]) + randint(0, 1)) % 16
            b = (hex2dec(color[4]) + randint(0, 1)) % 16
            return ('#' + dec2hex(r) + color[1] + dec2hex(g) + color[3] +
                    dec2hex(b) + color[5])

        style = {}
        if 'typeid' in label:
            # entity or zone
            typeid = label['typeid']

            if typeid in [
                    'PlayerStart', 'EndOfLevel', 'ParticleSource', 'Sprite',
                    'Strawberry', 'Wrecker', 'Checkpoint'
            ]:
                style['fill'] = 'none'
                style['stroke-width'] = '1px'
                style['stroke-linecap'] = 'butt'
                style['stroke-linejoin'] = 'miter'
                style['stroke-opacity'] = '1'

            if typeid == 'PlayerStart':
                # blue
                style['stroke'] = generateElementColor('0000ee')
            elif typeid == 'EndOfLevel':
                # yellow
                style['stroke'] = generateElementColor('eeee00')
            elif typeid == 'ParticleSource':
                # orange
                style['stroke'] = generateElementColor('eea500')
            elif typeid == 'Sprite':
                # purple
                style['stroke'] = generateElementColor('800080')
            elif typeid == 'Strawberry':
                # red
                style['stroke'] = generateElementColor('ee0000')
            elif typeid == 'Wrecker':
                # gray
                style['stroke'] = generateElementColor('808080')
            elif typeid == 'Checkpoint':
                # green
                style['stroke'] = generateElementColor('00ee00')
            elif typeid == 'Zone':
                # cyan
                style['fill'] = generateElementColor('00eeee')
                style['fill-opacity'] = 0.5
            elif typeid == 'Joint':
                # green
                style['fill'] = generateElementColor('00ee00')
                if getValue(label, 'joint', 'type', '') == 'pin':
                    style['stroke'] = '#000000'
                    style['stroke-opacity'] = '1'
            else:
                # black
                style['fill'] = generateElementColor('000000')
        else:
            # block
            if coloredBlock == False:
                createIfAbsent(label, 'usetexture')
                if 'id' not in label['usetexture']:
                    label['usetexture']['id'] = 'Dirt'

                # display the texture, if the texture is missing, display
                # the old colors
                try:
                    scale = float(getValue(label, 'usetexture', 'scale', 1.0))
                    patternId = self.svg.addPattern(label['usetexture']['id'],
                                                    TEXTURES, scale)
                    style['fill'] = 'url(#%s)' % patternId
                except Exception, e:
                    logging.info("Can't create pattern for texture %s.\n%s" %
                                 (label['usetexture']['id'], e))
                    style['fill-opacity'] = '1'
                    if 'position' in label:
                        if ('background' in label['position']
                                and 'dynamic' in label['position']):
                            # d36b00
                            style['fill'] = generateElementColor('d36b00')
                        elif 'background' in label['position']:
                            # bdb76b = darkkhaki
                            style['fill'] = generateElementColor('bdb76b')
                        elif 'dynamic' in label['position']:
                            # f08080 = lightcoral
                            style['fill'] = generateElementColor('e08080')
                        elif 'physics' in label['position']:
                            style['fill'] = generateElementColor('ee00ee')
                        else:
                            # 66cdaa = mediumaquamarine
                            style['fill'] = generateElementColor('66cdaa')
                    else:
                        # 66cdaa = mediumaquamarine
                        style['fill'] = generateElementColor('66cdaa')
            else: