Refactor: Abstract dimension input and finalize creation logic to SketchTool

Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
2026-02-17 14:58:02 -07:00
parent d66f7aaf56
commit e1327b2caa
6 changed files with 243 additions and 269 deletions

View File

@@ -14,20 +14,17 @@ LineTool::LineTool(ViewportWidget* viewport)
void LineTool::activate() void LineTool::activate()
{ {
m_isDefiningLine = false; SketchTool::activate();
m_dimensionModes << "length" << "angle";
m_dimensionPropertyNames["length"] = "dimensionInput";
m_dimensionPropertyNames["angle"] = "angleInput";
m_viewport->setProperty("dimensionInput", ""); m_viewport->setProperty("dimensionInput", "");
m_viewport->setProperty("angleInput", ""); m_viewport->setProperty("angleInput", "");
m_viewport->setProperty("dimensionEditMode", "length"); m_viewport->setProperty("dimensionEditMode", "length");
m_viewport->setProperty("isChainedLine", false); m_viewport->setProperty("isChainedLine", false);
} }
void LineTool::deactivate()
{
m_isDefiningLine = false;
m_viewport->setProperty("dimensionInput", "");
m_viewport->setProperty("angleInput", "");
}
void LineTool::mousePressEvent(QMouseEvent *event) void LineTool::mousePressEvent(QMouseEvent *event)
{ {
gp_Pnt p; gp_Pnt p;
@@ -38,7 +35,7 @@ void LineTool::mousePressEvent(QMouseEvent *event)
double inputLength = 0; double inputLength = 0;
double inputAngleDegrees = 0; double inputAngleDegrees = 0;
if (m_isDefiningLine) { if (m_isDefining) {
if (!dimInput.isEmpty()) { if (!dimInput.isEmpty()) {
bool ok; bool ok;
inputLength = dimInput.toDouble(&ok); inputLength = dimInput.toDouble(&ok);
@@ -51,7 +48,7 @@ void LineTool::mousePressEvent(QMouseEvent *event)
} }
} }
if (m_isDefiningLine && (lengthFromInput || angleFromInput)) { if (m_isDefining && (lengthFromInput || angleFromInput)) {
QVector3D worldPos; QVector3D worldPos;
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z()); QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
@@ -130,9 +127,9 @@ void LineTool::mousePressEvent(QMouseEvent *event)
} }
} }
if (!m_isDefiningLine) { if (!m_isDefining) {
m_firstLinePoint = p; m_firstLinePoint = p;
m_isDefiningLine = true; m_isDefining = true;
m_viewport->setProperty("dimensionInput", QVariant("")); m_viewport->setProperty("dimensionInput", QVariant(""));
m_viewport->setProperty("angleInput", QVariant("")); m_viewport->setProperty("angleInput", QVariant(""));
m_viewport->setProperty("dimensionEditMode", "length"); m_viewport->setProperty("dimensionEditMode", "length");
@@ -158,7 +155,7 @@ void LineTool::mouseMoveEvent(QMouseEvent *event)
m_viewport->setSnappingHorizontal(false); m_viewport->setSnappingHorizontal(false);
m_viewport->setSnappingVertical(false); m_viewport->setSnappingVertical(false);
if (m_isDefiningLine && !m_viewport->isSnappingOrigin() && !m_viewport->isSnappingVertex()) { if (m_isDefining && !m_viewport->isSnappingOrigin() && !m_viewport->isSnappingVertex()) {
QVector3D worldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); QVector3D worldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z()); QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
QVector3D delta = worldPos - startPos; QVector3D delta = worldPos - startPos;
@@ -188,44 +185,8 @@ void LineTool::mouseMoveEvent(QMouseEvent *event)
} }
} }
void LineTool::keyPressEvent(QKeyEvent *event) void LineTool::finalizeCreation()
{ {
if (m_isDefiningLine) {
if (event->key() == Qt::Key_Tab) {
QString currentMode = m_viewport->property("dimensionEditMode").toString();
if (currentMode == "length") {
m_viewport->setProperty("dimensionEditMode", "angle");
} else {
m_viewport->setProperty("dimensionEditMode", "length");
}
m_viewport->update();
return;
}
QString editMode = m_viewport->property("dimensionEditMode").toString();
const char* propertyName = (editMode == "length") ? "dimensionInput" : "angleInput";
QString currentInput = m_viewport->property(propertyName).toString();
if (event->key() >= Qt::Key_0 && event->key() <= Qt::Key_9) {
currentInput += event->text();
m_viewport->setProperty(propertyName, currentInput);
m_viewport->update();
return;
} else if (event->key() == Qt::Key_Period) {
if (!currentInput.contains('.')) {
currentInput += '.';
m_viewport->setProperty(propertyName, currentInput);
m_viewport->update();
}
return;
} else if (event->key() == Qt::Key_Backspace) {
if (!currentInput.isEmpty()) {
currentInput.chop(1);
m_viewport->setProperty(propertyName, currentInput);
m_viewport->update();
}
return;
} else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
QVector3D worldPos; QVector3D worldPos;
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z()); QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
// This is duplicated from paintGL to ensure consistent line creation // This is duplicated from paintGL to ensure consistent line creation
@@ -316,20 +277,11 @@ void LineTool::keyPressEvent(QKeyEvent *event)
m_viewport->setProperty("angleInput", QVariant("")); m_viewport->setProperty("angleInput", QVariant(""));
m_viewport->setProperty("dimensionEditMode", "length"); m_viewport->setProperty("dimensionEditMode", "length");
m_viewport->setProperty("isChainedLine", true); m_viewport->setProperty("isChainedLine", true);
m_viewport->update();
return;
} else if (event->key() == Qt::Key_Escape) {
deactivate();
m_viewport->deactivateActiveTool();
m_viewport->update();
return;
}
}
} }
void LineTool::paintGL() void LineTool::paintGL()
{ {
if (m_isDefiningLine) { if (m_isDefining) {
QVector<GLfloat> vertices; QVector<GLfloat> vertices;
QVector3D worldPos; QVector3D worldPos;
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z()); QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
@@ -662,7 +614,7 @@ void LineTool::paintGL()
void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection) void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection)
{ {
if (m_isDefiningLine) { if (m_isDefining) {
QVector3D worldPos; QVector3D worldPos;
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z()); QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
QString dimText; QString dimText;

View File

@@ -12,16 +12,16 @@ public:
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
void paintGL() override; void paintGL() override;
void paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection) override; void paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection) override;
void activate() override; void activate() override;
void deactivate() override;
protected:
void finalizeCreation() override;
private: private:
bool m_isDefiningLine = false;
gp_Pnt m_firstLinePoint; gp_Pnt m_firstLinePoint;
}; };

