diff --git a/src/Mod/TechDraw/Gui/QGIView.cpp b/src/Mod/TechDraw/Gui/QGIView.cpp index 5288fb5890..620900380d 100644 --- a/src/Mod/TechDraw/Gui/QGIView.cpp +++ b/src/Mod/TechDraw/Gui/QGIView.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -158,22 +159,25 @@ QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value) newPos = value.toPointF(); //position within parent! TechDraw::DrawView *viewObj = getViewObject(); - if (viewObj->isDerivedFrom(TechDraw::DrawProjGroupItem::getClassTypeId())) { + auto* dpgi = dynamic_cast(viewObj); + if (dpgi && dpgi->getPGroup()) { // restrict movements of secondary views. - TechDraw::DrawProjGroupItem* dpgi = static_cast(viewObj); - TechDraw::DrawProjGroup* dpg = dpgi->getPGroup(); - if (dpg) { - if(alignHash.size() == 1) { //if aligned. - QGraphicsItem* item = alignHash.begin().value(); - QString alignMode = alignHash.begin().key(); - if(alignMode == QString::fromLatin1("Vertical")) { - newPos.setX(item->pos().x()); - } else if(alignMode == QString::fromLatin1("Horizontal")) { - newPos.setY(item->pos().y()); - } + if(alignHash.size() == 1) { //if aligned. + QGraphicsItem* item = alignHash.begin().value(); + QString alignMode = alignHash.begin().key(); + if(alignMode == QString::fromLatin1("Vertical")) { + newPos.setX(item->pos().x()); + } + else if(alignMode == QString::fromLatin1("Horizontal")) { + newPos.setY(item->pos().y()); } } } + else { + // For general views we check if we need to snap to a position + snapPosition(newPos); + } + // tell the feature that we have moved Gui::ViewProvider *vp = getViewProvider(viewObj); if (vp && !vp->isRestoring()) { @@ -197,6 +201,44 @@ QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value) return QGraphicsItemGroup::itemChange(change, value); } +void QGIView::snapPosition(QPointF& pos) +{ + // For general views we check if the view is close to aligned vertically or horizontally to another view. + + // First get a list of the views of the page. + auto* mdi = dynamic_cast(Gui::getMainWindow()->activeWindow()); + if (!mdi) { + return; + } + ViewProviderPage* vp = mdi->getViewProviderPage(); + if (!vp) { + return; + } + QGSPage* scenePage = vp->getQGSPage(); + if (!scenePage) { + return; + } + + std::vector views = scenePage->getViews(); + + qreal snapPercent = 0.05; + for (auto* view : views) { + if (view == this) { continue; } + + QPointF vPos = view->pos(); + qreal dx = view->boundingRect().width() * snapPercent; + qreal dy = view->boundingRect().height() * snapPercent; + if (fabs(pos.x() - vPos.x()) < dx) { + pos.setX(vPos.x()); + break; + } + else if (fabs(pos.y() - vPos.y()) < dy) { + pos.setY(vPos.y()); + break; + } + } +} + void QGIView::mousePressEvent(QGraphicsSceneMouseEvent * event) { // Base::Console().Message("QGIV::mousePressEvent() - %s\n", getViewName()); diff --git a/src/Mod/TechDraw/Gui/QGIView.h b/src/Mod/TechDraw/Gui/QGIView.h index 46c835a65f..44428dd479 100644 --- a/src/Mod/TechDraw/Gui/QGIView.h +++ b/src/Mod/TechDraw/Gui/QGIView.h @@ -122,6 +122,8 @@ public: void isInnerView(bool state) { m_innerView = state; } QGIViewClip* getClipGroup(); + void snapPosition(QPointF& position); + void alignTo(QGraphicsItem*, const QString &alignment); QColor prefNormalColor(); //preference