From 489e3ca6fcc3716791d2217019642efb7e5d39e6 Mon Sep 17 00:00:00 2001 From: WandererFan Date: Mon, 13 Oct 2025 12:21:31 -0400 Subject: [PATCH] TechDraw: fix leader positioning (snapping) (#24468) * [TD]specialize leader snap handling * [TD]fix leader live update regression * [TD]QGTracker code clean-up --- src/Mod/TechDraw/App/DrawLeaderLine.h | 2 + src/Mod/TechDraw/App/DrawView.h | 2 + src/Mod/TechDraw/Gui/QGIView.cpp | 4 ++ src/Mod/TechDraw/Gui/QGTracker.cpp | 65 +++++++++------------------ src/Mod/TechDraw/Gui/QGTracker.h | 7 +-- 5 files changed, 29 insertions(+), 51 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawLeaderLine.h b/src/Mod/TechDraw/App/DrawLeaderLine.h index 0e1bb33258..c7e8bb7381 100644 --- a/src/Mod/TechDraw/App/DrawLeaderLine.h +++ b/src/Mod/TechDraw/App/DrawLeaderLine.h @@ -93,6 +93,8 @@ public: Base::Vector3d lastSegmentDirection() const; + bool snapsToPosition() const override { return false; } + private: diff --git a/src/Mod/TechDraw/App/DrawView.h b/src/Mod/TechDraw/App/DrawView.h index ee8e3878ed..5d84f45ce7 100644 --- a/src/Mod/TechDraw/App/DrawView.h +++ b/src/Mod/TechDraw/App/DrawView.h @@ -127,6 +127,8 @@ public: static bool isProjGroupItem(DrawViewPart* item); + virtual bool snapsToPosition() const { return true; } + protected: void onBeforeChange(const App::Property *prop) override; void onChanged(const App::Property* prop) override; diff --git a/src/Mod/TechDraw/Gui/QGIView.cpp b/src/Mod/TechDraw/Gui/QGIView.cpp index 9c581c9b71..8a9e85db65 100644 --- a/src/Mod/TechDraw/Gui/QGIView.cpp +++ b/src/Mod/TechDraw/Gui/QGIView.cpp @@ -293,6 +293,10 @@ void QGIView::snapPosition(QPointF& newPosition) return; } + if (!feature->snapsToPosition()) { + return; + } + auto dvp = freecad_cast(feature); if (dvp && !dvp->hasGeometry()) { diff --git a/src/Mod/TechDraw/Gui/QGTracker.cpp b/src/Mod/TechDraw/Gui/QGTracker.cpp index 99040c575a..8d47127a68 100644 --- a/src/Mod/TechDraw/Gui/QGTracker.cpp +++ b/src/Mod/TechDraw/Gui/QGTracker.cpp @@ -51,10 +51,10 @@ using namespace TechDrawGui; QGTracker::QGTracker(QGSPage* inScene, TrackerMode m): m_sleep(false), m_qgParent(nullptr), + m_trackerMode(m), m_lastClick(QPointF(std::numeric_limits::max(), std::numeric_limits::max())) { - setTrackerMode(m); if (inScene) { inScene->addItem(this); } else { @@ -71,26 +71,12 @@ QGTracker::QGTracker(QGSPage* inScene, TrackerMode m): setZValue(ZVALUE::TRACKER); setPos(0.0, 0.0); - QColor tColor = getTrackerColor(); - QColor tailColor(Qt::blue); + setNormalColor(getTrackerColor()); double tWeight = getTrackerWeight(); setWidth(tWeight); setStyle(Qt::DashLine); - setNormalColor(tailColor); setPrettyNormal(); - //m_track is the new segment of the line. - m_track = new QGraphicsPathItem(); - m_track->setParentItem(this); - m_trackPen.setColor(tColor); - m_trackPen.setWidthF(tWeight); - m_trackPen.setStyle(Qt::DashLine); - m_track->setPen(m_trackPen); - m_track->setBrush(QBrush(Qt::NoBrush)); - m_track->setFlag(QGraphicsItem::ItemSendsScenePositionChanges, true); - m_track->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); - m_track->setFocusProxy(this); - setHandlesChildEvents(true); setVisible(true); setEnabled(true); @@ -98,9 +84,6 @@ QGTracker::QGTracker(QGSPage* inScene, TrackerMode m): scene()->setFocusItem(this); } -QGTracker::~QGTracker() -{ -} void QGTracker::mousePressEvent(QGraphicsSceneMouseEvent *event) { @@ -177,11 +160,13 @@ void QGTracker::sleep(bool b) QPointF QGTracker::snapToAngle(QPointF dumbPt) { // If no point selected yet, snapping has no sense - if (m_points.empty()) + if (m_points.empty()) { return dumbPt; + } QPointF result(dumbPt); - double angleIncr = std::numbers::pi / 8.0; //15* + constexpr double stepsInHalfCircle{8.0}; + double angleIncr = std::numbers::pi / stepsInHalfCircle; //mirror last clicked point and event point to get sensible coords QPointF last(m_points.back().x(), -m_points.back().y()); QPointF pt(dumbPt.x(), -dumbPt.y()); @@ -193,7 +178,7 @@ QPointF QGTracker::snapToAngle(QPointF dumbPt) actual = (2 * std::numbers::pi) + actual; //map to +ve angle } - double intPart; + double intPart{0}; double remain = modf(actual/angleIncr, &intPart); if (!TechDraw::DrawUtil::fpCompare(remain, 0.0)) { //not n*15 double low = intPart * angleIncr; @@ -324,40 +309,31 @@ QPainterPath QGTracker::shape() const //actual art routines void QGTracker::drawTrackLine(QPointF pos) { - m_segEnd = pos; - QPainterPath tail; if (!m_points.empty()) { - m_segBegin = m_points.back(); - tail.moveTo(m_segBegin); - tail.lineTo(m_segEnd); - m_track->setPath(tail); - m_track->show(); + std::vector entireTrack = m_points; + entireTrack.push_back(pos); + setPathFromPoints(entireTrack); } } void QGTracker::drawTrackSquare(QPointF pos) { - m_segEnd = pos; - QPainterPath tail; if (!m_points.empty()) { - m_segBegin = m_points.front(); //sb front? 1st point picked?? - QRectF rect(m_segBegin, m_segEnd); - tail.addRect(rect); - m_track->setPath(tail); - m_track->show(); + std::vector oppositeCorners; + oppositeCorners.push_back(m_points.front()); + oppositeCorners.push_back(pos); + setSquareFromPoints(oppositeCorners); } } void QGTracker::drawTrackCircle(QPointF pos) { - QPointF circum = pos; QPainterPath tail; if (!m_points.empty()) { - QPointF center = m_points.front(); //not nec (0, 0); - QPointF ray = circum - center; - double radius = sqrt(pow(ray.x(), 2.0) + pow(ray.y(), 2.0)); - tail.addEllipse(center, radius, radius); - m_track->setPath(tail); + std::vector centerAndCircumference; + centerAndCircumference.push_back(m_points.front()); + centerAndCircumference.push_back(pos); + setCircleFromPoints(centerAndCircumference); } } @@ -407,7 +383,7 @@ void QGTracker::setCircleFromPoints(std::vector pts) QPointF center = pts.front(); QPointF circum = pts.back(); QPointF ray = circum - center; - double radius = sqrt(pow(ray.x(), 2.0) + pow(ray.y(), 2.0)); + double radius = sqrt(pow(ray.x(), 2) + pow(ray.y(), 2)); newPath.addEllipse(center, radius, radius); setPath(newPath); setPrettyNormal(); @@ -443,7 +419,6 @@ std::vector QGTracker::convertPoints() void QGTracker::terminateDrawing() { - m_track->hide(); setCursor(Qt::ArrowCursor); Q_EMIT drawingFinished(m_points, m_qgParent); } @@ -460,7 +435,7 @@ void QGTracker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QColor QGTracker::getTrackerColor() { - Base::Color trackColor = Base::Color((uint32_t) Preferences::getPreferenceGroup("Tracker")->GetUnsigned("TrackerColor", 0xFF000000)); + Base::Color trackColor = Base::Color((uint32_t) Preferences::getPreferenceGroup("Tracker")->GetUnsigned("TrackerColor", 0x0000FFFF)); return PreferencesGui::getAccessibleQColor(trackColor.asValue()); } diff --git a/src/Mod/TechDraw/Gui/QGTracker.h b/src/Mod/TechDraw/Gui/QGTracker.h index d4e32c552c..30d805a108 100644 --- a/src/Mod/TechDraw/Gui/QGTracker.h +++ b/src/Mod/TechDraw/Gui/QGTracker.h @@ -68,8 +68,7 @@ public: }; explicit QGTracker(QGSPage* scene = nullptr, TrackerMode m = TrackerMode::None); - ~QGTracker() override; - + ~QGTracker() override = default; enum {Type = UserType::QGTracker}; @@ -113,14 +112,10 @@ protected: double getTrackerWeight(); private: - QGraphicsPathItem* m_track; - QPointF m_segBegin; - QPointF m_segEnd; std::vector m_points; bool m_sleep; QGIView* m_qgParent; TrackerMode m_trackerMode; - QPen m_trackPen; QPen m_tailPen; QPointF m_lastClick; };