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

Pivot alignment #366

Closed
wants to merge 5 commits into from
Closed
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
122 changes: 121 additions & 1 deletion src/app/GUI/extraactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ void MainWindow::setupMenuExtras()
}
// align
{
const int alignTotal = 28;
const int alignTotal = 40;

const QString alignTextDefault = tr("Align %1 %2 Relative to %3");
const QString alignGeometry = tr("Geometry");
Expand Down Expand Up @@ -481,6 +481,126 @@ void MainWindow::setupMenuExtras()
alignBoth = false;
align = Qt::AlignVCenter;
break;
case 28: // Pivot alignment to Bounding Box - VCenter -----------------------------------------------------------------------------------
alignString = alignVCenter;
pivotString = alignPivot;
relString = alignLast;
pivot = AlignPivot::pivotItself;
rel = AlignRelativeTo::boundingBox;
iconString = alignVCenterIcon;
alignBoth = false;
align = Qt::AlignVCenter;
break;
case 29: // Pivot alignment to Bounding Box - HCenter
alignString = alignVCenter;
pivotString = alignPivot;
relString = alignLast;
pivot = AlignPivot::pivotItself;
rel = AlignRelativeTo::boundingBox;
iconString = alignVCenterIcon;
alignBoth = false;
align = Qt::AlignHCenter;
break;
case 30: // Pivot alignment to Bounding Box - Left
alignString = alignVCenter;
pivotString = alignPivot;
relString = alignLast;
pivot = AlignPivot::pivotItself;
rel = AlignRelativeTo::boundingBox;
iconString = alignVCenterIcon;
alignBoth = false;
align = Qt::AlignLeft;
break;
case 31: // Pivot alignment to Bounding Box - Right
alignString = alignVCenter;
pivotString = alignPivot;
relString = alignLast;
pivot = AlignPivot::pivotItself;
rel = AlignRelativeTo::boundingBox;
iconString = alignVCenterIcon;
alignBoth = false;
align = Qt::AlignRight;
break;
case 32: // Pivot alignment to Bounding Box - Top
alignString = alignVCenter;
pivotString = alignPivot;
relString = alignLast;
pivot = AlignPivot::pivotItself;
rel = AlignRelativeTo::boundingBox;
iconString = alignVCenterIcon;
alignBoth = false;
align = Qt::AlignTop;
break;
case 33: // Pivot alignment to Bounding Box - Bottom
alignString = alignVCenter;
pivotString = alignPivot;
relString = alignLast;
pivot = AlignPivot::pivotItself;
rel = AlignRelativeTo::boundingBox;
iconString = alignVCenterIcon;
alignBoth = false;
align = Qt::AlignBottom;
break;
case 34: // Pivot alignment to Scene - VCenter -----------------------------------------------------------------------------------
alignString = alignVCenter;
pivotString = alignPivot;
relString = alignLast;
pivot = AlignPivot::pivotItself;
rel = AlignRelativeTo::scene;
iconString = alignVCenterIcon;
alignBoth = false;
align = Qt::AlignVCenter;
break;
case 35: // Pivot alignment to Scene - HCenter
alignString = alignVCenter;
pivotString = alignPivot;
relString = alignLast;
pivot = AlignPivot::pivotItself;
rel = AlignRelativeTo::scene;
iconString = alignVCenterIcon;
alignBoth = false;
align = Qt::AlignHCenter;
break;
case 36: // Pivot alignment to Scene - Left
alignString = alignVCenter;
pivotString = alignPivot;
relString = alignLast;
pivot = AlignPivot::pivotItself;
rel = AlignRelativeTo::scene;
iconString = alignVCenterIcon;
alignBoth = false;
align = Qt::AlignLeft;
break;
case 37: // Pivot alignment to Scene - Right
alignString = alignVCenter;
pivotString = alignPivot;
relString = alignLast;
pivot = AlignPivot::pivotItself;
rel = AlignRelativeTo::scene;
iconString = alignVCenterIcon;
alignBoth = false;
align = Qt::AlignRight;
break;
case 38: // Pivot alignment to Scene - Top
alignString = alignVCenter;
pivotString = alignPivot;
relString = alignLast;
pivot = AlignPivot::pivotItself;
rel = AlignRelativeTo::scene;
iconString = alignVCenterIcon;
alignBoth = false;
align = Qt::AlignTop;
break;
case 39: // Pivot alignment to Scene - Bottom
alignString = alignVCenter;
pivotString = alignPivot;
relString = alignLast;
pivot = AlignPivot::pivotItself;
rel = AlignRelativeTo::scene;
iconString = alignVCenterIcon;
alignBoth = false;
align = Qt::AlignBottom;
break;
default:
return;
}
Expand Down
94 changes: 94 additions & 0 deletions src/core/Boxes/boundingbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,100 @@ void BoundingBox::alignPivot(const Qt::Alignment align, const QRectF& to) {
alignGeometry(QRectF(pivot, pivot), align, to);
}

