Files
OmaPhoto/tests/TransformSnapTests.cpp
T

127 lines
6.5 KiB
C++

#include "SessionFixtures.h"
#include <QtTest>
// What a move snaps to; the edits drags leave behind.
namespace {
QUuid insertImage(EditorSession &session, int width, int height, QPointF center)
{
session.insert(ImportedImage(QImage(width, height, QImage::Format_RGBA8888_Premultiplied), QImage(), "Image"), center);
return session.activeLayerID().value();
}
}
class TransformSnapTests : public QObject {
Q_OBJECT
private slots:
void targetsAreTheCanvasAndTheOtherVisibleLayersEdgesAndMiddles();
void snappedMoveNudgesWithinToleranceAndKeepsTheGuides();
void dragsEditsAreNotPersistentAndEndsClearTheGuides();
};
void TransformSnapTests::targetsAreTheCanvasAndTheOtherVisibleLayersEdgesAndMiddles()
{
EditorSession session;
QCOMPARE(session.transformSnapTargets({}), SnapGuides{});
session.createDocument(100, 80);
QCOMPARE(session.transformSnapTargets({}), (SnapGuides{{0, 100, 50}, {0, 80, 40}}));
const QUuid a = insertImage(session, 20, 10, {20, 15});
const QUuid b = insertImage(session, 10, 10, {70, 60});
QCOMPARE(session.transformSnapTargets({}), (SnapGuides{{0, 100, 50, 10, 20, 30, 65, 70, 75}, {0, 80, 40, 10, 15, 20, 55, 60, 65}}));
// The layers being moved are no targets; hidden ones neither.
QCOMPARE(session.transformSnapTargets({a}), (SnapGuides{{0, 100, 50, 65, 70, 75}, {0, 80, 40, 55, 60, 65}}));
session.toggleLayerVisibility(b);
QCOMPARE(session.transformSnapTargets({a}), (SnapGuides{{0, 100, 50}, {0, 80, 40}}));
session.toggleLayerVisibility(b);
// A turned layer offers the box around its corners, rounded.
rewrite(session, [&](ProjectSnapshot &snapshot) { record(snapshot, b).transform = {.origin = {60, 50}, .size = {20, 10}, .rotation = 90}; });
QCOMPARE(session.transformSnapTargets({a}), (SnapGuides{{0, 100, 50, 65, 70, 75}, {0, 80, 40, 45, 55, 65}}));
rewrite(session, [&](ProjectSnapshot &snapshot) { record(snapshot, b).transform = {.origin = {60, 50}, .size = {20, 10}, .rotation = 30}; });
QCOMPARE(session.transformSnapTargets({a}), (SnapGuides{{0, 100, 50, 59, 70, 81}, {0, 80, 40, 46, 55, 64}}));
// A pending edit's placement counts, as the canvas shows it.
session.selectLayer(b);
session.beginTransform();
session.previewTransform({.origin = {50, 50}, .size = {10, 10}});
QCOMPARE(session.transformSnapTargets({a}), (SnapGuides{{0, 100, 50, 50, 55, 60}, {0, 80, 40, 50, 55, 60}}));
session.cancelTransform();
// A blank layer has no pixels to line up with.
session.addBlankLayer();
QCOMPARE(session.transformSnapTargets({a, b}), (SnapGuides{{0, 100, 50}, {0, 80, 40}}));
}
void TransformSnapTests::snappedMoveNudgesWithinToleranceAndKeepsTheGuides()
{
EditorSession session;
session.createDocument(100, 80);
const QUuid a = insertImage(session, 20, 10, {20, 15});
// Middle three off, top two off: both snap.
const LayerTransform draft{.origin = {43, 38}, .size = {20, 10}};
QCOMPARE(session.snappedMove(draft, {a}, 5), (LayerTransform{.origin = {40, 40}, .size = {20, 10}}));
QCOMPARE(session.snapGuides, (SnapGuides{{50}, {40}}));
// Past the tolerance the draft comes back untouched.
QCOMPARE(session.snappedMove(draft, {a}, 1), draft);
QCOMPARE(session.snapGuides, SnapGuides{});
// The nearest of left, middle and right wins, one axis.
const LayerTransform edge{.origin = {98, 60}, .size = {20, 10}};
QCOMPARE(session.snappedMove(edge, {a}, 5), (LayerTransform{.origin = {100, 60}, .size = {20, 10}}));
QCOMPARE(session.snapGuides, (SnapGuides{{100}, {}}));
// A turned draft snaps by the box around its corners.
const LayerTransform turned{.origin = {42, 40}, .size = {20, 10}, .rotation = 90};
QCOMPARE(session.snappedMove(turned, {a}, 3), (LayerTransform{.origin = {40, 40}, .size = {20, 10}, .rotation = 90}));
QCOMPARE(session.snapGuides, (SnapGuides{{50}, {}}));
// Another layer's edge is a target unless it moves too.
const QUuid b = insertImage(session, 10, 10, {70, 60});
const LayerTransform near{.origin = {77, 20}, .size = {20, 10}};
QCOMPARE(session.snappedMove(near, {a}, 2).origin, QPointF(75, 20));
QCOMPARE(session.snappedMove(near, {a, b}, 2).origin, QPointF(77, 20));
// View > Snap off: every draft stays put, guides gone.
const LayerTransform snapped = session.snappedMove(draft, {a}, 5);
QVERIFY(snapped != draft && !session.snapGuides.xs.empty());
QSignalSpy changes(&session, &EditorSession::changed);
// The signal sees the guides gone: the canvas repaints.
std::vector<SnapGuides> heard;
const QMetaObject::Connection listening = connect(&session, &EditorSession::changed, this, [&] { heard.push_back(session.snapGuides); });
session.setSnapEnabled(false);
disconnect(listening);
QVERIFY(!session.snappingEnabled() && changes.count() == 1);
QCOMPARE(heard, std::vector<SnapGuides>{SnapGuides{}});
QCOMPARE(session.snapGuides, SnapGuides{});
session.snapGuides = SnapGuides{{1}, {2}};
QCOMPARE(session.snappedMove(draft, {a}, 5), draft);
QCOMPARE(session.snapGuides, SnapGuides{});
session.setSnapEnabled(true);
QCOMPARE(session.snappedMove(draft, {a}, 5), snapped);
}
void TransformSnapTests::dragsEditsAreNotPersistentAndEndsClearTheGuides()
{
EditorSession session;
session.createDocument(100, 80);
insertImage(session, 20, 10, {20, 15});
session.beginTransform();
QVERIFY(session.transformEdit().value().persistent);
session.snapGuides = {{50}, {}};
session.commitTransform();
QCOMPARE(session.snapGuides, SnapGuides{});
session.beginTransform(false);
QVERIFY(!session.transformEdit().value().persistent);
session.snapGuides = {{}, {40}};
session.cancelTransform();
QCOMPARE(session.snapGuides, SnapGuides{});
// Nothing pending: the ends still clear what a drag left.
session.snapGuides = {{50}, {}};
session.cancelTransform();
QCOMPARE(session.snapGuides, SnapGuides{});
session.snapGuides = {{50}, {}};
session.commitTransform();
QCOMPARE(session.snapGuides, SnapGuides{});
// The Move settings start as Swift's and change on request.
QVERIFY(!session.transformAutoSelect() && session.showsTransformControls() && session.locksTransformRatio());
session.setTransformAutoSelect(true);
session.setShowsTransformControls(false);
session.setLocksTransformRatio(false);
QVERIFY(session.transformAutoSelect() && !session.showsTransformControls() && !session.locksTransformRatio());
}
QTEST_GUILESS_MAIN(TransformSnapTests)
#include "TransformSnapTests.moc"