TechDraw: Enable snapping section views to their base views.
This commit is contained in:
committed by
WandererFan
parent
f0ebd62637
commit
127ee90cec
@@ -41,6 +41,8 @@
|
||||
#include <Mod/TechDraw/App/DrawPage.h>
|
||||
#include <Mod/TechDraw/App/DrawProjGroup.h>
|
||||
#include <Mod/TechDraw/App/DrawProjGroupItem.h>
|
||||
#include <Mod/TechDraw/App/DrawViewSection.h>
|
||||
#include <Mod/TechDraw/App/DrawViewPart.h>
|
||||
#include <Mod/TechDraw/App/DrawUtil.h>
|
||||
#include <Mod/TechDraw/App/DrawView.h>
|
||||
|
||||
@@ -71,7 +73,8 @@ QGIView::QGIView()
|
||||
:QGraphicsItemGroup(),
|
||||
viewObj(nullptr),
|
||||
m_innerView(false),
|
||||
m_multiselectActivated(false)
|
||||
m_multiselectActivated(false),
|
||||
snapping(false)
|
||||
{
|
||||
setCacheMode(QGraphicsItem::NoCache);
|
||||
setHandlesChildEvents(false);
|
||||
@@ -153,10 +156,9 @@ void QGIView::alignTo(QGraphicsItem*item, const QString &alignment)
|
||||
|
||||
QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
QPointF newPos(0.0, 0.0);
|
||||
// Base::Console().Message("QGIV::itemChange(%d)\n", change);
|
||||
if(change == ItemPositionChange && scene()) {
|
||||
newPos = value.toPointF(); //position within parent!
|
||||
QPointF newPos = value.toPointF(); //position within parent!
|
||||
|
||||
TechDraw::DrawView *viewObj = getViewObject();
|
||||
auto* dpgi = dynamic_cast<TechDraw::DrawProjGroupItem*>(viewObj);
|
||||
@@ -181,7 +183,9 @@ QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
// tell the feature that we have moved
|
||||
Gui::ViewProvider *vp = getViewProvider(viewObj);
|
||||
if (vp && !vp->isRestoring()) {
|
||||
snapping = true; // avoid triggering updateView by the VP updateData
|
||||
viewObj->setPosition(Rez::appX(newPos.x()), Rez::appX(-newPos.y()));
|
||||
snapping = false;
|
||||
}
|
||||
|
||||
return newPos;
|
||||
@@ -201,7 +205,7 @@ QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
return QGraphicsItemGroup::itemChange(change, value);
|
||||
}
|
||||
|
||||
void QGIView::snapPosition(QPointF& pos)
|
||||
void QGIView::snapPosition(QPointF& mPos)
|
||||
{
|
||||
// For general views we check if the view is close to aligned vertically or horizontally to another view.
|
||||
|
||||
@@ -220,20 +224,65 @@ void QGIView::snapPosition(QPointF& pos)
|
||||
}
|
||||
|
||||
std::vector<QGIView*> views = scenePage->getViews();
|
||||
|
||||
qreal snapPercent = 0.05;
|
||||
|
||||
auto* sectionView = dynamic_cast<TechDraw::DrawViewSection*>(getViewObject());
|
||||
if (sectionView) {
|
||||
auto* baseView = sectionView->getBaseDVP();
|
||||
if (!baseView) { return; }
|
||||
|
||||
Base::Vector3d dir3d = sectionView->getSectionDirectionOnBaseView();
|
||||
double bSize = Rez::guiX(baseView->getSizeAlongVector(dir3d));
|
||||
double sSize = Rez::guiX(sectionView->getSizeAlongVector(dir3d));
|
||||
|
||||
auto* vpdv = dynamic_cast<ViewProviderDrawingView*>(getViewProvider(baseView));
|
||||
if (!vpdv) { return; }
|
||||
auto* qgiv(dynamic_cast<QGIView*>(vpdv->getQView()));
|
||||
if (!qgiv) { return; }
|
||||
QPointF bvPos = qgiv->pos();
|
||||
Base::Vector2d bvPt(bvPos.x(), bvPos.y());
|
||||
Base::Vector2d mPt(mPos.x(), mPos.y());
|
||||
Base::Vector2d dir(dir3d.x, dir3d.y);
|
||||
if (dir.Length() < Precision::Confusion()) { return; }
|
||||
dir.Normalize();
|
||||
|
||||
double snapDist = bSize * snapPercent;
|
||||
|
||||
Base::Vector2d projPt;
|
||||
projPt.ProjectToLine(mPt - bvPt, dir);
|
||||
projPt = projPt + bvPt;
|
||||
|
||||
Base::Vector2d v = (projPt - bvPt) + 0.5 * (sSize - bSize) * dir;
|
||||
int sign = v * dir > 0 ? - 1 : 1;
|
||||
double dist = v.Length();
|
||||
if (dist < snapDist) {
|
||||
v = dist * dir;
|
||||
mPos = mPos + sign * QPointF(v.x, v.y);
|
||||
return;
|
||||
}
|
||||
|
||||
v = (projPt - bvPt) + 0.5 * (bSize - sSize) * dir;
|
||||
sign = v * dir > 0 ? - 1 : 1;
|
||||
dist = v.Length();
|
||||
if (dist < snapDist) {
|
||||
v = dist * dir;
|
||||
mPos = mPos + sign * QPointF(v.x, v.y);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
if (fabs(mPos.x() - vPos.x()) < dx) {
|
||||
mPos.setX(vPos.x());
|
||||
break;
|
||||
}
|
||||
else if (fabs(pos.y() - vPos.y()) < dy) {
|
||||
pos.setY(vPos.y());
|
||||
else if (fabs(mPos.y() - vPos.y()) < dy) {
|
||||
mPos.setY(vPos.y());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user