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