void MapDocument::resizeMap(const QSize &size, const QPoint &offset, bool removeObjects) { const QRegion movedSelection = mSelectedArea.translated(offset); const QRect newArea = QRect(-offset, size); const QRectF visibleArea = mRenderer->boundingRect(newArea); const QPointF origin = mRenderer->tileToPixelCoords(QPointF()); const QPointF newOrigin = mRenderer->tileToPixelCoords(-offset); const QPointF pixelOffset = origin - newOrigin; // Resize the map and each layer QUndoCommand *command = new QUndoCommand(tr("Resize Map")); LayerIterator iterator(mMap); while (Layer *layer = iterator.next()) { switch (layer->layerType()) { case Layer::TileLayerType: { TileLayer *tileLayer = static_cast<TileLayer*>(layer); new ResizeTileLayer(this, tileLayer, size, offset, command); break; } case Layer::ObjectGroupType: { ObjectGroup *objectGroup = static_cast<ObjectGroup*>(layer); for (MapObject *o : objectGroup->objects()) { if (removeObjects && !visibleIn(visibleArea, o, mRenderer)) { // Remove objects that will fall outside of the map new RemoveMapObject(this, o, command); } else { QPointF oldPos = o->position(); QPointF newPos = oldPos + pixelOffset; new MoveMapObject(this, o, newPos, oldPos, command); } } break; } case Layer::ImageLayerType: { // Adjust image layer by changing its offset auto imageLayer = static_cast<ImageLayer*>(layer); new SetLayerOffset(this, layer, imageLayer->offset() + pixelOffset, command); break; } case Layer::GroupLayerType: { // Recursion handled by LayerIterator break; } } } new ResizeMap(this, size, command); new ChangeSelectedArea(this, movedSelection, command); mUndoStack->push(command); // TODO: Handle layers that don't match the map size correctly }
QModelIndex MapObjectModel::index(int row, int column, const QModelIndex &parent) const { if (!parent.isValid()) { if (row < mObjectGroups.count()) return createIndex(row, column, mGroups[mObjectGroups.at(row)]); return QModelIndex(); } ObjectGroup *og = toObjectGroup(parent); // happens when deleting the last item in a parent if (row >= og->objectCount()) return QModelIndex(); // Paranoia: sometimes "fake" objects are in use (see createobjecttool) if (!mObjects.contains(og->objects().at(row))) return QModelIndex(); return createIndex(row, column, mObjects[og->objects()[row]]); }
static Ranges computeRanges(const QList<MapObject *> &objects) { Ranges ranges; for (MapObject *object : objects) { ObjectGroup *group = object->objectGroup(); auto &set = ranges[group]; set.insert(group->objects().indexOf(object)); } return ranges; }
void test_MapReader::loadMap() { MapReader reader; Map *map = reader.readMap("../data/mapobject.tmx"); // TODO: Also test tilesets (internal and external), properties and tile // layer data. QVERIFY(map); QCOMPARE(map->layerCount(), 2); QCOMPARE(map->width(), 100); QCOMPARE(map->height(), 80); QCOMPARE(map->tileWidth(), 32); QCOMPARE(map->tileHeight(), 32); TileLayer *tileLayer = dynamic_cast<TileLayer*>(map->layerAt(0)); QVERIFY(tileLayer); QCOMPARE(tileLayer->width(), 100); QCOMPARE(tileLayer->height(), 80); ObjectGroup *objectGroup = dynamic_cast<ObjectGroup*>(map->layerAt(1)); QVERIFY(objectGroup); QCOMPARE(objectGroup->name(), QLatin1String("Objects")); QCOMPARE(objectGroup->objects().count(), 1); MapObject *mapObject = objectGroup->objects().at(0); QCOMPARE(mapObject->name(), QLatin1String("Some object")); QCOMPARE(mapObject->type(), QLatin1String("WARP")); QCOMPARE(mapObject->x(), qreal(200)); QCOMPARE(mapObject->y(), qreal(200)); QCOMPARE(mapObject->width(), qreal(128)); QCOMPARE(mapObject->height(), qreal(64)); }
void ObjectSelectionItem::layerChanged(int index) { ObjectGroup *objectGroup = mMapDocument->map()->layerAt(index)->asObjectGroup(); if (!objectGroup) return; // If labels for all objects are visible, some labels may need to be added // removed based on layer visibility. if (Preferences::instance()->objectLabelVisibility() == Preferences::AllObjectLabels) addRemoveObjectLabels(); // If an object layer changed, that means its offset may have changed, // which affects the outlines of selected objects on that layer and the // positions of any name labels that are shown. syncOverlayItems(objectGroup->objects()); }
QVariant MapToVariantConverter::toVariant(const ObjectGroup &objectGroup) const { QVariantMap objectGroupVariant; objectGroupVariant[QLatin1String("type")] = QLatin1String("objectgroup"); if (objectGroup.color().isValid()) objectGroupVariant[QLatin1String("color")] = colorToString(objectGroup.color()); objectGroupVariant[QLatin1String("draworder")] = drawOrderToString(objectGroup.drawOrder()); addLayerAttributes(objectGroupVariant, objectGroup); QVariantList objectVariants; for (const MapObject *object : objectGroup.objects()) objectVariants << toVariant(*object); objectGroupVariant[QLatin1String("objects")] = objectVariants; return objectGroupVariant; }