Merge pull request #1412 from bhangart/fix/mirror-twice-keeps-position

Mirror a symbol twice and it comes back where it was
This commit is contained in:
ispyisail
2026-10-09 22:45:58 +13:00
committed by GitHub
2 changed files with 47 additions and 3 deletions
@@ -83,15 +83,17 @@ MirrorSelectionCommand::MirrorSelectionCommand(const QList<Element *> &elements,
//The mirror is about the element's hotspot, which is often a
//corner of the symbol: move it so that it stays where it was,
//centre on centre, and on the grid
//centre on centre. The move is snapped to the grid, not the new
//position: an element on the grid stays on it, one off the grid
//keeps its offset, and a second mirror moves it exactly back.
QPointF centre = element->boundingRect().center();
centre = QTransform::fromScale(new_horizontal ? -1 : 1, new_vertical ? -1 : 1)
.map(centre);
centre = QTransform().rotate(element->rotation()).map(centre);
const QPointF old_pos = element->pos();
const QPointF new_pos = Diagram::snapToGrid(
element->mapToScene(element->boundingRect().center()) - centre);
const QPointF new_pos = old_pos + Diagram::snapToGrid(
element->mapToScene(element->boundingRect().center()) - centre - old_pos);
if (new_pos != old_pos)
new QPropertyUndoCommand(element, "pos", old_pos, new_pos, this);
}
+42
View File
@@ -191,6 +191,48 @@ private slots:
r.value(QStringLiteral("v")).toArray());
}
/**
Mirroring a symbol twice the same way puts it back where it was,
for every symbol of the project, including those that do not sit
on the grid. Before, the second mirror snapped such a symbol onto
the grid, a few pixels away. Which symbol mirrorBackAndSave()
picks changes from run to run, so this checks them all.
*/
void mirrorTwiceComesBack_data()
{
QTest::addColumn<bool>("vertical");
QTest::newRow("horizontal") << false;
QTest::newRow("vertical") << true;
}
void mirrorTwiceComesBack()
{
QFETCH(bool, vertical);
const QJsonObject r = run(script(QStringLiteral(
"var out = {count: 0, moved: []};\n"
"for (var f = 0; f < qet.folioCount(); f++) {\n"
" var els = qet.elementUuids(f);\n"
" for (var e = 0; e < els.length; e++) {\n"
" var before = JSON.stringify(terms(f, els[e]));\n"
" qet.mirrorElement(f, els[e], %1);\n"
" qet.mirrorElement(f, els[e], %1);\n"
" var after = JSON.stringify(terms(f, els[e]));\n"
" out.count++;\n"
" if (after !== before) out.moved.push(els[e] + ' ' + before + ' -> ' + after);\n"
" }\n"
"}\n"
"qet.log('PROBE ' + JSON.stringify(out));\n")
.arg(vertical ? QStringLiteral("true") : QStringLiteral("false"))),
QStringLiteral(QET_EXAMPLES_DIR "/perceuse.qet"));
QVERIFY2(!r.isEmpty(), "the script logged nothing");
QVERIFY(r.value(QStringLiteral("count")).toInt() > 0);
const QJsonArray moved = r.value(QStringLiteral("moved")).toArray();
for (const QJsonValue &m : moved)
qWarning("moved: %s", qPrintable(m.toString()));
QCOMPARE(moved.size(), 0);
}
/**
On a turned symbol a mirror of the folio is the other mirror of the
symbol itself, and its rotation does not change: a label kept