From 3307e4bf7a72acb61de5e36ea069d38423354e5b Mon Sep 17 00:00:00 2001 From: wandererfan Date: Mon, 2 Mar 2020 19:28:01 -0500 Subject: [PATCH] [TD]fix Balloon coordinates --- src/Mod/TechDraw/App/DrawViewBalloon.cpp | 28 +++- src/Mod/TechDraw/App/DrawViewBalloon.h | 3 + src/Mod/TechDraw/Gui/QGIViewBalloon.cpp | 180 ++++++++++++++--------- src/Mod/TechDraw/Gui/QGIViewBalloon.h | 11 +- 4 files changed, 146 insertions(+), 76 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawViewBalloon.cpp b/src/Mod/TechDraw/App/DrawViewBalloon.cpp index d632c41f09..6e7765b9dd 100644 --- a/src/Mod/TechDraw/App/DrawViewBalloon.cpp +++ b/src/Mod/TechDraw/App/DrawViewBalloon.cpp @@ -64,10 +64,13 @@ using namespace TechDraw; //=========================================================================== // DrawViewBalloon //=========================================================================== -// +// Balloon coordinates are relative to the position of the SourceView // X,Y is the center of the balloon bubble // OriginX, OriginY is the tip of the arrow -// these are in ???? coordinates +// these are in unscaled SourceView coordinates +// Note that if the SourceView coordinate system changes +// (ie location changes or additional items added to the View +// the location of the balloon may also change. PROPERTY_SOURCE(TechDraw::DrawViewBalloon, TechDraw::DrawView) @@ -108,7 +111,6 @@ const char* DrawViewBalloon::balloonTypeEnums[]= {"Circular", DrawViewBalloon::DrawViewBalloon(void) { ADD_PROPERTY_TYPE(Text , (""),"",App::Prop_None,"The text to be displayed"); -// ADD_PROPERTY_TYPE(SourceView,(0),"",(App::PropertyType)(App::Prop_None),"Source view for balloon"); ADD_PROPERTY_TYPE(SourceView,(0),"",(App::PropertyType)(App::Prop_None),"Source view for balloon"); ADD_PROPERTY_TYPE(OriginX,(0),"",(App::PropertyType)(App::Prop_None),"Balloon origin x"); ADD_PROPERTY_TYPE(OriginY,(0),"",(App::PropertyType)(App::Prop_None),"Balloon origin y"); @@ -261,6 +263,14 @@ App::DocumentObjectExecReturn *DrawViewBalloon::execute(void) return App::DocumentObject::execute(); } +void DrawViewBalloon::setOrigin(Base::Vector3d newOrigin) +{ + //suspend onChanged/recompute? + OriginX.setValue(newOrigin.x); + OriginY.setValue(newOrigin.y); + origin = QPointF(newOrigin.x, newOrigin.y); +} + double DrawViewBalloon::prefKinkLength(void) const { Base::Reference hGrp = App::GetApplication().GetUserParameter(). @@ -287,6 +297,18 @@ int DrawViewBalloon::prefEnd(void) const return end; } +Base::Vector3d DrawViewBalloon::getOriginOffset() const +{ + double x = X.getValue(); + double y = Y.getValue(); + Base::Vector3d pos(x, y, 0.0); + double ox = OriginX.getValue(); + double oy = OriginY.getValue(); + Base::Vector3d org(ox, oy, 0.0); + Base::Vector3d offset = pos - org; + return offset; +} + /* PyObject *DrawViewBalloon::getPyObject(void) { diff --git a/src/Mod/TechDraw/App/DrawViewBalloon.h b/src/Mod/TechDraw/App/DrawViewBalloon.h index 55c8d16688..113bacb2e4 100644 --- a/src/Mod/TechDraw/App/DrawViewBalloon.h +++ b/src/Mod/TechDraw/App/DrawViewBalloon.h @@ -83,6 +83,9 @@ public: double prefKinkLength(void) const; int prefShape(void) const; int prefEnd(void) const; + void setOrigin(Base::Vector3d newOrigin); + + Base::Vector3d getOriginOffset() const; protected: void onChanged(const App::Property* prop) override; diff --git a/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp b/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp index 41d0353e18..90584d2d76 100644 --- a/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -64,12 +65,13 @@ #include "ViewProviderBalloon.h" #include "DrawGuiUtil.h" #include "QGIViewPart.h" +#include "ViewProviderViewPart.h" #include "QGIViewDimension.h" #include "QGVPage.h" #include "MDIViewPage.h" #include "TaskBalloon.h" -//TODO: hide the Qt coord system (+y down). +//TODO: hide the Qt coord system (+y down). using namespace TechDraw; using namespace TechDrawGui; @@ -78,6 +80,8 @@ QGIBalloonLabel::QGIBalloonLabel() { posX = 0; posY = 0; + m_ctrl = false; + m_drag = false; setCacheMode(QGraphicsItem::NoCache); setFlag(ItemSendsGeometryChanges, true); @@ -88,7 +92,6 @@ QGIBalloonLabel::QGIBalloonLabel() m_labelText = new QGCustomText(); m_labelText->setParentItem(this); - m_ctrl = false; hasHover = false; } @@ -105,7 +108,9 @@ QVariant QGIBalloonLabel::itemChange(GraphicsItemChange change, const QVariant & update(); } else if(change == ItemPositionHasChanged && scene()) { setLabelCenter(); - Q_EMIT dragging(m_ctrl); + if (m_drag) { + Q_EMIT dragging(m_ctrl); + } } return QGraphicsItem::itemChange(change, value); @@ -113,14 +118,12 @@ QVariant QGIBalloonLabel::itemChange(GraphicsItemChange change, const QVariant & void QGIBalloonLabel::mousePressEvent(QGraphicsSceneMouseEvent * event) { + m_ctrl = false; + m_drag = true; if(event->modifiers() & Qt::ControlModifier) { m_ctrl = true; } - - if(scene() && this == scene()->mouseGrabberItem()) { - Q_EMIT dragFinished(); - } - QGraphicsItem::mousePressEvent(event); + QGraphicsItem::mousePressEvent(event); } void QGIBalloonLabel::mouseMoveEvent(QGraphicsSceneMouseEvent * event) @@ -130,19 +133,17 @@ void QGIBalloonLabel::mouseMoveEvent(QGraphicsSceneMouseEvent * event) void QGIBalloonLabel::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) { -// Base::Console().Message("QGIVB::mouseRelease - pos: %s\n", -// DrawUtil::formatVector(pos()).c_str()); - m_ctrl = false; if(scene() && this == scene()->mouseGrabberItem()) { Q_EMIT dragFinished(); } - + m_ctrl = false; + m_drag = false; QGraphicsItem::mouseReleaseEvent(event); } void QGIBalloonLabel::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * event) { - Gui::Control().showDialog(new TaskDlgBalloon(parent)); +// Gui::Control().showDialog(new TaskDlgBalloon(parent)); //only from tree QGraphicsItem::mouseDoubleClickEvent(event); } @@ -246,6 +247,8 @@ QGIViewBalloon::QGIViewBalloon() : hasHover(false), m_lineWidth(0.0) { + m_ctrl = false; + setHandlesChildEvents(false); setFlag(QGraphicsItem::ItemIsMovable, false); setCacheMode(QGraphicsItem::NoCache); @@ -349,13 +352,22 @@ void QGIViewBalloon::hover(bool state) void QGIViewBalloon::setViewPartFeature(TechDraw::DrawViewBalloon *balloon) { +// Base::Console().Message("QGIVB::setViewPartFeature()\n"); if(balloon == 0) return; setViewFeature(static_cast(balloon)); - float x = Rez::guiX(balloon->X.getValue()); - float y = Rez::guiX(-balloon->Y.getValue()); + DrawView* balloonParent = nullptr; + double scale = 1.0; + App::DocumentObject* docObj = balloon->SourceView.getValue(); + if (docObj == nullptr) { + balloonParent = dynamic_cast(docObj); + scale = balloonParent->getScale(); + } + + float x = Rez::guiX(balloon->X.getValue() * scale) ; + float y = Rez::guiX(-balloon->Y.getValue() * scale); balloonLabel->setColor(getNormalColor()); balloonLabel->setPosFromCenter(x, y); @@ -368,8 +380,10 @@ void QGIViewBalloon::setViewPartFeature(TechDraw::DrawViewBalloon *balloon) draw(); } +//from ViewProviderDrawingView::updateData (X or Y) void QGIViewBalloon::updateView(bool update) { +// Base::Console().Message("QGIVB::updateView()\n"); Q_UNUSED(update); auto balloon( dynamic_cast(getViewObject()) ); if( balloon == nullptr ) @@ -385,18 +399,15 @@ void QGIViewBalloon::updateView(bool update) balloonLabel->setDimString(labelText, Rez::guiX(balloon->TextWrapLen.getValue())); balloonLabel->setColor(getNormalColor()); } - if ( balloon->X.isTouched() || balloon->Y.isTouched()){ - float x = Rez::guiX(balloon->X.getValue()); - float y = Rez::guiX(balloon->Y.getValue()); - balloonLabel->setPosFromCenter(x,-y); - } updateBalloon(); draw(); } +//update the bubble contents void QGIViewBalloon::updateBalloon(bool obtuse) { +// Base::Console().Message("QGIVB::updateBalloon()\n"); (void) obtuse; const auto balloon( dynamic_cast(getViewObject()) ); if( balloon == nullptr ) { @@ -432,28 +443,47 @@ void QGIViewBalloon::updateBalloon(bool obtuse) void QGIViewBalloon::balloonLabelDragged(bool ctrl) { - draw_modifier(ctrl); +// Base::Console().Message("QGIVB::bLabelDragged(%d)\n", ctrl); + m_ctrl = ctrl; + auto dvb( dynamic_cast(getViewObject()) ); + if (!m_dragInProgress) { //first drag movement + m_dragInProgress = true; + if (ctrl) { //moving whole thing, remember Origin offset from Bubble + m_saveOffset = dvb->getOriginOffset(); + } + } + + double scale = 1.0; + DrawView* balloonParent = getSourceView(); + if (balloonParent != nullptr) { + scale = balloonParent->getScale(); + } + + //set feature position (x,y) from graphic position + double x = Rez::appX(balloonLabel->X() / scale), + y = Rez::appX(balloonLabel->Y() / scale); + Gui::Command::openCommand("Drag Balloon"); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.X = %f", dvb->getNameInDocument(), x); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Y = %f", dvb->getNameInDocument(), -y); + //if origin is also moving, calc new origin and update feature + if (ctrl) { + Base::Vector3d pos(x, -y, 0.0); + Base::Vector3d newOrg = pos - m_saveOffset; + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.OriginX = %f", + dvb->getNameInDocument(), newOrg.x); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.OriginY = %f", + dvb->getNameInDocument(), newOrg.y); + } + Gui::Command::commitCommand(); } void QGIViewBalloon::balloonLabelDragFinished() { - auto dvb( dynamic_cast(getViewObject()) ); - - if( dvb == nullptr ) { - return; - } - - double x = Rez::appX(balloonLabel->X()), - y = Rez::appX(balloonLabel->Y()); - Gui::Command::openCommand("Drag Balloon"); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.X = %f", dvb->getNameInDocument(), x); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Y = %f", dvb->getNameInDocument(), -y); - Gui::Command::commitCommand(); + //really nothing to do here. position has been update by drag already + m_dragInProgress = false; } - - -//from QGVP::mouseReleaseEvent - pos = eventPos +//from QGVP::mouseReleaseEvent - pos = eventPos in scene coords? void QGIViewBalloon::placeBalloon(QPointF pos) { // Base::Console().Message("QGIVB::placeBalloon(%s)\n", @@ -481,10 +511,23 @@ void QGIViewBalloon::placeBalloon(QPointF pos) return; } - balloon->OriginX.setValue(Rez::appX(mapFromScene(pos).x())); - balloon->OriginY.setValue(Rez::appX(mapFromScene(pos).y())); - balloon->X.setValue(Rez::appX(mapFromScene(pos).x() + 200)); - balloon->Y.setValue(- Rez::appX(mapFromScene(pos).y() - 200)); + + QGIView* qgivParent = nullptr; + QPointF viewPos; + Gui::ViewProvider* objVp = QGIView::getViewProvider(balloonParent); + auto partVP = dynamic_cast(objVp); + if ( partVP != nullptr ) { + qgivParent = partVP->getQView(); + if (qgivParent != nullptr) { + //tip position is mouse release pos in parentView coords ==> OriginX, OriginY + //bubble pos is some arbitrary shift from tip position ==> X,Y + viewPos = qgivParent->mapFromScene(pos); + balloon->OriginX.setValue(Rez::appX(viewPos.x()) / balloonParent->getScale()); + balloon->OriginY.setValue(-Rez::appX(viewPos.y()) / balloonParent->getScale()); + balloon->X.setValue(Rez::appX((viewPos.x() + 200.0) / balloonParent->getScale() )); + balloon->Y.setValue(- Rez::appX((viewPos.y() - 200.0) / balloonParent->getScale() )); + } + } int idx = featPage->getNextBalloonIndex(); QString labelText = QString::number(idx); @@ -497,7 +540,7 @@ void QGIViewBalloon::placeBalloon(QPointF pos) prepareGeometryChange(); // Default label position - balloonLabel->setPosFromCenter(mapFromScene(pos).x() + 200, mapFromScene(pos).y() -200); + balloonLabel->setPosFromCenter(viewPos.x() + 200, viewPos.y() - 200); balloonLabel->setDimString(labelText, Rez::guiX(balloon->TextWrapLen.getValue())); draw(); @@ -505,11 +548,7 @@ void QGIViewBalloon::placeBalloon(QPointF pos) void QGIViewBalloon::draw() { - draw_modifier(false); -} - -void QGIViewBalloon::draw_modifier(bool modifier) -{ +// Base::Console().Message("QGIVB::draw()\n"); if (!isVisible()) { return; } @@ -544,8 +583,12 @@ void QGIViewBalloon::draw_modifier(bool modifier) double textWidth = balloonLabel->getDimText()->boundingRect().width(); double textHeight = balloonLabel->getDimText()->boundingRect().height(); - QRectF mappedRect = mapRectFromItem(balloonLabel, balloonLabel->boundingRect()); - Base::Vector3d lblCenter = Base::Vector3d(mappedRect.center().x(), mappedRect.center().y(), 0.0); + float x = Rez::guiX(balloon->X.getValue() * refObj->getScale()); + float y = Rez::guiX(balloon->Y.getValue() * refObj->getScale()); + Base::Vector3d lblCenter(x, -y, 0.0); + + float arrowTipX = Rez::guiX(balloon->OriginX.getValue() * refObj->getScale()); + float arrowTipY = - Rez::guiX(balloon->OriginY.getValue() * refObj->getScale()); if (balloon->isLocked()) { balloonLabel->setFlag(QGraphicsItem::ItemIsMovable, false); @@ -556,9 +599,6 @@ void QGIViewBalloon::draw_modifier(bool modifier) Base::Vector3d kinkPoint; double kinkLength = Rez::guiX(balloon->KinkLength.getValue()); - float orginX = Rez::guiX(balloon->OriginX.getValue()); - float orginY = Rez::guiX(balloon->OriginY.getValue()); - const char *balloonType = balloon->Symbol.getValueAsString(); float scale = balloon->SymbolScale.getValue(); @@ -637,7 +677,7 @@ void QGIViewBalloon::draw_modifier(bool modifier) balloonShape->setPath(balloonPath); - offsetLR = (lblCenter.x < orginX) ? offsetLR : -offsetLR ; + offsetLR = (lblCenter.x < arrowTipX) ? offsetLR : -offsetLR ; if (DrawUtil::fpCompare(kinkLength, 0.0)) { //if no kink, then dLine start sb on line from center to arrow dLineStart = lblCenter; @@ -645,7 +685,7 @@ void QGIViewBalloon::draw_modifier(bool modifier) } else { dLineStart.y = lblCenter.y; dLineStart.x = lblCenter.x + offsetLR ; - kinkLength = (lblCenter.x < orginX) ? kinkLength : -kinkLength; + kinkLength = (lblCenter.x < arrowTipX) ? kinkLength : -kinkLength; kinkPoint.y = dLineStart.y; kinkPoint.x = dLineStart.x + kinkLength; } @@ -654,17 +694,6 @@ void QGIViewBalloon::draw_modifier(bool modifier) dLinePath.moveTo(dLineStart.x, dLineStart.y); dLinePath.lineTo(kinkPoint.x, kinkPoint.y); - if (modifier) { - balloon->OriginX.setValue(Rez::appX(orginX + lblCenter.x - oldLabelCenter->x())); - balloon->OriginY.setValue(Rez::appX(orginY + lblCenter.y - oldLabelCenter->y())); - } - - orginX = Rez::guiX(balloon->OriginX.getValue()); - orginY = Rez::guiX(balloon->OriginY.getValue()); - - oldLabelCenter->setX(lblCenter.x); - oldLabelCenter->setY(lblCenter.y); - double xAdj = 0.0; double yAdj = 0.0; int endType = balloon->EndType.getValue(); @@ -680,17 +709,17 @@ void QGIViewBalloon::draw_modifier(bool modifier) arrow->setSize(QGIArrow::getPrefArrowSize()); arrow->draw(); - Base::Vector3d orign(orginX, orginY, 0.0); + Base::Vector3d arrowTipPos(arrowTipX, arrowTipY, 0.0); Base::Vector3d dirballoonLinesLine; if (!DrawUtil::fpCompare(kinkLength, 0.0)) { - dirballoonLinesLine = (orign - kinkPoint).Normalize(); + dirballoonLinesLine = (arrowTipPos - kinkPoint).Normalize(); } else { - dirballoonLinesLine = (orign - dLineStart).Normalize(); + dirballoonLinesLine = (arrowTipPos - dLineStart).Normalize(); } float arAngle = atan2(dirballoonLinesLine.y, dirballoonLinesLine.x) * 180 / M_PI; - arrow->setPos(orginX, orginY); + arrow->setPos(arrowTipX, arrowTipY); if ( (endTypeString == "PYRAMID") && (prefOrthoPyramid()) ) { if (arAngle < 0.0) { @@ -715,7 +744,7 @@ void QGIViewBalloon::draw_modifier(bool modifier) arrow->setRotation(arAngle); arrow->show(); } - dLinePath.lineTo(orginX - xAdj, orginY - yAdj); + dLinePath.lineTo(arrowTipX - xAdj, arrowTipY - yAdj); balloonLines->setPath(dLinePath); // redraw the Balloon and the parent View @@ -732,7 +761,6 @@ void QGIViewBalloon::draw_modifier(bool modifier) } else { Base::Console().Log("INFO - QGIVB::draw - no parent to update\n"); } - } void QGIViewBalloon::setPrettyPre(void) @@ -776,7 +804,6 @@ void QGIViewBalloon::paint ( QPainter * painter, const QStyleOptionGraphicsItem QPaintDevice* hw = painter->device(); QSvgGenerator* svg = dynamic_cast(hw); setPens(); - //double balloonLinesSaveWidth = arrow->getWidth(); if (svg) { setSvgPens(); } else { @@ -841,4 +868,15 @@ bool QGIViewBalloon::prefOrthoPyramid() const return ortho; } +DrawView* QGIViewBalloon::getSourceView() const +{ + DrawView* balloonParent = nullptr; + App::DocumentObject* docObj = getViewObject(); + DrawViewBalloon* dvb = dynamic_cast(docObj); + if (dvb != nullptr) { + balloonParent = dynamic_cast(dvb->SourceView.getValue()); + } + return balloonParent; +} + #include diff --git a/src/Mod/TechDraw/Gui/QGIViewBalloon.h b/src/Mod/TechDraw/Gui/QGIViewBalloon.h index 06de3cce51..4741a4d698 100644 --- a/src/Mod/TechDraw/Gui/QGIViewBalloon.h +++ b/src/Mod/TechDraw/Gui/QGIViewBalloon.h @@ -39,6 +39,7 @@ namespace TechDraw { class DrawViewBalloon; +class DrawView; } namespace TechDraw { @@ -109,10 +110,11 @@ protected: QGCustomText* m_labelText; QColor m_colNormal; - bool m_ctrl; double posX; double posY; + bool m_ctrl; + bool m_drag; private: }; @@ -139,7 +141,6 @@ public: QWidget * widget = 0 ) override; QString getLabelText(void); - void draw_modifier(bool modifier); void placeBalloon(QPointF pos); TechDraw::DrawViewBalloon *dvBalloon; void setPrettyPre(void); @@ -181,6 +182,12 @@ protected: QPointF *oldLabelCenter; QGIView *parent; //used to create edit dialog + TechDraw::DrawView* getSourceView() const; + bool m_dragInProgress; + bool m_ctrl; + Base::Vector3d m_saveOffset; + + }; } // namespace