Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Point rotation #3854

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libtiled/mapobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(); }
Expand Down
3 changes: 1 addition & 2 deletions src/tiled/mapobjectitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 4 additions & 6 deletions src/tiled/objectreferenceitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<MapScene*>(scene()))
screenPos += mapScene->absolutePositionForLayer(*object->objectGroup());
Expand Down
11 changes: 2 additions & 9 deletions src/tiled/objectselectionitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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<MapScene*>(scene()))
pos += mapScene->absolutePositionForLayer(*mObject->objectGroup());
Expand Down
62 changes: 50 additions & 12 deletions src/tiled/objectselectiontool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()) {
Expand Down Expand Up @@ -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<MapObject*> &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()));
Expand Down Expand Up @@ -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)
Expand All @@ -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());
}
}

Expand Down Expand Up @@ -1074,9 +1100,10 @@ void ObjectSelectionTool::updateHandleVisibility()
{
const QList<MapObject*> &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)
Expand Down Expand Up @@ -1635,6 +1662,17 @@ void ObjectSelectionTool::finishResizing()
updateHandlesAndOrigin();
}

void ObjectSelectionTool::resetModeForSelection(const QList<MapObject *> &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) {
Expand Down
4 changes: 3 additions & 1 deletion src/tiled/objectselectiontool.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class ObjectSelectionTool : public AbstractObjectTool

void updateHandles();
void updateHandlesAndOrigin();
void updateHandlesAndOriginAndMode();
void updateHandleVisibility();

void objectsAboutToBeRemoved(const QList<MapObject *> &);
Expand All @@ -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<MapObject*> objectsAboutToBeSelected(const QPointF &pos,
Expand Down Expand Up @@ -124,6 +125,7 @@ class ObjectSelectionTool : public AbstractObjectTool
void finishResizing();

void setMode(Mode mode);
void resetModeForSelection(const QList<MapObject *> &selection);
void saveSelectionState();

enum AbortReason {
Expand Down
3 changes: 1 addition & 2 deletions src/tiled/propertybrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
Loading