feat: Add editable angle dimensions to line drawing

Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
2026-02-16 17:42:05 -07:00
parent 93282fce52
commit 9d72fe2155

View File

@@ -202,12 +202,80 @@ void ViewportWidget::paintGL()
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
QString dimInput = property("dimensionInput").toString();
QString angleInput = property("angleInput").toString();
bool lengthFromInput = false;
bool angleFromInput = false;
double inputLength = 0;
double inputAngleDegrees = 0;
if (!dimInput.isEmpty()) {
bool ok;
double inputLength = dimInput.toDouble(&ok);
if (ok) {
lengthFromInput = true;
inputLength = dimInput.toDouble(&ok);
if (ok) lengthFromInput = true;
}
if (!angleInput.isEmpty()) {
bool ok;
inputAngleDegrees = angleInput.toDouble(&ok);
if (ok) angleFromInput = true;
}
if (angleFromInput) {
QVector3D refDir;
if (property("isChainedLine").toBool()) {
refDir = property("previousLineDirection").value<QVector3D>();
} else {
if (m_currentPlane == SketchPlane::XY || m_currentPlane == SketchPlane::XZ) {
refDir = QVector3D(1, 0, 0);
} else { // YZ
refDir = QVector3D(0, 1, 0);
}
}
QVector3D currentMouseWorldPos = unproject(m_currentMousePos, m_currentPlane);
QVector3D mouseVec = currentMouseWorldPos - startPos;
// Quadrant snapping
double mouseAngle;
if (m_currentPlane == SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x()));
else if (m_currentPlane == SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x()));
else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y()));
double refAngle;
if (m_currentPlane == SketchPlane::XY) refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.x()));
else if (m_currentPlane == SketchPlane::XZ) refAngle = qRadiansToDegrees(atan2(refDir.y(), refDir.x()));
else refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.y()));
double relativeMouseAngle = mouseAngle - refAngle;
while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0;
while (relativeMouseAngle > 180.0) relativeMouseAngle -= 360.0;
double snappedAngle = 0;
if (relativeMouseAngle >= -45 && relativeMouseAngle < 45) {
snappedAngle = inputAngleDegrees;
} else if (relativeMouseAngle >= 45 && relativeMouseAngle < 135) {
snappedAngle = 180 - inputAngleDegrees;
} else if (relativeMouseAngle >= 135 || relativeMouseAngle < -135) {
snappedAngle = inputAngleDegrees + 180.0;
} else { // -135 to -45
snappedAngle = 360 - inputAngleDegrees;
}
double finalAngleRad = qDegreesToRadians(refAngle + snappedAngle);
QVector3D finalDir;
if (m_currentPlane == SketchPlane::XY) finalDir = QVector3D(cos(finalAngleRad), 0, sin(finalAngleRad));
else if (m_currentPlane == SketchPlane::XZ) finalDir = QVector3D(cos(finalAngleRad), sin(finalAngleRad), 0);
else finalDir = QVector3D(0, cos(finalAngleRad), sin(finalAngleRad));
double lineLength;
if (lengthFromInput) {
lineLength = inputLength;
} else {
lineLength = QVector3D::dotProduct(mouseVec, finalDir);
if (lineLength < 0) lineLength = 0;
}
worldPos = startPos + lineLength * finalDir;
} else if (lengthFromInput) {
QVector3D currentMouseWorldPos = unproject(m_currentMousePos, m_currentPlane);
QVector3D dir = (currentMouseWorldPos - startPos);
if (dir.length() > 1e-6) {
@@ -220,10 +288,7 @@ void ViewportWidget::paintGL()
worldPos = startPos + QVector3D(0, inputLength, 0);
}
}
}
}
if (!lengthFromInput) {
} else {
worldPos = unproject(m_currentMousePos, m_currentPlane);
if (m_isSnappingOrigin) {
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
@@ -297,9 +362,101 @@ void ViewportWidget::paintGL()
m_vbo.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
glDrawArrays(GL_LINES, 0, vertices.size() / 3);
glLineWidth(2.0f);
// Draw angle dimension
vertices.clear();
QVector3D refDir;
if (property("isChainedLine").toBool()) {
refDir = property("previousLineDirection").value<QVector3D>();
} else {
if (m_currentPlane == SketchPlane::XY || m_currentPlane == SketchPlane::XZ) refDir = QVector3D(1, 0, 0);
else refDir = QVector3D(0, 1, 0);
}
if (!lengthFromInput && (m_isSnappingHorizontal || m_isSnappingVertical)) {
double refAngle, lineAngle;
if (m_currentPlane == SketchPlane::XY) {
refAngle = atan2(refDir.z(), refDir.x());
lineAngle = atan2(lineVec.z(), lineVec.x());
} else if (m_currentPlane == SketchPlane::XZ) {
refAngle = atan2(refDir.y(), refDir.x());
lineAngle = atan2(lineVec.y(), lineVec.x());
} else { // YZ
refAngle = atan2(refDir.z(), refDir.y());
lineAngle = atan2(lineVec.z(), lineVec.y());
}
double angleDiff = lineAngle - refAngle;
while (angleDiff <= -M_PI) angleDiff += 2 * M_PI;
while (angleDiff > M_PI) angleDiff -= 2 * M_PI;
lineAngle = refAngle + angleDiff;
const int numSegments = 30;
const float radius = 0.1f * -m_camera->zoom();
for (int i = 0; i <= numSegments; ++i) {
double angle = refAngle + (lineAngle - refAngle) * i / numSegments;
QVector3D p;
if (m_currentPlane == SketchPlane::XY) p = startPos + radius * QVector3D(cos(angle), 0, sin(angle));
else if (m_currentPlane == SketchPlane::XZ) p = startPos + radius * QVector3D(cos(angle), sin(angle), 0);
else p = startPos + radius * QVector3D(0, cos(angle), sin(angle));
vertices << p.x() << p.y() << p.z();
}
glLineWidth(1.0f);
m_vbo.bind();
m_vbo.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
glDrawArrays(GL_LINE_STRIP, 0, vertices.size() / 3);
// Arrowheads for arc
QVector<GLfloat> arrowVertices;
float arrowLength = 0.02f * -m_camera->zoom();
float arrowWidth = 0.005f * -m_camera->zoom();
// End arrowhead
QVector3D endPoint(vertices[vertices.size()-3], vertices[vertices.size()-2], vertices[vertices.size()-1]);
double endAngle = lineAngle;
QVector3D radialDir_end, tangentDir_end;
if (m_currentPlane == SketchPlane::XY) {
radialDir_end = QVector3D(cos(endAngle), 0, sin(endAngle));
tangentDir_end = QVector3D(-sin(endAngle), 0, cos(endAngle));
} else if (m_currentPlane == SketchPlane::XZ) {
radialDir_end = QVector3D(cos(endAngle), sin(endAngle), 0);
tangentDir_end = QVector3D(-sin(endAngle), cos(endAngle), 0);
} else {
radialDir_end = QVector3D(0, cos(endAngle), sin(endAngle));
tangentDir_end = QVector3D(0, -sin(endAngle), cos(endAngle));
}
QVector3D arrow_base_end = endPoint - arrowLength * tangentDir_end;
QVector3D arrowP1_end = arrow_base_end + arrowWidth * radialDir_end;
QVector3D arrowP2_end = arrow_base_end - arrowWidth * radialDir_end;
arrowVertices << endPoint.x() << endPoint.y() << endPoint.z() << arrowP1_end.x() << arrowP1_end.y() << arrowP1_end.z();
arrowVertices << endPoint.x() << endPoint.y() << endPoint.z() << arrowP2_end.x() << arrowP2_end.y() << arrowP2_end.z();
// Start arrowhead
QVector3D startPoint(vertices[0], vertices[1], vertices[2]);
double startAngle = refAngle;
QVector3D radialDir_start, tangentDir_start;
if (m_currentPlane == SketchPlane::XY) {
radialDir_start = QVector3D(cos(startAngle), 0, sin(startAngle));
tangentDir_start = QVector3D(-sin(startAngle), 0, cos(startAngle));
} else if (m_currentPlane == SketchPlane::XZ) {
radialDir_start = QVector3D(cos(startAngle), sin(startAngle), 0);
tangentDir_start = QVector3D(-sin(startAngle), cos(startAngle), 0);
} else {
radialDir_start = QVector3D(0, cos(startAngle), sin(startAngle));
tangentDir_start = QVector3D(0, -sin(startAngle), cos(startAngle));
}
QVector3D arrow_base_start = startPoint + arrowLength * tangentDir_start;
QVector3D arrowP1_start = arrow_base_start + arrowWidth * radialDir_start;
QVector3D arrowP2_start = arrow_base_start - arrowWidth * radialDir_start;
arrowVertices << startPoint.x() << startPoint.y() << startPoint.z() << arrowP1_start.x() << arrowP1_start.y() << arrowP1_start.z();
arrowVertices << startPoint.x() << startPoint.y() << startPoint.z() << arrowP2_start.x() << arrowP2_start.y() << arrowP2_start.z();
m_vbo.bind();
m_vbo.allocate(arrowVertices.constData(), arrowVertices.size() * sizeof(GLfloat));
glDrawArrays(GL_LINES, 0, arrowVertices.size() / 3);
glLineWidth(2.0f);
}
if (!lengthFromInput && !angleFromInput && (m_isSnappingHorizontal || m_isSnappingVertical)) {
vertices.clear();
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
QVector3D midPoint = (startPos + worldPos) / 2.0;
@@ -356,16 +513,82 @@ void ViewportWidget::paintGL()
QVector3D worldPos;
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
QString dimText;
QString angleText;
QString dimInput = property("dimensionInput").toString();
QString angleInput = property("angleInput").toString();
bool lengthFromInput = false;
bool angleFromInput = false;
double inputLength = 0;
double inputAngleDegrees = 0;
double lineLength = 0;
if (!dimInput.isEmpty()) {
bool ok;
double inputLength = dimInput.toDouble(&ok);
if (ok) {
lengthFromInput = true;
inputLength = dimInput.toDouble(&ok);
if (ok) lengthFromInput = true;
}
if (!angleInput.isEmpty()) {
bool ok;
inputAngleDegrees = angleInput.toDouble(&ok);
if (ok) angleFromInput = true;
}
if (angleFromInput) {
QVector3D refDir;
if (property("isChainedLine").toBool()) {
refDir = property("previousLineDirection").value<QVector3D>();
} else {
if (m_currentPlane == SketchPlane::XY || m_currentPlane == SketchPlane::XZ) {
refDir = QVector3D(1, 0, 0);
} else { // YZ
refDir = QVector3D(0, 1, 0);
}
}
QVector3D currentMouseWorldPos = unproject(m_currentMousePos, m_currentPlane);
QVector3D mouseVec = currentMouseWorldPos - startPos;
double mouseAngle;
if (m_currentPlane == SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x()));
else if (m_currentPlane == SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x()));
else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y()));
double refAngle;
if (m_currentPlane == SketchPlane::XY) refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.x()));
else if (m_currentPlane == SketchPlane::XZ) refAngle = qRadiansToDegrees(atan2(refDir.y(), refDir.x()));
else refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.y()));
double relativeMouseAngle = mouseAngle - refAngle;
while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0;
while (relativeMouseAngle > 180.0) relativeMouseAngle -= 360.0;
double snappedAngle = 0;
if (relativeMouseAngle >= -45 && relativeMouseAngle < 45) {
snappedAngle = inputAngleDegrees;
} else if (relativeMouseAngle >= 45 && relativeMouseAngle < 135) {
snappedAngle = 180 - inputAngleDegrees;
} else if (relativeMouseAngle >= 135 || relativeMouseAngle < -135) {
snappedAngle = inputAngleDegrees + 180.0;
} else { // -135 to -45
snappedAngle = 360 - inputAngleDegrees;
}
double finalAngleRad = qDegreesToRadians(refAngle + snappedAngle);
QVector3D finalDir;
if (m_currentPlane == SketchPlane::XY) finalDir = QVector3D(cos(finalAngleRad), 0, sin(finalAngleRad));
else if (m_currentPlane == SketchPlane::XZ) finalDir = QVector3D(cos(finalAngleRad), sin(finalAngleRad), 0);
else finalDir = QVector3D(0, cos(finalAngleRad), sin(finalAngleRad));
if (lengthFromInput) {
lineLength = inputLength;
} else {
lineLength = QVector3D::dotProduct(mouseVec, finalDir);
if (lineLength < 0) lineLength = 0;
}
worldPos = startPos + lineLength * finalDir;
} else if (lengthFromInput) {
lineLength = inputLength;
QVector3D currentMouseWorldPos = unproject(m_currentMousePos, m_currentPlane);
QVector3D dir = (currentMouseWorldPos - startPos);
@@ -379,10 +602,7 @@ void ViewportWidget::paintGL()
worldPos = startPos + QVector3D(0, inputLength, 0);
}
}
}
}
if (!lengthFromInput) {
} else {
worldPos = unproject(m_currentMousePos, m_currentPlane);
if (m_isSnappingOrigin) {
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
@@ -426,7 +646,7 @@ void ViewportWidget::paintGL()
QRect textRect = fm.boundingRect(dimText + "_");
textRect.moveCenter(screenPos.toPoint());
if (lengthFromInput) {
if (lengthFromInput && property("dimensionEditMode").toString() == "length") {
painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(64, 128, 255));
} else {
painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(50, 50, 50));
@@ -434,6 +654,55 @@ void ViewportWidget::paintGL()
painter.setPen(Qt::white);
painter.drawText(textRect, Qt::AlignCenter, dimText);
}
// Angle dimension text
QVector3D refDir;
if (property("isChainedLine").toBool()) {
refDir = property("previousLineDirection").value<QVector3D>();
} else {
if (m_currentPlane == SketchPlane::XY || m_currentPlane == SketchPlane::XZ) refDir = QVector3D(1, 0, 0);
else refDir = QVector3D(0, 1, 0);
}
double refAngle, lineAngle;
if (m_currentPlane == SketchPlane::XY) {
refAngle = atan2(refDir.z(), refDir.x());
lineAngle = atan2(lineVec.z(), lineVec.x());
} else if (m_currentPlane == SketchPlane::XZ) {
refAngle = atan2(refDir.y(), refDir.x());
lineAngle = atan2(lineVec.y(), lineVec.x());
} else { // YZ
refAngle = atan2(refDir.z(), refDir.y());
lineAngle = atan2(lineVec.z(), lineVec.y());
}
double angleDiffDegrees = qRadiansToDegrees(lineAngle - refAngle);
while (angleDiffDegrees <= -180.0) angleDiffDegrees += 360.0;
while (angleDiffDegrees > 180.0) angleDiffDegrees -= 360.0;
angleText = angleFromInput ? angleInput : QString::number(qAbs(angleDiffDegrees), 'f', 1) + QChar(0x00B0);
const float radius = 0.1f * -m_camera->zoom();
double midAngle = refAngle + (lineAngle - refAngle) / 2.0;
QVector3D textPos3DAngle;
float textOffset = 0.035f * -m_camera->zoom();
if (m_currentPlane == SketchPlane::XY) textPos3DAngle = startPos + (radius + textOffset) * QVector3D(cos(midAngle), 0, sin(midAngle));
else if (m_currentPlane == SketchPlane::XZ) textPos3DAngle = startPos + (radius + textOffset) * QVector3D(cos(midAngle), sin(midAngle), 0);
else textPos3DAngle = startPos + (radius + textOffset) * QVector3D(0, cos(midAngle), sin(midAngle));
QVector3D screenPosAngle = project(textPos3DAngle, model, projection, rect());
if (screenPosAngle.z() < 1.0f) {
QRect angleTextRect = fm.boundingRect(angleText + "_");
angleTextRect.moveCenter(screenPosAngle.toPoint());
if (angleFromInput && property("dimensionEditMode").toString() == "angle") {
painter.fillRect(angleTextRect.adjusted(-4, -2, 4, 2), QColor(64, 128, 255));
} else {
painter.fillRect(angleTextRect.adjusted(-4, -2, 4, 2), QColor(50, 50, 50));
}
painter.setPen(Qt::white);
painter.drawText(angleTextRect, Qt::AlignCenter, angleText);
}
}
}
@@ -483,10 +752,20 @@ void ViewportWidget::mousePressEvent(QMouseEvent *event)
m_firstLinePoint = p;
m_isDefiningLine = true;
setProperty("dimensionInput", QVariant(""));
setProperty("angleInput", QVariant(""));
setProperty("dimensionEditMode", "length");
setProperty("isChainedLine", false);
} else {
QVector3D start(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
QVector3D end(p.X(), p.Y(), p.Z());
setProperty("previousLineDirection", QVariant::fromValue((end - start).normalized()));
emit lineAdded(m_firstLinePoint, p);
m_firstLinePoint = p;
setProperty("dimensionInput", QVariant(""));
setProperty("angleInput", QVariant(""));
setProperty("dimensionEditMode", "length");
setProperty("isChainedLine", true);
}
update();
}
@@ -629,52 +908,136 @@ void ViewportWidget::wheelEvent(QWheelEvent *event)
void ViewportWidget::keyPressEvent(QKeyEvent *event)
{
if (m_isDefiningLine && m_activeTool == static_cast<int>(ApplicationController::ToolType::Line)) {
QString currentInput = property("dimensionInput").toString();
if (event->key() == Qt::Key_Tab) {
QString currentMode = property("dimensionEditMode").toString();
if (currentMode == "length") {
setProperty("dimensionEditMode", "angle");
} else {
setProperty("dimensionEditMode", "length");
}
update();
return;
}
QString editMode = property("dimensionEditMode").toString();
const char* propertyName = (editMode == "length") ? "dimensionInput" : "angleInput";
QString currentInput = property(propertyName).toString();
if (event->key() >= Qt::Key_0 && event->key() <= Qt::Key_9) {
currentInput += event->text();
setProperty("dimensionInput", currentInput);
setProperty(propertyName, currentInput);
update();
return;
} else if (event->key() == Qt::Key_Period) {
if (!currentInput.contains('.')) {
currentInput += '.';
setProperty("dimensionInput", currentInput);
setProperty(propertyName, currentInput);
update();
return;
}
} else if (event->key() == Qt::Key_Backspace) {
if (!currentInput.isEmpty()) {
currentInput.chop(1);
setProperty("dimensionInput", currentInput);
setProperty(propertyName, currentInput);
update();
return;
}
} else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
bool ok;
double length = currentInput.toDouble(&ok);
if (ok && length > 0) {
QVector3D worldPos = unproject(m_currentMousePos, m_currentPlane);
QVector3D worldPos;
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
QVector3D dir = (worldPos - startPos);
// This is duplicated from paintGL to ensure consistent line creation
QString dimInput = property("dimensionInput").toString();
QString angleInput = property("angleInput").toString();
bool lengthFromInput = false;
bool angleFromInput = false;
double inputLength = 0;
double inputAngleDegrees = 0;
if (!dimInput.isEmpty()) {
bool ok;
inputLength = dimInput.toDouble(&ok);
if (ok) lengthFromInput = true;
}
if (!angleInput.isEmpty()) {
bool ok;
inputAngleDegrees = angleInput.toDouble(&ok);
if (ok) angleFromInput = true;
}
if (angleFromInput) {
QVector3D refDir;
if (property("isChainedLine").toBool()) {
refDir = property("previousLineDirection").value<QVector3D>();
} else {
if (m_currentPlane == SketchPlane::XY || m_currentPlane == SketchPlane::XZ) refDir = QVector3D(1, 0, 0);
else refDir = QVector3D(0, 1, 0);
}
QVector3D currentMouseWorldPos = unproject(m_currentMousePos, m_currentPlane);
QVector3D mouseVec = currentMouseWorldPos - startPos;
double mouseAngle;
if (m_currentPlane == SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x()));
else if (m_currentPlane == SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x()));
else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y()));
double refAngle;
if (m_currentPlane == SketchPlane::XY) refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.x()));
else if (m_currentPlane == SketchPlane::XZ) refAngle = qRadiansToDegrees(atan2(refDir.y(), refDir.x()));
else refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.y()));
double relativeMouseAngle = mouseAngle - refAngle;
while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0;
while (relativeMouseAngle > 180.0) relativeMouseAngle -= 360.0;
double snappedAngle = 0;
if (relativeMouseAngle >= -45 && relativeMouseAngle < 45) snappedAngle = inputAngleDegrees;
else if (relativeMouseAngle >= 45 && relativeMouseAngle < 135) snappedAngle = 180 - inputAngleDegrees;
else if (relativeMouseAngle >= 135 || relativeMouseAngle < -135) snappedAngle = inputAngleDegrees + 180.0;
else snappedAngle = 360 - inputAngleDegrees;
double finalAngleRad = qDegreesToRadians(refAngle + snappedAngle);
QVector3D finalDir;
if (m_currentPlane == SketchPlane::XY) finalDir = QVector3D(cos(finalAngleRad), 0, sin(finalAngleRad));
else if (m_currentPlane == SketchPlane::XZ) finalDir = QVector3D(cos(finalAngleRad), sin(finalAngleRad), 0);
else finalDir = QVector3D(0, cos(finalAngleRad), sin(finalAngleRad));
double lineLength;
if (lengthFromInput) lineLength = inputLength;
else {
lineLength = QVector3D::dotProduct(mouseVec, finalDir);
if (lineLength < 0) lineLength = 0;
}
worldPos = startPos + lineLength * finalDir;
} else if (lengthFromInput) {
QVector3D currentMouseWorldPos = unproject(m_currentMousePos, m_currentPlane);
QVector3D dir = (currentMouseWorldPos - startPos);
if (dir.length() > 1e-6) {
dir.normalize();
QVector3D endPos = startPos + length * dir;
worldPos = startPos + inputLength * dir;
} else {
if (m_currentPlane == SketchPlane::XY || m_currentPlane == SketchPlane::XZ) worldPos = startPos + QVector3D(inputLength, 0, 0);
else worldPos = startPos + QVector3D(0, inputLength, 0);
}
} else {
worldPos = unproject(m_currentMousePos, m_currentPlane);
}
gp_Pnt p;
p.SetCoord(endPos.x(), endPos.y(), endPos.z());
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
QVector3D prevDir = (worldPos - startPos).normalized();
setProperty("previousLineDirection", QVariant::fromValue(prevDir));
emit lineAdded(m_firstLinePoint, p);
m_firstLinePoint = p; // for chained lines
m_firstLinePoint = p;
setProperty("dimensionInput", QVariant(""));
setProperty("angleInput", QVariant(""));
setProperty("dimensionEditMode", "length");
setProperty("isChainedLine", true);
update();
return;
}
}
}
}
if (event->key() == Qt::Key_Escape) {
if (m_isDefiningLine) {
m_isDefiningLine = false;
setProperty("dimensionInput", QVariant(""));
setProperty("angleInput", QVariant(""));
emit toolDeactivated();
update();
return;