Beispiel #1
0
void PropertyBrowser::applyMapObjectValue(PropertyId id, const QVariant &val)
{
    MapObject *mapObject = static_cast<MapObject*>(mObject);
    QUndoCommand *command = 0;

    switch (id) {
    case NameProperty:
    case TypeProperty:
        command = new ChangeMapObject(mMapDocument, mapObject,
                                      mIdToProperty[NameProperty]->value().toString(),
                                      mIdToProperty[TypeProperty]->value().toString());
        break;
    case VisibleProperty:
        command = new SetMapObjectVisible(mMapDocument, mapObject, val.toBool());
        break;
    case PositionProperty: {
        const QPointF oldPos = mapObject->position();
        mapObject->setPosition(val.toPointF());
        command = new MoveMapObject(mMapDocument, mapObject, oldPos);
        break;
    }
    case SizeProperty: {
        const QSizeF oldSize = mapObject->size();
        mapObject->setSize(val.toSizeF());
        command = new ResizeMapObject(mMapDocument, mapObject, oldSize);
        break;
    }
    case RotationProperty: {
        const qreal oldRotation = mapObject->rotation();
        mapObject->setRotation(val.toDouble());
        command = new RotateMapObject(mMapDocument, mapObject, oldRotation);
        break;
    }
    case FlippingProperty: {
        const int flippingFlags = val.toInt();
        const bool flippedHorizontally = flippingFlags & 1;
        const bool flippedVertically = flippingFlags & 2;

        // You can only change one checkbox at a time
        if (mapObject->cell().flippedHorizontally != flippedHorizontally) {
            command = new FlipMapObjects(mMapDocument,
                                         QList<MapObject*>() << mapObject,
                                         FlipHorizontally);
        } else if (mapObject->cell().flippedVertically != flippedVertically) {
            command = new FlipMapObjects(mMapDocument,
                                         QList<MapObject*>() << mapObject,
                                         FlipVertically);
        }
    }
    default:
        break;
    }

    if (command)
        mMapDocument->undoStack()->push(command);
}
ObjectGroup *VariantToMapConverter::toObjectGroup(const QVariantMap &variantMap)
{
    typedef QScopedPointer<ObjectGroup> ObjectGroupPtr;
    ObjectGroupPtr objectGroup(new ObjectGroup(variantMap[QLatin1String("name")].toString(),
                                               variantMap[QLatin1String("x")].toInt(),
                                               variantMap[QLatin1String("y")].toInt(),
                                               variantMap[QLatin1String("width")].toInt(),
                                               variantMap[QLatin1String("height")].toInt()));

    const qreal opacity = variantMap[QLatin1String("opacity")].toReal();
    const bool visible = variantMap[QLatin1String("visible")].toBool();

    objectGroup->setOpacity(opacity);
    objectGroup->setVisible(visible);

    objectGroup->setColor(variantMap.value(QLatin1String("color")).value<QColor>());

    const QString drawOrderString = variantMap.value(QLatin1String("draworder")).toString();
    if (!drawOrderString.isEmpty()) {
        objectGroup->setDrawOrder(drawOrderFromString(drawOrderString));
        if (objectGroup->drawOrder() == ObjectGroup::UnknownOrder) {
            mError = tr("Invalid draw order: %1").arg(drawOrderString);
            return nullptr;
        }
    }

    foreach (const QVariant &objectVariant, variantMap[QLatin1String("objects")].toList()) {
        const QVariantMap objectVariantMap = objectVariant.toMap();

        const QString name = objectVariantMap[QLatin1String("name")].toString();
        const QString type = objectVariantMap[QLatin1String("type")].toString();
        const int id = objectVariantMap[QLatin1String("id")].toInt();
        const int gid = objectVariantMap[QLatin1String("gid")].toInt();
        const qreal x = objectVariantMap[QLatin1String("x")].toReal();
        const qreal y = objectVariantMap[QLatin1String("y")].toReal();
        const qreal width = objectVariantMap[QLatin1String("width")].toReal();
        const qreal height = objectVariantMap[QLatin1String("height")].toReal();
        const qreal rotation = objectVariantMap[QLatin1String("rotation")].toReal();

        const QPointF pos(x, y);
        const QSizeF size(width, height);

        MapObject *object = new MapObject(name, type, pos, size);
        object->setId(id);
        object->setRotation(rotation);

        if (gid) {
            bool ok;
            object->setCell(mGidMapper.gidToCell(gid, ok));

            if (!object->cell().isEmpty()) {
                const QSizeF &tileSize = object->cell().tile->size();
                if (width == 0)
                    object->setWidth(tileSize.width());
                if (height == 0)
                    object->setHeight(tileSize.height());
            }
        }

        if (objectVariantMap.contains(QLatin1String("visible")))
            object->setVisible(objectVariantMap[QLatin1String("visible")].toBool());

        object->setProperties(extractProperties(objectVariantMap));
        objectGroup->addObject(object);

        const QVariant polylineVariant = objectVariantMap[QLatin1String("polyline")];
        const QVariant polygonVariant = objectVariantMap[QLatin1String("polygon")];

        if (polygonVariant.isValid()) {
            object->setShape(MapObject::Polygon);
            object->setPolygon(toPolygon(polygonVariant));
        }
        if (polylineVariant.isValid()) {
            object->setShape(MapObject::Polyline);
            object->setPolygon(toPolygon(polylineVariant));
        }
        if (objectVariantMap.contains(QLatin1String("ellipse")))
            object->setShape(MapObject::Ellipse);
    }

    return objectGroup.take();
}
QVariant MapToVariantConverter::toVariant(const MapObject &object) const
{
    QVariantMap objectVariant;
    const QString &name = object.name();
    const QString &type = object.type();

    addProperties(objectVariant, object.properties());

    if (const ObjectTemplate *objectTemplate = object.objectTemplate()) {
        QString relativeFileName = mMapDir.relativeFilePath(objectTemplate->fileName());
        objectVariant[QLatin1String("template")] = relativeFileName;
    }

    bool notTemplateInstance = !object.isTemplateInstance();

    int id = object.id();
    if (id != 0)
        objectVariant[QLatin1String("id")] = id;

    if (notTemplateInstance || object.propertyChanged(MapObject::NameProperty))
        objectVariant[QLatin1String("name")] = name;

    if (notTemplateInstance || object.propertyChanged(MapObject::TypeProperty))
        objectVariant[QLatin1String("type")] = type;


    if (notTemplateInstance || object.propertyChanged(MapObject::CellProperty))
        if (!object.cell().isEmpty())
            objectVariant[QLatin1String("gid")] = mGidMapper.cellToGid(object.cell());

    if (id != 0) {
        objectVariant[QLatin1String("x")] = object.x();
        objectVariant[QLatin1String("y")] = object.y();
    }

    if (notTemplateInstance || object.propertyChanged(MapObject::SizeProperty)) {
        objectVariant[QLatin1String("width")] = object.width();
        objectVariant[QLatin1String("height")] = object.height();
    }

    if (notTemplateInstance || object.propertyChanged(MapObject::RotationProperty))
        objectVariant[QLatin1String("rotation")] = object.rotation();

    if (notTemplateInstance || object.propertyChanged(MapObject::VisibleProperty))
        objectVariant[QLatin1String("visible")] = object.isVisible();

    /* Polygons are stored in this format:
     *
     *   "polygon/polyline": [
     *       { "x": 0, "y": 0 },
     *       { "x": 1, "y": 1 },
     *       ...
     *   ]
     */
    switch (object.shape()) {
    case MapObject::Rectangle:
        break;
    case MapObject::Polygon:
    case MapObject::Polyline: {
        if (notTemplateInstance || object.propertyChanged(MapObject::ShapeProperty)) {
            QVariantList pointVariants;
            for (const QPointF &point : object.polygon()) {
                QVariantMap pointVariant;
                pointVariant[QLatin1String("x")] = point.x();
                pointVariant[QLatin1String("y")] = point.y();
                pointVariants.append(pointVariant);
            }

            if (object.shape() == MapObject::Polygon)
                objectVariant[QLatin1String("polygon")] = pointVariants;
            else
                objectVariant[QLatin1String("polyline")] = pointVariants;
        }
        break;
    }
    case MapObject::Ellipse:
        if (notTemplateInstance || object.propertyChanged(MapObject::ShapeProperty))
            objectVariant[QLatin1String("ellipse")] = true;
        break;
    case MapObject::Text:
        if (notTemplateInstance || (object.propertyChanged(MapObject::TextProperty) ||
                                    object.propertyChanged(MapObject::TextFontProperty) ||
                                    object.propertyChanged(MapObject::TextAlignmentProperty) ||
                                    object.propertyChanged(MapObject::TextWordWrapProperty) ||
                                    object.propertyChanged(MapObject::TextColorProperty)))
            objectVariant[QLatin1String("text")] = toVariant(object.textData());
        break;
    case MapObject::Point:
        if (notTemplateInstance || object.propertyChanged(MapObject::ShapeProperty))
            objectVariant[QLatin1String("point")] = true;
        break;
    }

    return objectVariant;
}
Beispiel #4
0
void TemplatesDock::setTemplate(ObjectTemplate *objectTemplate)
{
    if (mObjectTemplate == objectTemplate)
        return;

    mObjectTemplate = objectTemplate;

    mMapScene->setSelectedTool(nullptr);
    MapDocumentPtr previousDocument = mDummyMapDocument;

    mMapView->setEnabled(objectTemplate);

    if (objectTemplate && objectTemplate->object()) {
        mDummyMapDocument = ourDummyDocuments.value(objectTemplate);

        if (!mDummyMapDocument) {
            Map::Orientation orientation = Map::Orthogonal;
            std::unique_ptr<Map> map { new Map(orientation, 1, 1, 1, 1) };

            MapObject *dummyObject = objectTemplate->object()->clone();
            dummyObject->markAsTemplateBase();

            if (Tileset *tileset = dummyObject->cell().tileset()) {
                map->addTileset(tileset->sharedPointer());
                dummyObject->setPosition({-dummyObject->width() / 2, dummyObject->height() / 2});
            } else {
                dummyObject->setPosition({-dummyObject->width() / 2, -dummyObject->height()  /2});
            }

            ObjectGroup *objectGroup = new ObjectGroup;
            objectGroup->addObject(dummyObject);

            map->addLayer(objectGroup);

            mDummyMapDocument = MapDocumentPtr::create(std::move(map));
            mDummyMapDocument->setAllowHidingObjects(false);
            mDummyMapDocument->setCurrentLayer(objectGroup);

            ourDummyDocuments.insert(objectTemplate, mDummyMapDocument);
        }

        mDummyMapDocument->setCurrentObject(dummyObject());

        mUndoAction->setEnabled(mDummyMapDocument->undoStack()->canUndo());
        mRedoAction->setEnabled(mDummyMapDocument->undoStack()->canRedo());

        connect(mDummyMapDocument->undoStack(), &QUndoStack::indexChanged,
                this, &TemplatesDock::applyChanges);

        checkTileset();
    } else {
        mDummyMapDocument.reset();
    }

    mMapScene->setMapDocument(mDummyMapDocument.data());
    mToolManager->setMapDocument(mDummyMapDocument.data());
    mPropertiesDock->setDocument(mDummyMapDocument.data());

    mMapScene->setSelectedTool(mToolManager->selectedTool());

    if (previousDocument)
        previousDocument->undoStack()->disconnect(this);
}