diff --git a/src/libtiled/mapobject.h b/src/libtiled/mapobject.h index 4e8ae8ab27..53d66039dc 100644 --- a/src/libtiled/mapobject.h +++ b/src/libtiled/mapobject.h @@ -422,7 +422,7 @@ inline bool MapObject::hasDimensions() const * Returns true if this object can be rotated. */ inline bool MapObject::canRotate() const -{ return mShape != Point; } +{ return true; } inline bool MapObject::isTileObject() const { return !mCell.isEmpty(); } diff --git a/src/tiled/mapobjectitem.cpp b/src/tiled/mapobjectitem.cpp index 70c679fecb..744f7ebf04 100644 --- a/src/tiled/mapobjectitem.cpp +++ b/src/tiled/mapobjectitem.cpp @@ -97,8 +97,7 @@ void MapObjectItem::syncWithMapObject() } setVisible(mObject->isVisible()); - setFlag(QGraphicsItem::ItemIgnoresTransformations, - mObject->shape() == MapObject::Point); + setFlag(QGraphicsItem::ItemIgnoresTransformations, false); } void MapObjectItem::setIsHoverIndicator(bool isHoverIndicator) diff --git a/src/tiled/objectreferenceitem.cpp b/src/tiled/objectreferenceitem.cpp index f0be3eca99..004d8302c1 100644 --- a/src/tiled/objectreferenceitem.cpp +++ b/src/tiled/objectreferenceitem.cpp @@ -199,13 +199,11 @@ QPointF ObjectReferenceItem::objectCenter(MapObject *object, const MapRenderer & { QPointF screenPos = renderer.pixelToScreenCoords(object->position()); - if (object->shape() != MapObject::Point) { - QRectF bounds = object->screenBounds(renderer); + QRectF bounds = object->screenBounds(renderer); - // Adjust the bounding box for object rotation - bounds = rotateAt(screenPos, object->rotation()).mapRect(bounds); - screenPos = bounds.center(); - } + // Adjust the bounding box for object rotation + bounds = rotateAt(screenPos, object->rotation()).mapRect(bounds); + screenPos = bounds.center(); if (auto mapScene = qobject_cast(scene())) screenPos += mapScene->absolutePositionForLayer(*object->objectGroup()); diff --git a/src/tiled/objectselectionitem.cpp b/src/tiled/objectselectionitem.cpp index 729de2f515..eb81db2606 100644 --- a/src/tiled/objectselectionitem.cpp +++ b/src/tiled/objectselectionitem.cpp @@ -110,8 +110,7 @@ void MapObjectOutline::syncWithMapObject(const MapRenderer &renderer) setPos(pixelPos); setRotation(mObject->rotation()); - setFlag(QGraphicsItem::ItemIgnoresTransformations, - mObject->shape() == MapObject::Point); + setFlag(QGraphicsItem::ItemIgnoresTransformations, false); if (mBoundingRect != bounds) { prepareGeometryChange(); @@ -203,13 +202,7 @@ void MapObjectLabel::syncWithMapObject(const MapRenderer &renderer) bounds = rotateAt(pos, mObject->rotation()).mapRect(bounds); // Center the object name on the object bounding box - if (mObject->shape() == MapObject::Point) { - // Use a local offset, since point objects don't scale with the view - boundingRect.translate(0, -bounds.height()); - mTextPos.ry() -= bounds.height(); - } else { - pos = { (bounds.left() + bounds.right()) / 2, bounds.top() }; - } + pos = { (bounds.left() + bounds.right()) / 2, bounds.top() }; if (auto mapScene = static_cast(scene())) pos += mapScene->absolutePositionForLayer(*mObject->objectGroup()); diff --git a/src/tiled/objectselectiontool.cpp b/src/tiled/objectselectiontool.cpp index 758eb7a113..02bfa95059 100644 --- a/src/tiled/objectselectiontool.cpp +++ b/src/tiled/objectselectiontool.cpp @@ -369,7 +369,7 @@ void ObjectSelectionTool::activate(MapScene *scene) connect(mapDocument(), &MapDocument::mapChanged, this, &ObjectSelectionTool::updateHandlesAndOrigin); connect(mapDocument(), &MapDocument::selectedObjectsChanged, - this, &ObjectSelectionTool::updateHandlesAndOrigin); + this, &ObjectSelectionTool::updateHandlesAndOriginAndMode); connect(mapDocument(), &MapDocument::tilesetTilePositioningChanged, this, &ObjectSelectionTool::updateHandlesAndOrigin); connect(scene, &MapScene::parallaxParametersChanged, @@ -393,7 +393,7 @@ void ObjectSelectionTool::deactivate(MapScene *scene) disconnect(mapDocument(), &MapDocument::mapChanged, this, &ObjectSelectionTool::updateHandlesAndOrigin); disconnect(mapDocument(), &MapDocument::selectedObjectsChanged, - this, &ObjectSelectionTool::updateHandlesAndOrigin); + this, &ObjectSelectionTool::updateHandlesAndOriginAndMode); disconnect(mapDocument(), &MapDocument::tilesetTilePositioningChanged, this, &ObjectSelectionTool::updateHandlesAndOrigin); disconnect(scene, &MapScene::parallaxParametersChanged, @@ -685,12 +685,12 @@ void ObjectSelectionTool::mouseReleased(QGraphicsSceneMouseEvent *event) if (selection.size() > 1 || selection.first()->canRotate()) setMode(Rotate); } else { - setMode(Resize); + resetModeForSelection(selection); } } else { selection.clear(); selection.append(mClickedObject); - setMode(Resize); + resetModeForSelection(selection); mapDocument()->setSelectedObjects(selection); } } else if (!(modifiers & Qt::ShiftModifier)) { @@ -800,12 +800,17 @@ void ObjectSelectionTool::changeEvent(const ChangeEvent &event) void ObjectSelectionTool::updateHandles() { - updateHandlesImpl(false); + updateHandlesImpl(false, false); } void ObjectSelectionTool::updateHandlesAndOrigin() { - updateHandlesImpl(true); + updateHandlesImpl(true, false); +} + +void ObjectSelectionTool::updateHandlesAndOriginAndMode() +{ + updateHandlesImpl(true, true); } // TODO: Check whether this function should be moved into MapObject::bounds @@ -856,6 +861,16 @@ static bool canResize(const MapObject *object) return object->shape() != MapObject::Point; } +static bool canResizeOrRotate(const MapObject *object) +{ + return canResize(object) || object->canRotate(); +} + +static bool originIsAlwaysPosition(const MapObject *object) +{ + return object->shape() == MapObject::Point; +} + static bool canResizeAbsolute(const MapObject *object) { switch (object->shape()) { @@ -971,15 +986,18 @@ static QRectF uniteBounds(const QRectF &a, const QRectF &b) return QRectF(left, top, right - left, bottom - top); } -void ObjectSelectionTool::updateHandlesImpl(bool resetOriginIndicator) +void ObjectSelectionTool::updateHandlesImpl(bool resetOriginIndicator, bool shouldResetMode) { if (mAction == Moving || mAction == Rotating || mAction == Resizing) return; const QList &objects = mapDocument()->selectedObjects(); - const bool showHandles = objects.size() > 0 && (objects.size() > 1 || canResize(objects.first())); + const bool showHandles = objects.size() > 0 && (objects.size() > 1 || canResizeOrRotate(objects.first())); if (showHandles) { + if (shouldResetMode) + resetModeForSelection(objects); + MapRenderer *renderer = mapDocument()->renderer(); QRectF boundingRect = objectBounds(objects.first(), renderer, objectTransform(objects.first(), renderer, mapScene())); @@ -1013,7 +1031,11 @@ void ObjectSelectionTool::updateHandlesImpl(bool resetOriginIndicator) topRight = transform.map(renderer->pixelToScreenCoords(bounds.topRight())); bottomLeft = transform.map(renderer->pixelToScreenCoords(bounds.bottomLeft())); bottomRight = transform.map(renderer->pixelToScreenCoords(bounds.bottomRight())); - center = transform.map(renderer->pixelToScreenCoords(bounds.center())); + + if (originIsAlwaysPosition(object)) + center = object->position(); + else + center = transform.map(renderer->pixelToScreenCoords(bounds.center())); // Ugly hack to make handles appear nicer in this case if (mapDocument()->map()->orientation() == Map::Isometric) @@ -1026,7 +1048,11 @@ void ObjectSelectionTool::updateHandlesImpl(bool resetOriginIndicator) topRight = transform.map(bounds.topRight()); bottomLeft = transform.map(bounds.bottomLeft()); bottomRight = transform.map(bounds.bottomRight()); - center = transform.map(bounds.center()); + + if (originIsAlwaysPosition(object)) + center = object->position(); + else + center = transform.map(bounds.center()); } } @@ -1074,9 +1100,10 @@ void ObjectSelectionTool::updateHandleVisibility() { const QList &objects = mapDocument()->selectedObjects(); const bool hasSelection = !objects.isEmpty(); - const bool hasResizableObject = std::any_of(objects.begin(), objects.end(), canResize); - const bool showHandles = hasSelection && (objects.size() > 1 || hasResizableObject) && (mAction == NoAction || mAction == Selecting); + const bool hasResizableOrRotatableObject = std::any_of(objects.begin(), objects.end(), canResizeOrRotate); + const bool showHandles = hasSelection && (objects.size() > 1 || hasResizableOrRotatableObject) && (mAction == NoAction || mAction == Selecting); const bool showOrigin = hasSelection && + (objects.size() > 1 || !originIsAlwaysPosition(objects.first())) && mAction != Moving && (mMode == Rotate || mAction == Resizing); for (RotateHandle *handle : mRotateHandles) @@ -1635,6 +1662,17 @@ void ObjectSelectionTool::finishResizing() updateHandlesAndOrigin(); } +void ObjectSelectionTool::resetModeForSelection(const QList &selection) +{ + if (selection.size() == 1) + if (selection.first()->canRotate()) + if (!canResize(selection.first())) { + setMode(Rotate); + return; + } + setMode(Resize); +} + void ObjectSelectionTool::setMode(Mode mode) { if (mMode != mode) { diff --git a/src/tiled/objectselectiontool.h b/src/tiled/objectselectiontool.h index 6b01a4b66a..bb0275b861 100644 --- a/src/tiled/objectselectiontool.h +++ b/src/tiled/objectselectiontool.h @@ -72,6 +72,7 @@ class ObjectSelectionTool : public AbstractObjectTool void updateHandles(); void updateHandlesAndOrigin(); + void updateHandlesAndOriginAndMode(); void updateHandleVisibility(); void objectsAboutToBeRemoved(const QList &); @@ -92,7 +93,7 @@ class ObjectSelectionTool : public AbstractObjectTool Rotate, }; - void updateHandlesImpl(bool resetOriginIndicator); + void updateHandlesImpl(bool resetOriginIndicator, bool shouldResetMode); void updateHover(const QPointF &pos); QList objectsAboutToBeSelected(const QPointF &pos, @@ -124,6 +125,7 @@ class ObjectSelectionTool : public AbstractObjectTool void finishResizing(); void setMode(Mode mode); + void resetModeForSelection(const QList &selection); void saveSelectionState(); enum AbortReason { diff --git a/src/tiled/propertybrowser.cpp b/src/tiled/propertybrowser.cpp index 1b1850b873..864b4cd825 100644 --- a/src/tiled/propertybrowser.cpp +++ b/src/tiled/propertybrowser.cpp @@ -835,8 +835,7 @@ void PropertyBrowser::addMapObjectProperties() addProperty(HeightProperty, QMetaType::Double, tr("Height"), groupProperty); } - bool isPoint = mapObject->shape() == MapObject::Point; - addProperty(RotationProperty, QMetaType::Double, tr("Rotation"), groupProperty)->setEnabled(!isPoint); + addProperty(RotationProperty, QMetaType::Double, tr("Rotation"), groupProperty); if (mMapObjectFlags & ObjectHasTile) { QtVariantProperty *flippingProperty =