View File

@@ -16,23 +16,20 @@ RectangleTool::RectangleTool(ViewportWidget* viewport)
void RectangleTool::activate() void RectangleTool::activate()
{ {
m_isDefiningRectangle = false; SketchTool::activate();
m_dimensionModes << "height" << "width";
m_dimensionPropertyNames["height"] = "heightInput";
m_dimensionPropertyNames["width"] = "widthInput";
m_viewport->setProperty("widthInput", ""); m_viewport->setProperty("widthInput", "");
m_viewport->setProperty("heightInput", ""); m_viewport->setProperty("heightInput", "");
m_viewport->setProperty("dimensionEditMode", "height"); m_viewport->setProperty("dimensionEditMode", "height");
} }
void RectangleTool::deactivate()
{
m_isDefiningRectangle = false;
m_viewport->setProperty("widthInput", "");
m_viewport->setProperty("heightInput", "");
}
void RectangleTool::mousePressEvent(QMouseEvent *event) void RectangleTool::mousePressEvent(QMouseEvent *event)
{ {
gp_Pnt p; gp_Pnt p;
if (!m_isDefiningRectangle) { if (!m_isDefining) {
if (m_viewport->isSnappingOrigin()) { if (m_viewport->isSnappingOrigin()) {
p.SetCoord(0, 0, 0); p.SetCoord(0, 0, 0);
} else if (m_viewport->isSnappingVertex()) { } else if (m_viewport->isSnappingVertex()) {
@@ -42,7 +39,7 @@ void RectangleTool::mousePressEvent(QMouseEvent *event)
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z()); p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
} }
m_firstRectanglePoint = p; m_firstRectanglePoint = p;
m_isDefiningRectangle = true; m_isDefining = true;
m_viewport->setProperty("widthInput", ""); m_viewport->setProperty("widthInput", "");
m_viewport->setProperty("heightInput", ""); m_viewport->setProperty("heightInput", "");
m_viewport->setProperty("dimensionEditMode", "height"); m_viewport->setProperty("dimensionEditMode", "height");
@@ -116,44 +113,8 @@ void RectangleTool::mouseMoveEvent(QMouseEvent *event)
// To be implemented // To be implemented
} }
void RectangleTool::keyPressEvent(QKeyEvent *event) void RectangleTool::finalizeCreation()
{ {
if (m_isDefiningRectangle) {
if (event->key() == Qt::Key_Tab) {
QString currentMode = m_viewport->property("dimensionEditMode").toString();
if (currentMode == "width") {
m_viewport->setProperty("dimensionEditMode", "height");
} else {
m_viewport->setProperty("dimensionEditMode", "width");
}
m_viewport->update();
return;
}
QString editMode = m_viewport->property("dimensionEditMode").toString();
const char* propertyName = (editMode == "width") ? "widthInput" : "heightInput";
QString currentInput = m_viewport->property(propertyName).toString();
if (event->key() >= Qt::Key_0 && event->key() <= Qt::Key_9) {
currentInput += event->text();
m_viewport->setProperty(propertyName, currentInput);
m_viewport->update();
return;
} else if (event->key() == Qt::Key_Period) {
if (!currentInput.contains('.')) {
currentInput += '.';
m_viewport->setProperty(propertyName, currentInput);
m_viewport->update();
}
return;
} else if (event->key() == Qt::Key_Backspace) {
if (!currentInput.isEmpty()) {
currentInput.chop(1);
m_viewport->setProperty(propertyName, currentInput);
m_viewport->update();
}
return;
} else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
QVector3D worldPos; QVector3D worldPos;
QVector3D startPos(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z()); QVector3D startPos(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z());
@@ -212,20 +173,11 @@ void RectangleTool::keyPressEvent(QKeyEvent *event)
emit m_viewport->rectangleAdded(m_firstRectanglePoint, p); emit m_viewport->rectangleAdded(m_firstRectanglePoint, p);
deactivate(); deactivate();
m_viewport->update();
return;
} else if (event->key() == Qt::Key_Escape) {
deactivate();
m_viewport->deactivateActiveTool();
m_viewport->update();
return;
}
}
} }
void RectangleTool::paintGL() void RectangleTool::paintGL()
{ {
if (m_isDefiningRectangle) { if (m_isDefining) {
QVector<GLfloat> vertices; QVector<GLfloat> vertices;
QVector3D worldPos; QVector3D worldPos;
QVector3D startPos(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z()); QVector3D startPos(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z());
@@ -320,7 +272,7 @@ void RectangleTool::paintGL()
void RectangleTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection) void RectangleTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection)
{ {
if (m_isDefiningRectangle) { if (m_isDefining) {
QVector3D worldPos; QVector3D worldPos;
QVector3D p1_3d(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z()); QVector3D p1_3d(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z());

View File

@@ -12,16 +12,16 @@ public:
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
void paintGL() override; void paintGL() override;
void paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection) override; void paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection) override;
void activate() override; void activate() override;
void deactivate() override;
protected:
void finalizeCreation() override;
private: private:
bool m_isDefiningRectangle = false;
gp_Pnt m_firstRectanglePoint; gp_Pnt m_firstRectanglePoint;
}; };

View File

@@ -1,5 +1,6 @@
#include "SketchTool.h" #include "SketchTool.h"
#include "ViewportWidget.h" #include "ViewportWidget.h"
#include <QKeyEvent>
SketchTool::SketchTool(ViewportWidget* viewport) SketchTool::SketchTool(ViewportWidget* viewport)
: QObject(viewport), m_viewport(viewport) : QObject(viewport), m_viewport(viewport)
@@ -8,8 +9,71 @@ SketchTool::SketchTool(ViewportWidget* viewport)
void SketchTool::activate() void SketchTool::activate()
{ {
m_isDefining = false;
} }
void SketchTool::deactivate() void SketchTool::deactivate()
{ {
m_isDefining = false;
for (const QString& propName : m_dimensionPropertyNames.values()) {
m_viewport->setProperty(propName, "");
}
m_dimensionModes.clear();
m_dimensionPropertyNames.clear();
}
void SketchTool::keyPressEvent(QKeyEvent *event)
{
if (m_isDefining) {
if (event->key() == Qt::Key_Tab) {
if (m_dimensionModes.size() > 1) {
QString currentMode = m_viewport->property("dimensionEditMode").toString();
int currentIndex = m_dimensionModes.indexOf(currentMode);
if (currentIndex != -1) {
int nextIndex = (currentIndex + 1) % m_dimensionModes.size();
m_viewport->setProperty("dimensionEditMode", m_dimensionModes[nextIndex]);
m_viewport->update();
}
}
return;
}
QString editMode = m_viewport->property("dimensionEditMode").toString();
if (m_dimensionPropertyNames.contains(editMode)) {
QString propertyName = m_dimensionPropertyNames[editMode];
QString currentInput = m_viewport->property(propertyName).toString();
if (event->key() >= Qt::Key_0 && event->key() <= Qt::Key_9) {
currentInput += event->text();
m_viewport->setProperty(propertyName, currentInput);
m_viewport->update();
return;
} else if (event->key() == Qt::Key_Period) {
if (!currentInput.contains('.')) {
currentInput += '.';
m_viewport->setProperty(propertyName, currentInput);
m_viewport->update();
}
return;
} else if (event->key() == Qt::Key_Backspace) {
if (!currentInput.isEmpty()) {
currentInput.chop(1);
m_viewport->setProperty(propertyName, currentInput);
m_viewport->update();
}
return;
}
}
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
finalizeCreation();
m_viewport->update();
return;
} else if (event->key() == Qt::Key_Escape) {
deactivate();
m_viewport->deactivateActiveTool();
m_viewport->update();
return;
}
}
} }

View File

@@ -2,6 +2,8 @@
#define SKETCHTOOL_H #define SKETCHTOOL_H
#include <QObject> #include <QObject>
#include <QStringList>
#include <QMap>
class QMouseEvent; class QMouseEvent;
class QKeyEvent; class QKeyEvent;
@@ -19,7 +21,7 @@ public:
virtual void mousePressEvent(QMouseEvent *event) = 0; virtual void mousePressEvent(QMouseEvent *event) = 0;
virtual void mouseMoveEvent(QMouseEvent *event) = 0; virtual void mouseMoveEvent(QMouseEvent *event) = 0;
virtual void keyPressEvent(QKeyEvent *event) = 0; virtual void keyPressEvent(QKeyEvent *event);
virtual void paintGL() = 0; virtual void paintGL() = 0;
virtual void paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection) = 0; virtual void paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection) = 0;
@@ -28,7 +30,11 @@ public:
virtual void deactivate(); virtual void deactivate();
protected: protected:
virtual void finalizeCreation() = 0;
ViewportWidget* m_viewport; ViewportWidget* m_viewport;
bool m_isDefining = false;
QStringList m_dimensionModes;
QMap<QString, QString> m_dimensionPropertyNames;
}; };
#endif // SKETCHTOOL_H #endif // SKETCHTOOL_H