From 5c5f2c41a0327943cc5e2a33297ef40f2326ad7c Mon Sep 17 00:00:00 2001 From: wandererfan Date: Fri, 20 Dec 2019 01:45:42 -0500 Subject: [PATCH] [TD]fix LeaderLine point edit --- src/Mod/TechDraw/App/DrawLeaderLine.cpp | 21 +- src/Mod/TechDraw/App/DrawLeaderLine.h | 1 + src/Mod/TechDraw/Gui/QGEPath.cpp | 223 ++++---------- src/Mod/TechDraw/Gui/QGEPath.h | 40 +-- src/Mod/TechDraw/Gui/QGILeaderLine.cpp | 375 ++++++++++++------------ src/Mod/TechDraw/Gui/QGILeaderLine.h | 26 +- 6 files changed, 298 insertions(+), 388 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawLeaderLine.cpp b/src/Mod/TechDraw/App/DrawLeaderLine.cpp index b24dd49c61..bf725d2df8 100644 --- a/src/Mod/TechDraw/App/DrawLeaderLine.cpp +++ b/src/Mod/TechDraw/App/DrawLeaderLine.cpp @@ -68,8 +68,8 @@ DrawLeaderLine::DrawLeaderLine(void) Rotation.setStatus(App::Property::Hidden,true); Caption.setStatus(App::Property::Hidden,true); - //generally, lines/leaders are not meant to move around. LockPosition.setValue(true); + LockPosition.setStatus(App::Property::Hidden,true); } DrawLeaderLine::~DrawLeaderLine() @@ -104,7 +104,7 @@ short DrawLeaderLine::mustExecute() const App::DocumentObjectExecReturn *DrawLeaderLine::execute(void) { -// Base::Console().Message("DL::execute()\n"); +// Base::Console().Message("DLL::execute()\n"); if (!keepUpdated()) { return App::DocumentObject::StdReturn; } @@ -144,6 +144,22 @@ bool DrawLeaderLine::keepUpdated(void) return result; } +//need separate getParentScale()??? + +double DrawLeaderLine::getBaseScale(void) const +{ +// Base::Console().Message("DLL::getBaseScale()\n"); + double result = 1.0; + DrawView* parent = getBaseView(); + if (parent != nullptr) { + result = parent->getScale(); + } else { + //TARFU + Base::Console().Log("DrawLeaderLine - %s - scale not found. Using 1.0. \n", getNameInDocument()); + } + return result; +} + double DrawLeaderLine::getScale(void) const { // Base::Console().Message("DLL::getScale()\n"); @@ -157,7 +173,6 @@ double DrawLeaderLine::getScale(void) const Base::Console().Log("DrawLeaderLine - %s - scale not found. Using 1.0. \n", getNameInDocument()); } } -// Base::Console().Message("DLL::getScale - returns: %.3f\n", result); return result; } diff --git a/src/Mod/TechDraw/App/DrawLeaderLine.h b/src/Mod/TechDraw/App/DrawLeaderLine.h index 634b4f24d0..4ebf183672 100644 --- a/src/Mod/TechDraw/App/DrawLeaderLine.h +++ b/src/Mod/TechDraw/App/DrawLeaderLine.h @@ -63,6 +63,7 @@ public: virtual App::DocumentObject* getBaseObject(void) const; bool keepUpdated(void); double getScale(void) const override; + double getBaseScale(void) const; void adjustLastSegment(void); bool getDefAuto(void) const; diff --git a/src/Mod/TechDraw/Gui/QGEPath.cpp b/src/Mod/TechDraw/Gui/QGEPath.cpp index 915c1ddac7..2f0cee456a 100644 --- a/src/Mod/TechDraw/Gui/QGEPath.cpp +++ b/src/Mod/TechDraw/Gui/QGEPath.cpp @@ -36,13 +36,17 @@ #include #include +#include + #include "DrawGuiStd.h" #include "QGIPrimPath.h" #include "QGIVertex.h" #include "QGIView.h" +#include "QGILeaderLine.h" #include "QGEPath.h" using namespace TechDrawGui; +using namespace TechDraw; QGMarker::QGMarker(int idx) : QGIVertex(idx), m_dragging(false) @@ -81,8 +85,7 @@ void QGMarker::mousePressEvent(QGraphicsSceneMouseEvent * event) } else if(scene() && this == scene()->mouseGrabberItem()) { //start dragging m_dragging = true; - QPointF mapped = mapToParent(event->pos()); - Q_EMIT dragging(mapped, getProjIndex()); + Q_EMIT dragging(pos(), getProjIndex()); //pass center of marker[i] to epath } QGIVertex::mousePressEvent(event); } @@ -105,8 +108,7 @@ void QGMarker::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) if (m_dragging) { m_dragging = false; setSelected(false); - QPointF mapped = mapToParent(event->pos()); - Q_EMIT dragFinished(mapped, getProjIndex()); + Q_EMIT dragFinished(pos(), getProjIndex()); //pass center of marker[i] to epath } } QGIVertex::mouseReleaseEvent(event); @@ -142,22 +144,6 @@ void QGMarker::setRadius(float r) setPath(p); } -//void QGMarker::setShape(int s) -//{ -// m_markerShape = s; -//} - -QRectF QGMarker::boundingRect() const -{ - return QGIVertex::boundingRect(); -} - -QPainterPath QGMarker::shape() const -{ - return QGIVertex::shape(); -} - - void QGMarker::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) { QStyleOptionGraphicsItem myOption(*option); @@ -170,11 +156,10 @@ void QGMarker::paint ( QPainter * painter, const QStyleOptionGraphicsItem * opti //****************************************************************************** -QGEPath::QGEPath() : - m_attach(QPointF(0.0,0.0)), +QGEPath::QGEPath(QGILeaderLine* leader) : m_scale(1.0), m_inEdit(false), - m_parentItem(nullptr), + m_parentLeader(leader), m_startAdj(0.0), m_endAdj(0.0) { @@ -182,16 +167,10 @@ QGEPath::QGEPath() : setAcceptHoverEvents(true); setFlag(QGraphicsItem::ItemIsSelectable, true); setFlag(QGraphicsItem::ItemIsMovable, false); -// setFlag(QGraphicsItem::ItemSendsScenePositionChanges, true); setFlag(QGraphicsItem::ItemSendsScenePositionChanges, false); setFlag(QGraphicsItem::ItemSendsGeometryChanges,true); - QGraphicsItem* parent = parentItem(); - QGIView* pView = dynamic_cast(parent); - if (pView != nullptr) { - m_parentItem = pView; - } - m_ghost = new QGIPrimPath(); + m_ghost = new QGIPrimPath(); //drawing/editing line m_ghost->setParentItem(this); m_ghost->setNormalColor(Qt::red); m_ghost->setStyle(Qt::DashLine); @@ -243,44 +222,31 @@ void QGEPath::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) // QGIPrimPath::hoverLeaveEvent(event); //QGIPP::hoverleave will reset pretty to normal } -void QGEPath::startPathEdit() +void QGEPath::startPathEdit(std::vector pathPoints) { // Base::Console().Message("QGEPath::startPathEdit()\n"); inEdit(true); - m_saveDeltas = m_deltas; - showMarkers(m_deltas); + m_ghostPoints = pathPoints; + showMarkers(m_ghostPoints); } -void QGEPath::restoreState() -{ -// Base::Console().Message("QGEPath::restoreState()\n"); - inEdit(false); - if (m_ghost != nullptr) { - if (m_ghost->scene() != nullptr) { - scene()->removeItem(m_ghost); //stop ghost from messing up brect - } - } - m_deltas = m_saveDeltas; - updatePath(); -} - - -void QGEPath::showMarkers(std::vector deltas) +void QGEPath::showMarkers(std::vector points) { // Base::Console().Message("QGEPath::showMarkers()\n"); if (!inEdit()) { return; } - QGraphicsItem* qgepParent = parentItem(); - if (qgepParent == nullptr) { - Base::Console().Error("QGEPath::showMarkers - no parent item\n"); + + if (points.empty()) { + Base::Console().Message("QGEP::showMarkers - no deltas\n"); return; } clearMarkers(); +// dumpGhostPoints("QGEPath::showMarkers"); int pointDx = 0; - for (auto& p: deltas) { + for (auto& p: points) { QGMarker* v = new QGMarker(pointDx); v->setFlag(QGraphicsItem::ItemIsMovable, true); v->setFlag(QGraphicsItem::ItemIsFocusable, true); @@ -306,7 +272,7 @@ void QGEPath::showMarkers(std::vector deltas) v->setRadius(50.0); v->setNormalColor(QColor(Qt::black)); v->setZValue(ZVALUE::VERTEX); - v->setPos(p * m_scale); + v->setPos(p); v->show(); m_markers.push_back(v); @@ -334,15 +300,13 @@ void QGEPath::clearMarkers() } // end of node marker drag -void QGEPath::onDragFinished(QPointF pos, int markerIndex) +void QGEPath::onDragFinished(QPointF dragEndPos, int markerIndex) { -// Base::Console().Message("QGEPath::onDragFinished()\n"); - if ((int) m_points.size() > markerIndex) { - m_points.at(markerIndex) = pos / m_scale; - } - makeDeltasFromPoints(m_points); - if (markerIndex == 0) { - Q_EMIT attachMoved(m_points.front()); +// Base::Console().Message("QGEPath::onDragFinished(%s, %d)\n", +// TechDraw::DrawUtil::formatVector(dragEndPos).c_str(), +// markerIndex); + if ((int) m_ghostPoints.size() > markerIndex) { + m_ghostPoints.at(markerIndex) = dragEndPos; } drawGhost(); } @@ -371,82 +335,49 @@ void QGEPath::onEndEdit(void) scene()->removeItem(m_ghost); //stop ghost from messing up brect } inEdit(false); - updatePath(); - updateFeature(); //Q_EMIT pointsUpdated(m_deltas) ==> onLineEditComplete <<<1 + + updateParent(); //Q_EMIT pointsUpdated(m_featDeltas) ==> onLineEditComplete <<< clearMarkers(); } -//updates the painterpath using our deltas -//path is (0,0),d(p1-p0), d(p2-p1),... -void QGEPath::updatePath(void) +std::vector QGEPath::getDeltasFromLeader(void) { -// Base::Console().Message("QGEPath::updatePath() - scale: %.3f\n", m_scale); - if (m_deltas.empty()) { - Base::Console().Warning("QGEPath::updatePath - no points\n"); - return; + std::vector qDeltas; + if (m_parentLeader == nullptr) { + Base::Console().Message("QGEP::getDeltasFromLeader - m_parentLeader is nullptr\n"); + return qDeltas; } - QPainterPath result; - prepareGeometryChange(); - QPointF startAdjVec(0.0,0.0); - QPointF endAdjVec(0.0,0.0); - if (m_deltas.size() > 1) { - startAdjVec = m_deltas.at(1) - m_deltas.front(); - endAdjVec = (*(m_deltas.end() - 2))- m_deltas.back(); - //this next bit is ugly. - QVector2D startTemp(startAdjVec); - QVector2D endTemp(endAdjVec); - startTemp.normalize(); - endTemp.normalize(); - startAdjVec = startTemp.toPointF() * m_startAdj; - endAdjVec = endTemp.toPointF() * m_endAdj; - std::vector tempDeltas = m_deltas; - tempDeltas.front() += startAdjVec; - tempDeltas.back() += endAdjVec; - result.moveTo(tempDeltas.front()); - for (int i = 1; i < (int)tempDeltas.size(); i++) { - result.lineTo(tempDeltas.at(i) * m_scale); - } - } - setPath(result); -} -QPointF QGEPath::makeDeltasFromPoints(void) -{ - return makeDeltasFromPoints(m_points); -} + DrawLeaderLine* featLeader = m_parentLeader->getFeature(); + if (featLeader == nullptr) { + Base::Console().Message("QGEP::getDeltasFromLeader - featLeader is nullptr\n"); + return qDeltas; + } -QPointF QGEPath::makeDeltasFromPoints(std::vector pts) -{ - m_points = pts; -// Base::Console().Message("QGEPath::makeDeltasFromPoints(%d)\n",pts.size()); - QPointF firstPt(0.0,0.0); - if (pts.empty()) { - Base::Console().Warning("QGEPath::makeDeltasFromPoints - no points\n"); - return firstPt; + std::vector vDeltas = featLeader->WayPoints.getValues(); + for (auto& d: vDeltas) { + Base::Vector3d vTemp = Rez::guiX(d); + QPointF temp(vTemp.x, -vTemp.y); + qDeltas.push_back(temp); } - std::vector deltas; - firstPt = pts.front(); - QPointF newStart(0.0,0.0); - deltas.push_back(newStart); - unsigned int i = 1; - for (; i < pts.size(); i++) { - QPointF mapped = pts.at(i) - firstPt; - deltas.push_back(mapped); + if (qDeltas.empty()) { + Base::Console().Warning("QGEPath::getDeltasFromLeader - no points\n"); } - m_deltas = deltas; - return firstPt; + return qDeltas; } //announce points editing is finished -void QGEPath::updateFeature(void) +void QGEPath::updateParent(void) { -// Base::Console().Message("QGEPath::updateFeature() - inEdit: %d pts: %d\n",inEdit(),m_points.size()); - QPointF attach = m_points.front(); +// Base::Console().Message("QGEPath::updateParent() - inEdit: %d pts: %d\n",inEdit(), m_ghostPoints.size()); +// dumpGhostPoints("QGEP::updateParent"); + QPointF attach = m_ghostPoints.front(); if (!inEdit()) { - Q_EMIT pointsUpdated(attach, m_deltas); + Q_EMIT pointsUpdated(attach, m_ghostPoints); } } +//the ghost is the red line drawn when creating or editing the Leader points void QGEPath::drawGhost(void) { // Base::Console().Message("QGEPath::drawGhost()\n"); @@ -454,9 +385,9 @@ void QGEPath::drawGhost(void) m_ghost->setParentItem(this); } QPainterPath qpp; - qpp.moveTo(m_points.front()); - for (int i = 1; i < (int)m_points.size(); i++) { - qpp.lineTo(m_points.at(i)); + qpp.moveTo(m_ghostPoints.front()); + for (int i = 1; i < (int)m_ghostPoints.size(); i++) { + qpp.lineTo(m_ghostPoints.at(i)); } m_ghost->setPath(qpp); m_ghost->show(); @@ -494,7 +425,6 @@ QPainterPath QGEPath::shape() const return result; } - void QGEPath::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) { QStyleOptionGraphicsItem myOption(*option); myOption.state &= ~QStyle::State_Selected; @@ -504,50 +434,11 @@ void QGEPath::paint ( QPainter * painter, const QStyleOptionGraphicsItem * optio QGIPrimPath::paint (painter, &myOption, widget); } -void QGEPath::addPoint(unsigned int before, unsigned int after) -{ - std::vector deltaCopy = getDeltas(); - unsigned int iMax = deltaCopy.size() - 1; - if ( (after <= before) || - (after > iMax) ) { - Base::Console().Message("QGEP::addPoint - parameter out of range\n"); - return; - } - QPointF bPt = deltaCopy.at(before); - QPointF aPt = deltaCopy.at(after); - QPointF newPt = (bPt + aPt) / 2.0; - deltaCopy.insert(deltaCopy.begin() + after, newPt); - setDeltas(deltaCopy); -} - -void QGEPath::deletePoint(unsigned int atX) -{ - std::vector deltaCopy = getDeltas(); - unsigned int iMax = deltaCopy.size() - 1; - if ( (atX < 1) || //can't delete attach point - (atX > iMax) ) { - Base::Console().Message("QGEP::deletePoint - parameter out of range\n"); - return; - } - deltaCopy.erase(deltaCopy.begin() + (unsigned int) atX); - setDeltas(deltaCopy); -} - -void QGEPath::dumpDeltas(const char* text) +void QGEPath::dumpGhostPoints(const char* text) { int idb = 0; - for (auto& d: m_deltas) { - Base::Console().Message("QGEP - %s - delta: %d %s\n", text, - idb,TechDraw::DrawUtil::formatVector(d).c_str()); - idb++; - } -} - -void QGEPath::dumpPoints(const char* text) -{ - int idb = 0; - for (auto& d: m_points) { - Base::Console().Message("QGEP - %s - point: %d %s\n", text, + for (auto& d: m_ghostPoints) { + Base::Console().Message("%s - point: %d %s\n", text, idb,TechDraw::DrawUtil::formatVector(d).c_str()); idb++; } diff --git a/src/Mod/TechDraw/Gui/QGEPath.h b/src/Mod/TechDraw/Gui/QGEPath.h index b1669c299e..bc5907cb4e 100644 --- a/src/Mod/TechDraw/Gui/QGEPath.h +++ b/src/Mod/TechDraw/Gui/QGEPath.h @@ -23,7 +23,6 @@ #ifndef TECHDRAWGUI_EDITABLEPATH_H #define TECHDRAWGUI_EDITABLEPATH_H -/*#include */ #include #include #include @@ -49,8 +48,6 @@ public: enum {Type = QGraphicsItem::UserType + 302}; int type() const override { return Type;} - virtual QRectF boundingRect() const override; - virtual QPainterPath shape() const override; virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ) override; virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; @@ -79,13 +76,11 @@ private: //****************************************************************************** -//the path is in item coords, starting at (0,0) - ie delta vectors between nodes. -// The QGEPath item is positioned at "attachment point" of the view. class TechDrawGuiExport QGEPath : public QObject, public QGIPrimPath { Q_OBJECT public: - explicit QGEPath(void); + explicit QGEPath(QGILeaderLine* leader); virtual ~QGEPath() {} enum {Type = QGraphicsItem::UserType + 301}; @@ -96,32 +91,23 @@ public: void inEdit(bool b) { m_inEdit = b; } bool inEdit(void) { return m_inEdit; } - void startPathEdit(); + void startPathEdit(std::vector pathPoints); void showMarkers(std::vector points); void clearMarkers(); - void addPoint(unsigned int before, unsigned int after); - void deletePoint(unsigned int atX); - void setDeltas(std::vector pts) { m_deltas = pts; } - std::vector getDeltas(void) { return m_deltas; } + std::vector getDeltasFromLeader(void); + void setScale(double s) { m_scale = s; } double getScale(void) { return m_scale; } - void setAttach(QPointF s) { m_attach = s; } - void setAttach(Base::Vector3d v) { m_attach = QPointF(v.x, v.y); } - QPointF getAttach(void) { return m_attach; } - QPointF makeDeltasFromPoints(std::vector pts); - QPointF makeDeltasFromPoints(void); - void setPoints(std::vector pts) { m_points = pts; } - void updatePath(); - void updateFeature(); + void setPoints(std::vector pts) { m_ghostPoints = pts; } + + void updateParent(); void drawGhost(void); - void dumpDeltas(const char* text); - void dumpPoints(const char* text); + void dumpGhostPoints(const char* text); void dumpMarkerPos(const char* text); - void restoreState(void); void setStartAdjust(double adjust); void setEndAdjust(double adjust); @@ -133,7 +119,6 @@ public Q_SLOTS: Q_SIGNALS: void pointsUpdated(QPointF attach, std::vector deltas); - void attachMoved(QPointF attach); void hover(bool state); void selected(bool state); @@ -144,16 +129,13 @@ protected: virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override; double getEdgeFuzz(void) const; - std::vector m_deltas; //deltas between points 1:1 scale, starts at (0,0) - std::vector m_points; //actual pos of markers - std::vector m_saveDeltas; + std::vector m_ghostPoints; std::vector m_markers; - QPointF m_attach; - double m_scale; + double m_scale; bool m_inEdit; - QGIView* m_parentItem; + QGILeaderLine* m_parentLeader; QGIPrimPath* m_ghost; double m_startAdj; diff --git a/src/Mod/TechDraw/Gui/QGILeaderLine.cpp b/src/Mod/TechDraw/Gui/QGILeaderLine.cpp index 036db728d5..a3be5f5fd8 100644 --- a/src/Mod/TechDraw/Gui/QGILeaderLine.cpp +++ b/src/Mod/TechDraw/Gui/QGILeaderLine.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include "Rez.h" #include "ZVALUE.h" @@ -73,7 +74,6 @@ using namespace TechDrawGui; QGILeaderLine::QGILeaderLine(QGraphicsItem* myParent, TechDraw::DrawLeaderLine* leader) : m_parentItem(myParent), - m_lineWidth(0.0), m_lineColor(Qt::black), m_hasHover(false), m_blockDraw(false) @@ -88,18 +88,22 @@ QGILeaderLine::QGILeaderLine(QGraphicsItem* myParent, setCacheMode(QGraphicsItem::NoCache); - m_lineColor = Qt::blue; - - m_line = new QGEPath(); - m_line->setNormalColor(getNormalColor()); -// m_line->setPrettyNormal(); - + m_line = new QGIPrimPath(); addToGroup(m_line); - m_line->setPos(0.0, 0.0); - m_line->setFlag(QGraphicsItem::ItemIsSelectable, false); - m_line->setFlag(QGraphicsItem::ItemIsMovable, false); + m_line->setNormalColor(getNormalColor()); + m_line->setPrettyNormal(); + m_line->setPos(0.0,0.0); + + m_editPath = new QGEPath(this); + m_editPath->setNormalColor(getNormalColor()); + + addToGroup(m_editPath); + m_editPath->setPos(0.0, 0.0); + m_editPath->setFlag(QGraphicsItem::ItemIsSelectable, false); + m_editPath->setFlag(QGraphicsItem::ItemIsMovable, false); setFlag(QGraphicsItem::ItemSendsScenePositionChanges, false); - m_line->setZValue(ZVALUE::DIMENSION); + m_editPath->setZValue(ZVALUE::DIMENSION); + m_editPath->hide(); m_arrow1 = new QGIArrow(); addToGroup(m_arrow1); @@ -123,19 +127,15 @@ QGILeaderLine::QGILeaderLine(QGraphicsItem* myParent, setZValue(ZVALUE::DIMENSION); QObject::connect( - m_line, SIGNAL(pointsUpdated(QPointF, std::vector)), + m_editPath, SIGNAL(pointsUpdated(QPointF, std::vector)), this , SLOT (onLineEditFinished(QPointF, std::vector)) ); QObject::connect( - m_line, SIGNAL(attachMoved(QPointF)), - this , SLOT (onAttachMoved(QPointF)) - ); - QObject::connect( - m_line, SIGNAL(selected(bool)), + m_editPath, SIGNAL(selected(bool)), this , SLOT (select(bool))); - QObject::connect( - m_line, SIGNAL(hover(bool)), + QObject::connect( //do we care? + m_editPath, SIGNAL(hover(bool)), this , SLOT (hover(bool))); } @@ -144,11 +144,11 @@ QVariant QGILeaderLine::itemChange(GraphicsItemChange change, const QVariant &va // Base::Console().Message("QGILL::itemChange(%d)\n", change); if (change == ItemSelectedHasChanged && scene()) { if(isSelected()) { - m_line->setSelected(true); + m_editPath->setSelected(true); m_arrow1->setSelected(true); m_arrow2->setSelected(true); } else { - m_line->setSelected(false); + m_editPath->setSelected(false); m_arrow1->setSelected(false); m_arrow2->setSelected(false); } @@ -173,72 +173,61 @@ void QGILeaderLine::onSourceChange(TechDraw::DrawView* newParent) } } -void QGILeaderLine::onAttachMoved(QPointF attach) -{ - auto leadFeat( dynamic_cast(getViewObject()) ); - double pScale = leadFeat->getScale(); - QPointF mapped = m_parentItem->mapFromItem(this,attach); //map point to baseView - Base::Vector3d attachPoint = Base::Vector3d(mapped.x(),mapped.y(),0.0); - getFeature()->setPosition(Rez::appX(attachPoint.x / pScale), //attach point must scale with parent. - Rez::appX(- attachPoint.y / pScale), - true); -} - - void QGILeaderLine::select(bool state) { setSelected(state); - draw(); +// draw(); } void QGILeaderLine::hover(bool state) { m_hasHover = state; - draw(); +// draw(); } void QGILeaderLine::closeEdit(void) { // Base::Console().Message("QGIL::closeEdit()\n"); - if (m_line != nullptr) { - m_line->onEndEdit(); //to QGEPath + if (m_editPath != nullptr) { + m_editPath->onEndEdit(); //tell QEPath that edit session ended } } -//from QGEPath -void QGILeaderLine::onLineEditFinished(QPointF attach, std::vector deltas) +//signaled from QEPath +void QGILeaderLine::onLineEditFinished(QPointF tipDisplace, std::vector points) { // Base::Console().Message("QGILL::onLineEditFinished(%s, %d)\n", -// TechDraw::DrawUtil::formatVector(attach).c_str(), -// deltas.size()); +// TechDraw::DrawUtil::formatVector(tipDisplace).c_str(), +// points.size()); m_blockDraw = true; - auto leadFeat( dynamic_cast(getViewObject()) ); - double pScale = leadFeat->getScale(); + auto featLeader = getFeature(); + if (featLeader == nullptr) { + //tarfu + return; + } + double baseScale = featLeader->getBaseScale(); - QPointF p0 = deltas.front(); - if ( !(TechDraw::DrawUtil::fpCompare(attach.x(),0.0) && - TechDraw::DrawUtil::fpCompare(attach.y(),0.0)) ) { - //p0 was moved. need to change AttachPoint and intervals from p0 - QPointF mapped = m_parentItem->mapFromItem(this,attach); //map point to baseView - Base::Vector3d attachPoint = Base::Vector3d(mapped.x(),mapped.y(),0.0); - for (auto& p : deltas) { - p -= p0; - } - deltas.at(0) = QPointF(0.0,0.0); - getFeature()->setPosition(Rez::appX(attachPoint.x / pScale), //attach point must scale with parent. - Rez::appX(- attachPoint.y / pScale), + if ( !(TechDraw::DrawUtil::fpCompare(tipDisplace.x(),0.0) && + TechDraw::DrawUtil::fpCompare(tipDisplace.y(),0.0)) ) { + //tip was moved. need to change AttachPoint + QPointF oldAttach = getAttachFromFeature(); + QPointF newAttach = oldAttach + (tipDisplace / baseScale); + featLeader->setPosition(Rez::appX(newAttach.x()), + Rez::appX(- newAttach.y()), true); } std::vector waypoints; - for (auto& p: deltas) { - Base::Vector3d v(p.x(),p.y(),0.0); + for (auto& p: points) { + QPointF moved = p - tipDisplace; + Base::Vector3d v(moved.x(),moved.y(),0.0); waypoints.push_back(v); } + waypoints.at(0) = Base::Vector3d(0.0, 0.0, 0.0); - getFeature()->WayPoints.setValues(waypoints); - if (getFeature()->AutoHorizontal.getValue()) { - getFeature()->adjustLastSegment(); + featLeader->WayPoints.setValues(waypoints); + if (featLeader->AutoHorizontal.getValue()) { + featLeader->adjustLastSegment(); } if (m_parentItem == nullptr) { @@ -250,49 +239,53 @@ void QGILeaderLine::onLineEditFinished(QPointF attach, std::vector delt } } m_blockDraw = false; + m_editPath->hide(); draw(); } void QGILeaderLine::startPathEdit(void) { saveState(); - auto leadFeat( dynamic_cast(getViewObject()) ); + auto featLeader( dynamic_cast(getViewObject()) ); - double scale = leadFeat->getScale(); - m_line->setScale(scale); - m_line->inEdit(true); - m_line->startPathEdit(); + double scale = featLeader->getScale(); + m_editPath->setScale(scale); + m_editPath->inEdit(true); + m_editPath->show(); + m_editPath->startPathEdit(getWayPointsFromFeature()); } void QGILeaderLine::saveState(void) { // Base::Console().Message("QGILL::saveState()\n"); - auto leadFeat = getFeature(); - if (leadFeat != nullptr) { - m_savePoints = leadFeat->WayPoints.getValues(); - m_saveX = leadFeat->X.getValue(); - m_saveY = leadFeat->Y.getValue(); + auto featLeader = getFeature(); + if (featLeader != nullptr) { + m_savePoints = featLeader->WayPoints.getValues(); + m_saveX = featLeader->X.getValue(); + m_saveY = featLeader->Y.getValue(); } } void QGILeaderLine::restoreState(void) { // Base::Console().Message("QGILL::restoreState()\n"); - auto leadFeat = getFeature(); - if (leadFeat != nullptr) { - leadFeat->WayPoints.setValues(m_savePoints); - leadFeat->X.setValue(m_saveX); - leadFeat->Y.setValue(m_saveY); - leadFeat->recomputeFeature(); + auto featLeader = getFeature(); + if (featLeader != nullptr) { + featLeader->WayPoints.setValues(m_savePoints); + featLeader->X.setValue(m_saveX); + featLeader->Y.setValue(m_saveY); + featLeader->recomputeFeature(); } } +//****************************************************************************** + void QGILeaderLine::updateView(bool update) { // Base::Console().Message("QGIL::updateView() %s\n",getViewObject()->getNameInDocument()); Q_UNUSED(update); - auto leadFeat( dynamic_cast(getViewObject()) ); - if ( leadFeat == nullptr ) { + auto featLeader( dynamic_cast(getViewObject()) ); + if ( featLeader == nullptr ) { Base::Console().Warning("QGILL::updateView - no feature!\n"); return; } @@ -311,157 +304,166 @@ void QGILeaderLine::draw() // Base::Console().Message("QGIL::draw - block draw\n"); return; } - if (!isVisible()) { // Base::Console().Message("QGIL::draw - not visible\n"); return; } - - TechDraw::DrawLeaderLine* leadFeat = getFeature(); - if((!leadFeat) ) { + TechDraw::DrawLeaderLine* featLeader = getFeature(); + if((!featLeader) ) { // Base::Console().Message("QGIL::draw - no feature\n"); return; } - auto vp = static_cast(getViewProvider(getViewObject())); if ( vp == nullptr ) { // Base::Console().Message("QGIL::draw - no viewprovider\n"); return; } - - TechDraw::DrawView* parent = leadFeat->getBaseView(); + TechDraw::DrawView* parent = featLeader->getBaseView(); QGVPage* view = QGIView::getGraphicsView(parent); if (view == nullptr) { // Base::Console().Message("QGIL::draw - no graphcisView for parent!! - setup?\n"); return; } - - if (m_line->inEdit()) { -// Base::Console().Message("QGIL::draw - m_line in edit\n"); + if (m_editPath->inEdit()) { +// Base::Console().Message("QGIL::draw - m_editPath in edit\n"); return; } - if (leadFeat->isLocked()) { +//******** + + if (featLeader->isLocked()) { setFlag(QGraphicsItem::ItemIsMovable, false); } else { setFlag(QGraphicsItem::ItemIsMovable, true); } - - m_lineWidth = Rez::guiX(vp->LineWidth.getValue()); - m_lineColor = vp->Color.getValue().asValue(); m_lineStyle = (Qt::PenStyle) vp->LineStyle.getValue(); - double scale = parent->getScale(); //only attach point scales with parent. - double x = Rez::guiX(leadFeat->X.getValue()); - double y = - Rez::guiX(leadFeat->Y.getValue()); - QPointF aPoint(x,y); //1:1 parent coords - aPoint *= scale; //scaled parent coords + double scale = parent->getScale(); + double baseScale = featLeader->getBaseScale(); + double x = Rez::guiX(featLeader->X.getValue()); + double y = - Rez::guiX(featLeader->Y.getValue()); + QPointF aPoint(x,y); + aPoint *= baseScale; setPos(aPoint); -// this is for Page as parent -// double ptScale = 1.0; -// if (leadFeat->Scalable.getValue()) { -// ptScale = scale; -// } - std::vector qPoints = waypointsToQPoints(); - if (qPoints.empty()) { -// Base::Console().Warning("QGIL::draw - no points\n"); - return; - } - m_line->setFillStyle(Qt::NoBrush); m_line->setStyle(m_lineStyle); - double scaler = 1.0; - m_line->setWidth(scaler * m_lineWidth); + m_line->setWidth(getLineWidth()); - m_line->setNormalColor(m_lineColor); - scale = leadFeat->getScale(); - m_line->setScale(scale); - if (leadFeat->StartSymbol.getValue() > -1) { - m_line->setStartAdjust(QGIArrow::getOverlapAdjust(leadFeat->StartSymbol.getValue(), - QGIArrow::getPrefArrowSize())); - } - if (leadFeat->EndSymbol.getValue() > -1) { - m_line->setEndAdjust(QGIArrow::getOverlapAdjust(leadFeat->EndSymbol.getValue(), - QGIArrow::getPrefArrowSize())); - } + m_line->setNormalColor(getNormalColor()); + m_line->setPos(0,0); //make m_line coords == leader coords - m_line->makeDeltasFromPoints(qPoints); - m_line->setPos(0,0); - m_line->updatePath(); + std::vector qPoints = getWayPointsFromFeature(); + if (featLeader->Scalable.getValue()) { + for (auto& p : qPoints) { + p = p * scale; + } + } + m_line->setPath(makeLeaderPath(qPoints)); m_line->show(); setArrows(qPoints); +} - if (m_hasHover && !isSelected()) { - m_arrow1->setPrettyPre(); - m_arrow2->setPrettyPre(); - m_line->setPrettyPre(); - } else if (isSelected()) { - m_arrow1->setPrettySel(); - m_arrow2->setPrettySel(); - m_line->setPrettySel(); - } else { - m_arrow1->setPrettyNormal(); - m_arrow2->setPrettyNormal(); - m_line->setPrettyNormal(); +QPainterPath QGILeaderLine::makeLeaderPath(std::vector qPoints) +{ +// Base::Console().Message("QGILeaderLine::makeLeaderPath()\n"); + QPainterPath result; + DrawLeaderLine* featLeader = getFeature(); + if (featLeader == nullptr) { + Base::Console().Message("QGILL::makeLeaderPath - featLeader is nullptr\n"); + return result; } -// Base::Console().Message("QGIL::draw - exits\n"); + + QPointF startAdjVec(0.0,0.0); + double startAdjLength(0.0); + QPointF endAdjVec(0.0,0.0); + double endAdjLength(0.0); + if (qPoints.size() > 1) { + //make path adjustment to hide leaderline ends behind arrowheads + if (featLeader->StartSymbol.getValue() > -1) { + startAdjLength = QGIArrow::getOverlapAdjust(featLeader->StartSymbol.getValue(), + QGIArrow::getPrefArrowSize()); + } + if (featLeader->EndSymbol.getValue() > -1) { + endAdjLength = QGIArrow::getOverlapAdjust(featLeader->EndSymbol.getValue(), + QGIArrow::getPrefArrowSize()); + } + + //get adjustment directions + startAdjVec = qPoints.at(1) - qPoints.front(); + endAdjVec = (*(qPoints.end() - 2))- qPoints.back(); + + //get adjustment vectors + QVector2D startTemp(startAdjVec); + QVector2D endTemp(endAdjVec); + startTemp.normalize(); + endTemp.normalize(); + startAdjVec = startTemp.toPointF() * startAdjLength; + endAdjVec = endTemp.toPointF() * endAdjLength; + + qPoints.front() += startAdjVec; + qPoints.back() += endAdjVec; + result.moveTo(qPoints.front()); + for (int i = 1; i < (int)qPoints.size(); i++) { + result.lineTo(qPoints.at(i)); + } + } + return result; } -void QGILeaderLine::drawBorder() +QPointF QGILeaderLine::getAttachFromFeature(void) { -////Leaders have no border! -// QGIView::drawBorder(); //good for debugging -} - -//waypoints converted to QPointF -std::vector QGILeaderLine::waypointsToQPoints() -{ -// Base::Console().Message("QGIL::waypointsToQPoints - #1 ()\n"); - TechDraw::DrawLeaderLine* featLine = getFeature(); - std::vector result; - std::vector vPts = featLine->WayPoints.getValues(); - if (vPts.empty()) { - Base::Console().Warning("QGIL::waypointsToQPoints - no points from feature!\n"); + QPointF result; + TechDraw::DrawLeaderLine* featLeader = getFeature(); + if((!featLeader) ) { + Base::Console().Message("QGIL::getAttachFromLeader - no feature\n"); return result; } - - for (auto& p: vPts) { - QPointF pConvert(p.x, p.y); - result.push_back(pConvert); - } + double x = Rez::guiX(featLeader->X.getValue()); + double y = - Rez::guiX(featLeader->Y.getValue()); + result = QPointF(x,y); return result; } -std::vector QGILeaderLine::waypointsToQPoints(std::vector pts) -{ -// Base::Console().Message("QGIL::waypointsToQPoints(%d) - #2\n", pts.size()); - std::vector result; - for (auto& p: pts) { - QPointF pConvert(p.x, p.y); - result.push_back(pConvert); +std::vector QGILeaderLine::getWayPointsFromFeature(void) +{ + std::vector qPoints; + + DrawLeaderLine* featLeader = getFeature(); + if (featLeader == nullptr) { + Base::Console().Message("QGILL::getWayPointsFromFeature - featLeader is nullptr\n"); + return qPoints; } - return result; + + std::vector vPoints = featLeader->WayPoints.getValues(); + for (auto& d: vPoints) { + QPointF temp(d.x, d.y); + qPoints.push_back(temp); + } + if (qPoints.empty()) { + Base::Console().Warning("QGILeaderLine::getWayPointsFromFeature - no points\n"); + } + return qPoints; } void QGILeaderLine::setArrows(std::vector pathPoints) { Base::Vector3d stdX(1.0,0.0,0.0); - TechDraw::DrawLeaderLine* line = getFeature(); - - double scale = line->getScale(); - QPointF lastOffset = (pathPoints.back() - pathPoints.front()) * scale; + TechDraw::DrawLeaderLine* featLeader = getFeature(); - if (line->StartSymbol.getValue() > -1) { - m_arrow1->setStyle(line->StartSymbol.getValue()); - m_arrow1->setWidth(m_lineWidth); + double baseScale = featLeader->getBaseScale(); + QPointF lastOffset = (pathPoints.back() - pathPoints.front()) * baseScale; + + if (featLeader->StartSymbol.getValue() > -1) { + m_arrow1->setStyle(featLeader->StartSymbol.getValue()); + m_arrow1->setWidth(getLineWidth()); // TODO: variable size arrow heads m_arrow1->setSize(QGIArrow::getPrefArrowSize()); m_arrow1->setDirMode(true); m_arrow1->setDirection(stdX); - m_arrow1->setNormalColor(m_lineColor); - m_arrow1->setFillColor(m_lineColor); + m_arrow1->setNormalColor(getNormalColor()); + m_arrow1->setFillColor(getNormalColor()); if (pathPoints.size() > 1) { auto it = pathPoints.begin(); QPointF s = (*it); @@ -477,12 +479,12 @@ void QGILeaderLine::setArrows(std::vector pathPoints) m_arrow1->hide(); } - if (line->EndSymbol.getValue() > -1) { - m_arrow2->setStyle(line->EndSymbol.getValue()); - m_arrow2->setWidth(m_lineWidth); + if (featLeader->EndSymbol.getValue() > -1) { + m_arrow2->setStyle(featLeader->EndSymbol.getValue()); + m_arrow2->setWidth(getLineWidth()); m_arrow2->setDirMode(true); m_arrow2->setDirection(-stdX); - m_arrow2->setNormalColor(m_lineColor); + m_arrow2->setNormalColor(getNormalColor()); m_arrow2->setFillColor(getNormalColor()); if (pathPoints.size() > 1) { auto itr = pathPoints.rbegin(); @@ -500,17 +502,30 @@ void QGILeaderLine::setArrows(std::vector pathPoints) } } +void QGILeaderLine::drawBorder() +{ +////Leaders have no border! +// QGIView::drawBorder(); //good for debugging +} + +//****************************************************************************** + + void QGILeaderLine::abandonEdit(void) { // Base::Console().Message("QGIL::abandonEdit()\n"); - m_line->clearMarkers(); - m_line->restoreState(); + m_editPath->clearMarkers(); + m_editPath->hide(); restoreState(); } double QGILeaderLine::getLineWidth(void) { - return m_lineWidth; + auto vp = static_cast(getViewProvider(getViewObject())); + if ( vp == nullptr ) { + return Rez::guiX(LineGroup::getDefaultWidth("Graphic")); + } + return Rez::guiX(vp->LineWidth.getValue()); } TechDraw::DrawLeaderLine* QGILeaderLine::getFeature(void) diff --git a/src/Mod/TechDraw/Gui/QGILeaderLine.h b/src/Mod/TechDraw/Gui/QGILeaderLine.h index 0db864b315..bf502d07e2 100644 --- a/src/Mod/TechDraw/Gui/QGILeaderLine.h +++ b/src/Mod/TechDraw/Gui/QGILeaderLine.h @@ -67,15 +67,11 @@ public: QWidget * widget = 0 ) override; virtual QRectF boundingRect() const override; virtual QPainterPath shape(void) const override; - double getEdgeFuzz(void) const; virtual void drawBorder() override; virtual void updateView(bool update = false) override; virtual TechDraw::DrawLeaderLine* getFeature(void); - QGEPath* getLeaderLine(void) { return m_line; } - std::vector waypointsToQPoints(void); - std::vector waypointsToQPoints(std::vector pts); void startPathEdit(void); void setArrows(std::vector pathPoints); @@ -84,10 +80,12 @@ public: void closeEdit(void); double getLineWidth(void); + double getEdgeFuzz(void) const; + + public Q_SLOTS: void onLineEditFinished(QPointF attach, std::vector deltas); //QGEPath is finished editing points - void onAttachMoved(QPointF attach); void select(bool state); void hover(bool state); virtual void onSourceChange(TechDraw::DrawView* newParent) override; @@ -97,10 +95,13 @@ Q_SIGNALS: protected: virtual void draw() override; + QPainterPath makeLeaderPath(std::vector qPoints); + std::vector getWayPointsFromFeature(void); + QPointF getAttachFromFeature(void); + virtual QVariant itemChange( GraphicsItemChange change, const QVariant &value ) override; std::vector m_pathPoints; - Base::Vector3d m_attachPoint; void saveState(void); void restoreState(void); @@ -108,13 +109,18 @@ protected: protected: QColor getNormalColor() override; - QGraphicsItem* m_parentItem; //<<< this never changes! - QGEPath* m_line; - QGIArrow* m_arrow1; - QGIArrow* m_arrow2; + QGraphicsItem* m_parentItem; + QGIPrimPath* m_line; //actual leader line double m_lineWidth; QColor m_lineColor; Qt::PenStyle m_lineStyle; + QGIArrow* m_arrow1; + QGIArrow* m_arrow2; + + QGEPath* m_editPath; //line editor + QColor m_editPathColor; + Qt::PenStyle m_editPathStyle; + bool m_hasHover; double m_saveX;