void ObjectSelectionTool::updateHandles() { if (mMode == Moving || mMode == Rotating) return; const QSet<MapObjectItem*> &items = mapScene()->selectedObjectItems(); const bool showHandles = items.size() > 0; QRectF boundingRect; if (showHandles) { QSetIterator<MapObjectItem*> iter(items); MapObjectItem *item = iter.next(); boundingRect = item->mapToScene(item->boundingRect()).boundingRect(); while (iter.hasNext()) { item = iter.next(); boundingRect |= item->mapToScene(item->boundingRect()).boundingRect(); } mCornerHandles[TopLeft]->setPos(boundingRect.topLeft()); mCornerHandles[TopRight]->setPos(boundingRect.topRight()); mCornerHandles[BottomLeft]->setPos(boundingRect.bottomLeft()); mCornerHandles[BottomRight]->setPos(boundingRect.bottomRight()); // TODO: Might be nice to make it configurable mRotationOrigin = boundingRect.center(); mRotationOriginIndicator->setPos(mRotationOrigin); } mSelectionBoundingRect = boundingRect; setHandlesVisible(showHandles); mRotationOriginIndicator->setVisible(showHandles); }
/** * Inserts map object items for the given objects. */ void MapScene::objectsInserted(ObjectGroup *objectGroup, int first, int last) { ObjectGroupItem *ogItem = nullptr; // Find the object group item for the object group for (QGraphicsItem *item : mLayerItems) { if (ObjectGroupItem *ogi = dynamic_cast<ObjectGroupItem*>(item)) { if (ogi->objectGroup() == objectGroup) { ogItem = ogi; break; } } } Q_ASSERT(ogItem); const ObjectGroup::DrawOrder drawOrder = objectGroup->drawOrder(); for (int i = first; i <= last; ++i) { MapObject *object = objectGroup->objectAt(i); MapObjectItem *item = new MapObjectItem(object, mMapDocument, ogItem); if (drawOrder == ObjectGroup::TopDownOrder) item->setZValue(item->y()); else item->setZValue(i); mObjectItems.insert(object, item); } }
QGraphicsItem *MapScene::createLayerItem(Layer *layer) { QGraphicsItem *layerItem = nullptr; if (TileLayer *tl = layer->asTileLayer()) { layerItem = new TileLayerItem(tl, mMapDocument); } else if (ObjectGroup *og = layer->asObjectGroup()) { const ObjectGroup::DrawOrder drawOrder = og->drawOrder(); ObjectGroupItem *ogItem = new ObjectGroupItem(og); int objectIndex = 0; for (MapObject *object : og->objects()) { MapObjectItem *item = new MapObjectItem(object, mMapDocument, ogItem); if (drawOrder == ObjectGroup::TopDownOrder) item->setZValue(item->y()); else item->setZValue(objectIndex); mObjectItems.insert(object, item); ++objectIndex; } layerItem = ogItem; } else if (ImageLayer *il = layer->asImageLayer()) { layerItem = new ImageLayerItem(il, mMapDocument); } Q_ASSERT(layerItem); layerItem->setVisible(layer->isVisible()); return layerItem; }
/** * Updates the map object items related to the given objects. */ void MapScene::objectsChanged(const QList<MapObject*> &objects) { for (MapObject *object : objects) { MapObjectItem *item = itemForObject(object); Q_ASSERT(item); item->syncWithMapObject(); } }
/** * Updates the map object items related to the given objects. */ void MapItem::objectsChanged(const QList<MapObject*> &objects) { for (MapObject *object : objects) { MapObjectItem *item = mObjectItems.value(object); Q_ASSERT(item); item->syncWithMapObject(); } }
MapObjectItem *AbstractObjectTool::topMostObjectItemAt(QPointF pos) const { const QList<QGraphicsItem *> &items = mMapScene->items(pos); for (QGraphicsItem *item : items) { MapObjectItem *objectItem = qgraphicsitem_cast<MapObjectItem*>(item); if (objectItem && objectItem->mapObject()->objectGroup()->isUnlocked()) return objectItem; } return nullptr; }
LayerItem *MapItem::createLayerItem(Layer *layer) { LayerItem *layerItem = nullptr; QGraphicsItem *parent = this; if (layer->parentLayer()) parent = mLayerItems.value(layer->parentLayer()); switch (layer->layerType()) { case Layer::TileLayerType: layerItem = new TileLayerItem(static_cast<TileLayer*>(layer), mapDocument(), parent); break; case Layer::ObjectGroupType: { auto og = static_cast<ObjectGroup*>(layer); const ObjectGroup::DrawOrder drawOrder = og->drawOrder(); ObjectGroupItem *ogItem = new ObjectGroupItem(og, parent); int objectIndex = 0; for (MapObject *object : og->objects()) { MapObjectItem *item = new MapObjectItem(object, mapDocument(), ogItem); if (drawOrder == ObjectGroup::TopDownOrder) item->setZValue(item->y()); else item->setZValue(objectIndex); mObjectItems.insert(object, item); ++objectIndex; } layerItem = ogItem; break; } case Layer::ImageLayerType: layerItem = new ImageLayerItem(static_cast<ImageLayer*>(layer), mapDocument(), parent); break; case Layer::GroupLayerType: layerItem = new GroupLayerItem(static_cast<GroupLayer*>(layer), parent); break; } Q_ASSERT(layerItem); layerItem->setVisible(layer->isVisible()); layerItem->setEnabled(mDisplayMode == Editable); mLayerItems.insert(layer, layerItem); if (GroupLayer *groupLayer = layer->asGroupLayer()) createLayerItems(groupLayer->layers()); return layerItem; }
QList<MapObjectItem*> AbstractObjectTool::objectItemsAt(QPointF pos) const { const QList<QGraphicsItem *> &items = mMapScene->items(pos); QList<MapObjectItem*> objectList; for (auto item : items) { MapObjectItem *objectItem = qgraphicsitem_cast<MapObjectItem*>(item); if (objectItem && objectItem->mapObject()->objectGroup()->isUnlocked()) objectList.append(objectItem); } return objectList; }
/** * Updates the Z value of the objects when appropriate. */ void MapScene::objectsIndexChanged(ObjectGroup *objectGroup, int first, int last) { if (objectGroup->drawOrder() != ObjectGroup::IndexOrder) return; for (int i = first; i <= last; ++i) { MapObjectItem *item = itemForObject(objectGroup->objectAt(i)); Q_ASSERT(item); item->setZValue(i); } }
ObjectGroupItem(ObjectGroup *objectGroup, MapRenderer *renderer, QGraphicsItem *parent = nullptr) : QGraphicsItem(parent) { setFlag(QGraphicsItem::ItemHasNoContents); setPos(objectGroup->offset()); const ObjectGroup::DrawOrder drawOrder = objectGroup->drawOrder(); // Create a child item for each object for (MapObject *object : objectGroup->objects()) { MapObjectItem *item = new MapObjectItem(object, renderer, this); if (drawOrder == ObjectGroup::TopDownOrder) item->setZValue(item->y()); } }