feat: Allow editable rectangle dimensions and fix Tab crash
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
@@ -199,13 +199,64 @@ void ViewportWidget::paintGL()
|
||||
|
||||
if (m_isDefiningRectangle && m_activeTool == static_cast<int>(ApplicationController::ToolType::Rectangle)) {
|
||||
vertices.clear();
|
||||
QVector3D worldPos = unproject(m_currentMousePos, m_currentPlane);
|
||||
QVector3D worldPos;
|
||||
QVector3D startPos(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z());
|
||||
|
||||
if (m_isSnappingOrigin) {
|
||||
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
|
||||
} else if (m_isSnappingVertex) {
|
||||
worldPos.setX(m_snapVertex.X()); worldPos.setY(m_snapVertex.Y()); worldPos.setZ(m_snapVertex.Z());
|
||||
QString widthInput = property("widthInput").toString();
|
||||
QString heightInput = property("heightInput").toString();
|
||||
bool widthFromInput = false;
|
||||
bool heightFromInput = false;
|
||||
double inputWidth = 0, inputHeight = 0;
|
||||
|
||||
if (!widthInput.isEmpty()) {
|
||||
bool ok;
|
||||
inputWidth = widthInput.toDouble(&ok);
|
||||
if (ok) widthFromInput = true;
|
||||
}
|
||||
if (!heightInput.isEmpty()) {
|
||||
bool ok;
|
||||
inputHeight = heightInput.toDouble(&ok);
|
||||
if (ok) heightFromInput = true;
|
||||
}
|
||||
|
||||
QVector3D mousePos = unproject(m_currentMousePos, m_currentPlane);
|
||||
|
||||
if (widthFromInput || heightFromInput) {
|
||||
QVector3D mouseDir = mousePos - startPos;
|
||||
double current_w, current_h;
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.y());
|
||||
} else { // YZ
|
||||
current_w = qAbs(mouseDir.y());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
}
|
||||
double rect_w = widthFromInput ? inputWidth : current_w;
|
||||
double rect_h = heightFromInput ? inputHeight : current_h;
|
||||
int signX = (mouseDir.x() >= 0) ? 1 : -1;
|
||||
int signY = (mouseDir.y() >= 0) ? 1 : -1;
|
||||
int signZ = (mouseDir.z() >= 0) ? 1 : -1;
|
||||
worldPos = startPos;
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
worldPos.setX(startPos.x() + signX * rect_w);
|
||||
worldPos.setZ(startPos.z() + signZ * rect_h);
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
worldPos.setX(startPos.x() + signX * rect_w);
|
||||
worldPos.setY(startPos.y() + signY * rect_h);
|
||||
} else { // YZ
|
||||
worldPos.setY(startPos.y() + signY * rect_w);
|
||||
worldPos.setZ(startPos.z() + signZ * rect_h);
|
||||
}
|
||||
} else {
|
||||
worldPos = mousePos;
|
||||
if (m_isSnappingOrigin) {
|
||||
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
|
||||
} else if (m_isSnappingVertex) {
|
||||
worldPos.setX(m_snapVertex.X()); worldPos.setY(m_snapVertex.Y()); worldPos.setZ(m_snapVertex.Z());
|
||||
}
|
||||
}
|
||||
|
||||
QVector3D p1 = startPos;
|
||||
@@ -587,14 +638,65 @@ void ViewportWidget::paintGL()
|
||||
m_featureBrowser->paint(painter, width(), height());
|
||||
|
||||
if (m_isDefiningRectangle && m_activeTool == static_cast<int>(ApplicationController::ToolType::Rectangle)) {
|
||||
QVector3D worldPos = unproject(m_currentMousePos, m_currentPlane);
|
||||
if (m_isSnappingOrigin) {
|
||||
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
|
||||
} else if (m_isSnappingVertex) {
|
||||
worldPos.setX(m_snapVertex.X()); worldPos.setY(m_snapVertex.Y()); worldPos.setZ(m_snapVertex.Z());
|
||||
QVector3D worldPos;
|
||||
QVector3D p1_3d(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z());
|
||||
|
||||
QString widthInput = property("widthInput").toString();
|
||||
QString heightInput = property("heightInput").toString();
|
||||
bool widthFromInput = false;
|
||||
bool heightFromInput = false;
|
||||
double inputWidth = 0, inputHeight = 0;
|
||||
|
||||
if (!widthInput.isEmpty()) {
|
||||
bool ok;
|
||||
inputWidth = widthInput.toDouble(&ok);
|
||||
if (ok) widthFromInput = true;
|
||||
}
|
||||
if (!heightInput.isEmpty()) {
|
||||
bool ok;
|
||||
inputHeight = heightInput.toDouble(&ok);
|
||||
if (ok) heightFromInput = true;
|
||||
}
|
||||
|
||||
QVector3D p1_3d(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z());
|
||||
QVector3D mousePos = unproject(m_currentMousePos, m_currentPlane);
|
||||
|
||||
if (widthFromInput || heightFromInput) {
|
||||
QVector3D mouseDir = mousePos - p1_3d;
|
||||
double current_w, current_h;
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.y());
|
||||
} else { // YZ
|
||||
current_w = qAbs(mouseDir.y());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
}
|
||||
double rect_w = widthFromInput ? inputWidth : current_w;
|
||||
double rect_h = heightFromInput ? inputHeight : current_h;
|
||||
int signX = (mouseDir.x() >= 0) ? 1 : -1;
|
||||
int signY = (mouseDir.y() >= 0) ? 1 : -1;
|
||||
int signZ = (mouseDir.z() >= 0) ? 1 : -1;
|
||||
worldPos = p1_3d;
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
worldPos.setX(p1_3d.x() + signX * rect_w);
|
||||
worldPos.setZ(p1_3d.z() + signZ * rect_h);
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
worldPos.setX(p1_3d.x() + signX * rect_w);
|
||||
worldPos.setY(p1_3d.y() + signY * rect_h);
|
||||
} else { // YZ
|
||||
worldPos.setY(p1_3d.y() + signY * rect_w);
|
||||
worldPos.setZ(p1_3d.z() + signZ * rect_h);
|
||||
}
|
||||
} else {
|
||||
worldPos = mousePos;
|
||||
if (m_isSnappingOrigin) {
|
||||
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
|
||||
} else if (m_isSnappingVertex) {
|
||||
worldPos.setX(m_snapVertex.X()); worldPos.setY(m_snapVertex.Y()); worldPos.setZ(m_snapVertex.Z());
|
||||
}
|
||||
}
|
||||
QVector3D p3_3d = worldPos;
|
||||
QVector3D p2_3d, p4_3d;
|
||||
|
||||
@@ -624,10 +726,14 @@ void ViewportWidget::paintGL()
|
||||
QVector3D widthTextPos3D = (p1_3d + p2_3d) / 2.0f;
|
||||
QVector3D screenPosW = project(widthTextPos3D, model, projection, rect());
|
||||
if (screenPosW.z() < 1.0f) {
|
||||
QString widthText = QString::number(w, 'f', 2);
|
||||
QString widthText = widthFromInput ? widthInput : QString::number(w, 'f', 2);
|
||||
QRect textRect = fm.boundingRect(widthText + "__");
|
||||
textRect.moveCenter(screenPosW.toPoint() + QPoint(0, (p3_3d.z() > p1_3d.z() || p3_3d.y() > p1_3d.y()) ? -15 : 15));
|
||||
painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(50, 50, 50));
|
||||
if (property("dimensionEditMode").toString() == "width") {
|
||||
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));
|
||||
}
|
||||
painter.setPen(Qt::white);
|
||||
painter.drawText(textRect, Qt::AlignCenter, widthText);
|
||||
}
|
||||
@@ -636,10 +742,14 @@ void ViewportWidget::paintGL()
|
||||
QVector3D heightTextPos3D = (p2_3d + p3_3d) / 2.0f;
|
||||
QVector3D screenPosH = project(heightTextPos3D, model, projection, rect());
|
||||
if (screenPosH.z() < 1.0f) {
|
||||
QString heightText = QString::number(h, 'f', 2);
|
||||
QString heightText = heightFromInput ? heightInput : QString::number(h, 'f', 2);
|
||||
QRect textRect = fm.boundingRect(heightText + "__");
|
||||
textRect.moveCenter(screenPosH.toPoint() + QPoint((p3_3d.x() > p1_3d.x()) ? 15 : -15, 0));
|
||||
painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(50, 50, 50));
|
||||
if (property("dimensionEditMode").toString() == "height") {
|
||||
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));
|
||||
}
|
||||
painter.setPen(Qt::white);
|
||||
painter.drawText(textRect, Qt::AlignCenter, heightText);
|
||||
}
|
||||
@@ -905,21 +1015,84 @@ void ViewportWidget::mousePressEvent(QMouseEvent *event)
|
||||
|
||||
if (m_currentPlane != SketchPlane::NONE && m_activeTool == static_cast<int>(ApplicationController::ToolType::Rectangle)) {
|
||||
gp_Pnt p;
|
||||
if (m_isSnappingOrigin) {
|
||||
p.SetCoord(0, 0, 0);
|
||||
} else if (m_isSnappingVertex) {
|
||||
p = m_snapVertex;
|
||||
} else {
|
||||
QVector3D worldPos = unproject(event->pos(), m_currentPlane);
|
||||
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
}
|
||||
|
||||
if (!m_isDefiningRectangle) {
|
||||
if (m_isSnappingOrigin) {
|
||||
p.SetCoord(0, 0, 0);
|
||||
} else if (m_isSnappingVertex) {
|
||||
p = m_snapVertex;
|
||||
} else {
|
||||
QVector3D worldPos = unproject(event->pos(), m_currentPlane);
|
||||
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
}
|
||||
m_firstRectanglePoint = p;
|
||||
m_isDefiningRectangle = true;
|
||||
setProperty("widthInput", "");
|
||||
setProperty("heightInput", "");
|
||||
setProperty("dimensionEditMode", "height");
|
||||
} else {
|
||||
QVector3D worldPos;
|
||||
QVector3D startPos(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z());
|
||||
|
||||
QString widthInput = property("widthInput").toString();
|
||||
QString heightInput = property("heightInput").toString();
|
||||
bool widthFromInput = false, heightFromInput = false;
|
||||
double inputWidth = 0, inputHeight = 0;
|
||||
|
||||
if (!widthInput.isEmpty()) {
|
||||
bool ok;
|
||||
inputWidth = widthInput.toDouble(&ok);
|
||||
if (ok) widthFromInput = true;
|
||||
}
|
||||
if (!heightInput.isEmpty()) {
|
||||
bool ok;
|
||||
inputHeight = heightInput.toDouble(&ok);
|
||||
if (ok) heightFromInput = true;
|
||||
}
|
||||
|
||||
if (widthFromInput || heightFromInput) {
|
||||
QVector3D mousePos = unproject(event->pos(), m_currentPlane);
|
||||
QVector3D mouseDir = mousePos - startPos;
|
||||
double current_w, current_h;
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.y());
|
||||
} else { // YZ
|
||||
current_w = qAbs(mouseDir.y());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
}
|
||||
double rect_w = widthFromInput ? inputWidth : current_w;
|
||||
double rect_h = heightFromInput ? inputHeight : current_h;
|
||||
int signX = (mouseDir.x() >= 0) ? 1 : -1;
|
||||
int signY = (mouseDir.y() >= 0) ? 1 : -1;
|
||||
int signZ = (mouseDir.z() >= 0) ? 1 : -1;
|
||||
worldPos = startPos;
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
worldPos.setX(startPos.x() + signX * rect_w);
|
||||
worldPos.setZ(startPos.z() + signZ * rect_h);
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
worldPos.setX(startPos.x() + signX * rect_w);
|
||||
worldPos.setY(startPos.y() + signY * rect_h);
|
||||
} else { // YZ
|
||||
worldPos.setY(startPos.y() + signY * rect_w);
|
||||
worldPos.setZ(startPos.z() + signZ * rect_h);
|
||||
}
|
||||
} else {
|
||||
if (m_isSnappingOrigin) {
|
||||
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
|
||||
} else if (m_isSnappingVertex) {
|
||||
worldPos = QVector3D(m_snapVertex.X(), m_snapVertex.Y(), m_snapVertex.Z());
|
||||
} else {
|
||||
worldPos = unproject(event->pos(), m_currentPlane);
|
||||
}
|
||||
}
|
||||
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
emit rectangleAdded(m_firstRectanglePoint, p);
|
||||
m_isDefiningRectangle = false;
|
||||
setProperty("widthInput", "");
|
||||
setProperty("heightInput", "");
|
||||
}
|
||||
update();
|
||||
return;
|
||||
@@ -1316,6 +1489,107 @@ void ViewportWidget::keyPressEvent(QKeyEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
if (m_isDefiningRectangle && m_activeTool == static_cast<int>(ApplicationController::ToolType::Rectangle)) {
|
||||
if (event->key() == Qt::Key_Tab) {
|
||||
QString currentMode = property("dimensionEditMode").toString();
|
||||
if (currentMode == "width") {
|
||||
setProperty("dimensionEditMode", "height");
|
||||
} else {
|
||||
setProperty("dimensionEditMode", "width");
|
||||
}
|
||||
update();
|
||||
return;
|
||||
}
|
||||
|
||||
QString editMode = property("dimensionEditMode").toString();
|
||||
const char* propertyName = (editMode == "width") ? "widthInput" : "heightInput";
|
||||
QString currentInput = property(propertyName).toString();
|
||||
|
||||
if (event->key() >= Qt::Key_0 && event->key() <= Qt::Key_9) {
|
||||
currentInput += event->text();
|
||||
setProperty(propertyName, currentInput);
|
||||
update();
|
||||
return;
|
||||
} else if (event->key() == Qt::Key_Period) {
|
||||
if (!currentInput.contains('.')) {
|
||||
currentInput += '.';
|
||||
setProperty(propertyName, currentInput);
|
||||
update();
|
||||
return;
|
||||
}
|
||||
} else if (event->key() == Qt::Key_Backspace) {
|
||||
if (!currentInput.isEmpty()) {
|
||||
currentInput.chop(1);
|
||||
setProperty(propertyName, currentInput);
|
||||
update();
|
||||
return;
|
||||
}
|
||||
} else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
|
||||
QVector3D worldPos;
|
||||
QVector3D startPos(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z());
|
||||
|
||||
QString widthInput = property("widthInput").toString();
|
||||
QString heightInput = property("heightInput").toString();
|
||||
bool widthFromInput = false, heightFromInput = false;
|
||||
double inputWidth = 0, inputHeight = 0;
|
||||
|
||||
if (!widthInput.isEmpty()) {
|
||||
bool ok;
|
||||
inputWidth = widthInput.toDouble(&ok);
|
||||
if (ok) widthFromInput = true;
|
||||
}
|
||||
if (!heightInput.isEmpty()) {
|
||||
bool ok;
|
||||
inputHeight = heightInput.toDouble(&ok);
|
||||
if (ok) heightFromInput = true;
|
||||
}
|
||||
|
||||
if (widthFromInput || heightFromInput) {
|
||||
QVector3D mousePos = unproject(m_currentMousePos, m_currentPlane);
|
||||
QVector3D mouseDir = mousePos - startPos;
|
||||
double current_w, current_h;
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.y());
|
||||
} else { // YZ
|
||||
current_w = qAbs(mouseDir.y());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
}
|
||||
double rect_w = widthFromInput ? inputWidth : current_w;
|
||||
double rect_h = heightFromInput ? inputHeight : current_h;
|
||||
int signX = (mouseDir.x() >= 0) ? 1 : -1;
|
||||
int signY = (mouseDir.y() >= 0) ? 1 : -1;
|
||||
int signZ = (mouseDir.z() >= 0) ? 1 : -1;
|
||||
worldPos = startPos;
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
worldPos.setX(startPos.x() + signX * rect_w);
|
||||
worldPos.setZ(startPos.z() + signZ * rect_h);
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
worldPos.setX(startPos.x() + signX * rect_w);
|
||||
worldPos.setY(startPos.y() + signY * rect_h);
|
||||
} else { // YZ
|
||||
worldPos.setY(startPos.y() + signY * rect_w);
|
||||
worldPos.setZ(startPos.z() + signZ * rect_h);
|
||||
}
|
||||
} else {
|
||||
worldPos = unproject(m_currentMousePos, m_currentPlane);
|
||||
}
|
||||
|
||||
gp_Pnt p;
|
||||
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
|
||||
emit rectangleAdded(m_firstRectanglePoint, p);
|
||||
m_isDefiningRectangle = false;
|
||||
setProperty("widthInput", "");
|
||||
setProperty("heightInput", "");
|
||||
update();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (event->key() == Qt::Key_Escape) {
|
||||
if (m_isDefiningLine) {
|
||||
m_isDefiningLine = false;
|
||||
@@ -1327,6 +1601,8 @@ void ViewportWidget::keyPressEvent(QKeyEvent *event)
|
||||
}
|
||||
if (m_isDefiningRectangle) {
|
||||
m_isDefiningRectangle = false;
|
||||
setProperty("widthInput", "");
|
||||
setProperty("heightInput", "");
|
||||
emit toolDeactivated();
|
||||
update();
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user