void BoundingBox::alignPivotItself(const Qt::Alignment align,
const QRectF& to,
const AlignRelativeTo relativeTo,
const QPointF lastPivotAbsPos) {
auto settings = getStrokeSettings();
auto strokeWidth = settings->getCurrentStrokeWidth();

auto boundingBox2 = getAbsBoundingRect();
auto toAbsBoundingRect = getTotalTransform().mapRect(to);
QPointF currentPivot = mTransformAnimator->getPivot();
QPointF currentPivotAbsPos = getPivotAbsPos();

QPointF lastSelectedPivotAbsPos = lastPivotAbsPos;

QPointF center = getRelCenterPosition();

if (relativeTo == AlignRelativeTo::scene) {
if (align & Qt::AlignVCenter) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably use a switch. Not important, just wanted to note :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

center.setX(currentPivot.x());
center.setY(currentPivot.y() - currentPivotAbsPos.y() + to.bottomRight().y()/2);
} else if (align & Qt::AlignHCenter) {
center.setX(currentPivot.x() - currentPivotAbsPos.x() + to.bottomRight().x()/2);
center.setY(currentPivot.y());
} else if (align & Qt::AlignLeft) {
center.setX(currentPivot.x() - currentPivotAbsPos.x());
center.setY(currentPivot.y());
} else if (align & Qt::AlignRight) {
center.setX(currentPivot.x() + (to.topRight().x() - currentPivotAbsPos.x()));
center.setY(currentPivot.y());
} else if (align & Qt::AlignTop) {
center.setX(currentPivot.x());
center.setY(currentPivot.y() - currentPivotAbsPos.y());
} else if (align & Qt::AlignBottom) {
center.setX(currentPivot.x());
center.setY(currentPivot.y() + (to.bottomRight().y() - currentPivotAbsPos.y()));
}
} else if (relativeTo == AlignRelativeTo::lastSelected) {
if (align & Qt::AlignVCenter) {
center.setX(currentPivot.x());
center.setY(currentPivot.y() - currentPivotAbsPos.y() + to.center().y());
} else if (align & Qt::AlignHCenter) {
center.setX(currentPivot.x() - currentPivotAbsPos.x() + to.center().x());
center.setY(currentPivot.y());
} else if (align & Qt::AlignLeft) {
center.setX(currentPivot.x() - currentPivotAbsPos.x() + to.topLeft().x());
center.setY(currentPivot.y());
} else if (align & Qt::AlignRight) {
center.setX(currentPivot.x() + (to.topRight().x() - currentPivotAbsPos.x()));
center.setY(currentPivot.y());
} else if (align & Qt::AlignTop) {
center.setX(currentPivot.x());
center.setY(currentPivot.y() - currentPivotAbsPos.y() + to.topLeft().y());
} else if (align & Qt::AlignBottom) {
center.setX(currentPivot.x());
center.setY(currentPivot.y() + (to.bottomRight().y() - currentPivotAbsPos.y()));
}
} else if (relativeTo == AlignRelativeTo::lastSelectedPivot) {
if (align & Qt::AlignVCenter) {
center.setX(currentPivot.x());
center.setY(currentPivot.y() - currentPivotAbsPos.y() + lastSelectedPivotAbsPos.y());
} else if (align & Qt::AlignHCenter) {
center.setX(currentPivot.x() - currentPivotAbsPos.x() + lastSelectedPivotAbsPos.x());
center.setY(currentPivot.y());
} else {
center.setX(currentPivot.x());
center.setY(currentPivot.y());
}
} else if (relativeTo == AlignRelativeTo::boundingBox) {
if (align & Qt::AlignVCenter) {
center.setX(currentPivot.x());
} else if (align & Qt::AlignHCenter) {
center.setY(currentPivot.y());
} else if (align & Qt::AlignLeft) {
center.setX(mRelRect.topLeft().x());
center.setY(currentPivot.y());
} else if (align & Qt::AlignRight) {
center.setX(mRelRect.topRight().x());
center.setY(currentPivot.y());
} else if (align & Qt::AlignTop) {
center.setX(currentPivot.x());
center.setY(mRelRect.topLeft().y());
} else if (align & Qt::AlignBottom) {
center.setX(currentPivot.x());
center.setY(mRelRect.bottomLeft().y());
}
}

