Move bar: held Ctrl and Shift flip Auto Select and the lock, values apply as one step, resize handles snap (13.13)
This commit is contained in:
1 parent
765e071c0c
commit
b50657bcdb
17 files changed
+703
-78
No files matched your search
@@ -0,0 +1,157 @@
|
||||
#include "SessionFixtures.h"
|
||||
#include <QtTest>
|
||||
|
||||
// Swift's ResizeSnapTests: a resized layer's edges snap, as moves do.
|
||||
namespace {
|
||||
struct Resized {
|
||||
EditorSession session;
|
||||
QUuid layer;
|
||||
|
||||
// 300 by 200: the layer at 10; another at 150.
|
||||
Resized()
|
||||
{
|
||||
session.createDocument(300, 200);
|
||||
place(QPointF(150, 150), QSizeF(40, 40));
|
||||
place(QPointF(10, 10), QSizeF(100, 100));
|
||||
layer = session.activeLayerID().value();
|
||||
}
|
||||
void place(QPointF origin, QSizeF size)
|
||||
{
|
||||
session.insert(ImportedImage(QImage(20, 20, QImage::Format_RGBA8888_Premultiplied), QImage(), "Layer"));
|
||||
session.beginTransform();
|
||||
session.previewTransform(LayerTransform{.origin = origin, .size = size});
|
||||
session.commitTransform();
|
||||
}
|
||||
LayerTransform resize(int handle, QPointF start, QPointF point, bool lockRatio)
|
||||
{
|
||||
const TransformDrag drag{layerWith(session, layer).transform, start, {TransformDrag::Kind::resize, handle}, std::nullopt};
|
||||
const QPointF snapped = session.snappedResizePoint(point, drag, lockRatio, {layer}, 5, [&](QPointF to) {
|
||||
return drag.updated(to, lockRatio, false);
|
||||
});
|
||||
return drag.updated(snapped, lockRatio, false).rounded();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class ResizeSnapTests : public QObject {
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void aSideHandleSnapsItsEdge();
|
||||
void aProportionalCornerSnapsItsNearerEdgeAndKeepsTheRatio();
|
||||
void aTurnedLayerDoesntSnap();
|
||||
void eachEdgeSnapsOnItsOwn();
|
||||
void theDraggedSideAloneSnaps();
|
||||
void snappingOffOrAnotherDragLeavesThePoint();
|
||||
};
|
||||
|
||||
void ResizeSnapTests::aSideHandleSnapsItsEdge()
|
||||
{
|
||||
Resized resized;
|
||||
QCOMPARE(LayerTransform::handles[3], QPointF(1, 0.5));
|
||||
// The right edge, three short of the other layer's left.
|
||||
const LayerTransform result = resized.resize(3, QPointF(110, 60), QPointF(147, 60), false);
|
||||
QCOMPARE(result.origin.x() + result.size.width(), 150.0);
|
||||
QCOMPARE(result.size.height(), 100.0);
|
||||
QCOMPARE(resized.session.snapGuides, (SnapGuides{{150}, {}}));
|
||||
// Out of reach, it does not.
|
||||
const LayerTransform free = resized.resize(3, QPointF(110, 60), QPointF(130, 60), false);
|
||||
QCOMPARE(free.origin.x() + free.size.width(), 130.0);
|
||||
QCOMPARE(resized.session.snapGuides, SnapGuides{});
|
||||
// The left handle snaps the left edge, to the canvas.
|
||||
const LayerTransform left = resized.resize(7, QPointF(10, 60), QPointF(3, 60), false);
|
||||
QCOMPARE(left.origin.x(), 0.0);
|
||||
QCOMPARE(left.origin.x() + left.size.width(), 110.0);
|
||||
}
|
||||
|
||||
void ResizeSnapTests::aProportionalCornerSnapsItsNearerEdgeAndKeepsTheRatio()
|
||||
{
|
||||
Resized resized;
|
||||
// Bottom right toward 146, 148: the bottom edge snaps.
|
||||
const LayerTransform result = resized.resize(4, QPointF(110, 110), QPointF(146, 148), true);
|
||||
QCOMPARE(result.origin.y() + result.size.height(), 150.0);
|
||||
QVERIFY(std::abs(result.size.width() - result.size.height()) <= 1);
|
||||
// A tie goes to the right edge, the first.
|
||||
QCOMPARE(resized.session.snapGuides, (SnapGuides{{150}, {}}));
|
||||
// A top at 148 lies nearer the bottom: it snaps.
|
||||
resized.place(QPointF(260, 148), QSizeF(10, 10));
|
||||
resized.session.selectLayer(resized.layer);
|
||||
const LayerTransform bottom = resized.resize(4, QPointF(110, 110), QPointF(147, 147), true);
|
||||
QCOMPARE(bottom, (LayerTransform{.origin = {10, 10}, .size = {138, 138}}));
|
||||
QCOMPARE(resized.session.snapGuides, (SnapGuides{{}, {148}}));
|
||||
// Free, both edges snap, each to its nearest.
|
||||
const LayerTransform free = resized.resize(4, QPointF(110, 110), QPointF(147, 147), false);
|
||||
QCOMPARE(free, (LayerTransform{.origin = {10, 10}, .size = {140, 138}}));
|
||||
}
|
||||
|
||||
void ResizeSnapTests::aTurnedLayerDoesntSnap()
|
||||
{
|
||||
Resized resized;
|
||||
LayerTransform turned = layerWith(resized.session, resized.layer).transform;
|
||||
turned.rotation = 20;
|
||||
const TransformDrag drag{turned, QPointF(110, 60), {TransformDrag::Kind::resize, 3}, std::nullopt};
|
||||
// Wherever the handle goes, the pointer stays put.
|
||||
for (double x = 100; x <= 200; x += 0.5) {
|
||||
resized.session.snapGuides = SnapGuides{{1}, {2}};
|
||||
const QPointF point(x, 60);
|
||||
QCOMPARE(resized.session.snappedResizePoint(point, drag, false, {resized.layer}, 5, [&](QPointF to) { return drag.updated(to, false, false); }),
|
||||
point);
|
||||
QCOMPARE(resized.session.snapGuides, SnapGuides{});
|
||||
}
|
||||
}
|
||||
|
||||
void ResizeSnapTests::eachEdgeSnapsOnItsOwn()
|
||||
{
|
||||
Resized resized;
|
||||
// Free, a corner snaps both edges, each to its line.
|
||||
const LayerTransform result = resized.resize(4, QPointF(110, 110), QPointF(146, 147), false);
|
||||
QCOMPARE(result, (LayerTransform{.origin = {10, 10}, .size = {140, 140}}));
|
||||
QCOMPARE(resized.session.snapGuides, (SnapGuides{{150}, {150}}));
|
||||
// The top left corner moves the top and left edges.
|
||||
const LayerTransform corner = resized.resize(0, QPointF(10, 10), QPointF(2, 4), false);
|
||||
QCOMPARE(corner, (LayerTransform{.origin = {0, 0}, .size = {110, 110}}));
|
||||
// An edge no step moves keeps the pointer; guide shown.
|
||||
const TransformDrag drag{layerWith(resized.session, resized.layer).transform, QPointF(110, 60), {TransformDrag::Kind::resize, 3}, std::nullopt};
|
||||
const QPointF still = resized.session.snappedResizePoint(QPointF(147, 60), drag, false, {resized.layer}, 5, [&](QPointF) {
|
||||
return LayerTransform{.origin = {10, 10}, .size = {138, 100}};
|
||||
});
|
||||
QCOMPARE(still, QPointF(147, 60));
|
||||
QCOMPARE(resized.session.snapGuides, (SnapGuides{{150}, {}}));
|
||||
}
|
||||
|
||||
// The dragged side tells its edge, wherever the press began.
|
||||
void ResizeSnapTests::theDraggedSideAloneSnaps()
|
||||
{
|
||||
Resized resized;
|
||||
// Pressed left of the layer, the right edge still moves.
|
||||
const LayerTransform far = resized.resize(3, QPointF(-50, 60), QPointF(-13, 60), false);
|
||||
QCOMPARE(far.origin.x() + far.size.width(), 150.0);
|
||||
QCOMPARE(far.origin.x(), 10.0);
|
||||
// A top on a line: side drags never snap it.
|
||||
resized.session.beginTransform();
|
||||
resized.session.previewTransform(LayerTransform{.origin = {10, 98}, .size = {100, 60}});
|
||||
resized.session.commitTransform();
|
||||
resized.resize(3, QPointF(110, 128), QPointF(147, 128), false);
|
||||
QCOMPARE(resized.session.snapGuides, (SnapGuides{{150}, {}}));
|
||||
// Nor a bottom handle the left edge, near the canvas's.
|
||||
resized.session.beginTransform();
|
||||
resized.session.previewTransform(LayerTransform{.origin = {2, 10}, .size = {100, 100}});
|
||||
resized.session.commitTransform();
|
||||
const LayerTransform down = resized.resize(5, QPointF(52, 110), QPointF(52, 148), false);
|
||||
QCOMPARE(down, (LayerTransform{.origin = {2, 10}, .size = {100, 140}}));
|
||||
QCOMPARE(resized.session.snapGuides, (SnapGuides{{}, {150}}));
|
||||
}
|
||||
|
||||
void ResizeSnapTests::snappingOffOrAnotherDragLeavesThePoint()
|
||||
{
|
||||
Resized resized;
|
||||
resized.session.setSnappingEnabled(false);
|
||||
const LayerTransform result = resized.resize(3, QPointF(110, 60), QPointF(147, 60), false);
|
||||
QCOMPARE(result.origin.x() + result.size.width(), 147.0);
|
||||
resized.session.setSnappingEnabled(true);
|
||||
const TransformDrag move{layerWith(resized.session, resized.layer).transform, QPointF(110, 60), {TransformDrag::Kind::move, 3}, std::nullopt};
|
||||
QCOMPARE(resized.session.snappedResizePoint(QPointF(147, 60), move, false, {resized.layer}, 5, [&](QPointF to) { return move.updated(to, false, false); }),
|
||||
QPointF(147, 60));
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(ResizeSnapTests)
|
||||
#include "ResizeSnapTests.moc"
|
||||
Reference in new issue
Block a user