startPosTransform();
// TODO: get undo/redo to save last previous state
mTransformAnimator->setPivotFixedTransform(center);
requestGlobalPivotUpdateIfSelected();
finishTransform();
}

void BoundingBox::moveByAbs(const QPointF &trans) {
mTransformAnimator->moveByAbs(trans);
}
Expand Down
9 changes: 9 additions & 0 deletions src/core/Boxes/boundingbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@

class Canvas;

enum class AlignRelativeTo;

class QrealAction;
class MovablePoint;

Expand Down Expand Up @@ -298,6 +300,10 @@ class CORE_EXPORT BoundingBox : public eBoxOrSound {

void alignGeometry(const Qt::Alignment align, const QRectF& to);
void alignPivot(const Qt::Alignment align, const QRectF& to);
void alignPivotItself(const Qt::Alignment align,
const QRectF& to,
const AlignRelativeTo relativeTo,
const QPointF lastPivotAbsPos);

QMatrix getTotalTransform() const;

Expand Down Expand Up @@ -456,6 +462,9 @@ class CORE_EXPORT BoundingBox : public eBoxOrSound {

uint mStateId = 0;

int mWidth;
int mHeight;

int mNReasonsNotToApplyUglyTransform = 0;
protected:
bool getUpdatePlanned() const
Expand Down
4 changes: 2 additions & 2 deletions src/core/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ class eKeyEvent;
enum class CtrlsMode : short;

enum class AlignPivot {
geometry, pivot
geometry, pivot, pivotItself
};

enum class AlignRelativeTo {
scene, lastSelected
scene, lastSelected, lastSelectedPivot, boundingBox
};

class CORE_EXPORT Canvas : public CanvasBase
Expand Down
11 changes: 11 additions & 0 deletions src/core/canvasselectedboxesactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,14 @@ void Canvas::alignSelectedBoxes(const Qt::Alignment align,
skip = mLastSelectedBox;
geometry = mLastSelectedBox->getAbsBoundingRect();
break;
case AlignRelativeTo::lastSelectedPivot:
if(!mLastSelectedBox) return;
skip = mLastSelectedBox;
geometry = QRectF(mLastSelectedBox->getPivotAbsPos(),mLastSelectedBox->getPivotAbsPos());
break;
case AlignRelativeTo::boundingBox:
geometry = QRectF(0., 0., mWidth, mHeight); // TODO: not using it?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Todo what? :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would need to double check if it is used or not for aligning object to canvas... just that, I'll try removing it and see if it breaks something...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, let's get the boudingbox stuff working 100% before the UI stuff.

Is everything working as expected? I did basic testing of some boxes and it seems to work, but I didn't test everything.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right.

I test it pretty deeply and the only two issues I found are the ones I commented:

  • pivot alignment crashes Friction with Null object, I need to check if you fixed it by removing a function, you already commented about it
  • text object doesn't work perfectly, it seems to have a different approach for its origin... try and let me know if you understand why

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pivot alignment crashes Friction with Null object, I need to check if you fixed it by removing a function, you already commented about it

This is fixed, you tried to access stroke settings without checking that settings was valid if (settings). It wasn't used for anything anyway, so I removed it.

text object doesn't work perfectly, it seems to have a different approach for its origin... try and let me know if you understand why

Ok, will need to test.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been doing some tests and this seems not to make any difference so I guess the whole case can be deleted.

Do you want me to do it?

break;
}

pushUndoRedoName("align");
Expand All @@ -876,6 +884,9 @@ void Canvas::alignSelectedBoxes(const Qt::Alignment align,
case AlignPivot::geometry:
box->alignGeometry(align, geometry);
break;
case AlignPivot::pivotItself:
box->alignPivotItself(align, geometry, relativeTo, mLastSelectedBox->getPivotAbsPos());
break;
}
}
}
Loading
Loading