From cd87af37462f4c448b35631a49399a3731d9d027 Mon Sep 17 00:00:00 2001 From: WandererFan Date: Thu, 27 Oct 2016 13:53:57 -0400 Subject: [PATCH] Allow manual repositioning of ProjGroup views --- src/Mod/TechDraw/App/DrawProjGroup.cpp | 67 +++++++++++--------- src/Mod/TechDraw/App/DrawProjGroup.h | 1 + src/Mod/TechDraw/App/DrawProjGroupItem.cpp | 15 ++++- src/Mod/TechDraw/App/DrawProjGroupItem.h | 3 + src/Mod/TechDraw/App/DrawView.cpp | 12 +++- src/Mod/TechDraw/App/DrawView.h | 1 + src/Mod/TechDraw/Gui/QGIView.cpp | 73 +++++++++++++--------- src/Mod/TechDraw/Gui/QGIView.h | 2 + 8 files changed, 112 insertions(+), 62 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawProjGroup.cpp b/src/Mod/TechDraw/App/DrawProjGroup.cpp index fb3e9c989911..e342e39c5732 100644 --- a/src/Mod/TechDraw/App/DrawProjGroup.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroup.cpp @@ -53,15 +53,17 @@ PROPERTY_SOURCE(TechDraw::DrawProjGroup, TechDraw::DrawViewCollection) DrawProjGroup::DrawProjGroup(void) { - static const char *group = "ProjGroup"; + static const char *group = "Base"; + static const char *agroup = "Distribute"; - ADD_PROPERTY_TYPE(Anchor, (0), group, App::Prop_None, "The root view to align projections with"); + ADD_PROPERTY_TYPE(Anchor, (0), group, App::Prop_None, "The root view to align projections with"); ProjectionType.setEnums(ProjectionTypeEnums); ADD_PROPERTY(ProjectionType, ((long)0)); - ADD_PROPERTY_TYPE(spacingX, (15), group, App::Prop_None, "Horizontal spacing between views"); - ADD_PROPERTY_TYPE(spacingY, (15), group, App::Prop_None, "Vertical spacing between views"); + ADD_PROPERTY_TYPE(AutoDistribute ,(true),agroup,App::Prop_None,"Distribute Views Automatically or Manually"); + ADD_PROPERTY_TYPE(spacingX, (15), agroup, App::Prop_None, "Horizontal spacing between views"); + ADD_PROPERTY_TYPE(spacingY, (15), agroup, App::Prop_None, "Vertical spacing between views"); ADD_PROPERTY(viewOrientationMatrix, (Base::Matrix4D())); } @@ -208,10 +210,14 @@ void DrawProjGroup::onChanged(const App::Property* prop) recompute(); } else if (prop == &Scale) { updateChildren(Scale.getValue()); - resetPositions(); + //resetPositions(); distributeProjections(); } else if (prop == &ScaleType) { recompute(); + } else if (prop == &AutoDistribute && + AutoDistribute.getValue()) { + resetPositions(); + recompute(); } } TechDraw::DrawViewCollection::onChanged(prop); @@ -465,6 +471,9 @@ void DrawProjGroup::makeViewBbs(DrawProjGroupItem *viewPtrs[10], bool DrawProjGroup::distributeProjections() { + if (!AutoDistribute.getValue()) { + return true; + } DrawProjGroupItem *viewPtrs[10]; arrangeViewPointers(viewPtrs); @@ -485,41 +494,37 @@ bool DrawProjGroup::distributeProjections() double xSpacing = scale * spacingX.getValue(); //in mm double ySpacing = scale * spacingY.getValue(); //in mm - if (viewPtrs[0] && - viewPtrs[0]->allowAutoPos() && + if (viewPtrs[0] && viewPtrs[0]->allowAutoPos() && bboxes[0].IsValid()) { double displace = std::max(bboxes[0].LengthX() + bboxes[4].LengthX(), bboxes[0].LengthY() + bboxes[4].LengthY()); viewPtrs[0]->X.setValue(displace / -2.0 - xSpacing); viewPtrs[0]->Y.setValue(displace / 2.0 + ySpacing); } - if (viewPtrs[1] && - viewPtrs[1]->allowAutoPos() && + if (viewPtrs[1] && viewPtrs[1]->allowAutoPos() && bboxes[1].IsValid()) { viewPtrs[1]->Y.setValue((bboxes[1].LengthY() + bboxes[4].LengthY()) / 2.0 + ySpacing); } - if (viewPtrs[2] && viewPtrs[2]->allowAutoPos()) { + if (viewPtrs[2] && viewPtrs[2]->allowAutoPos() + ) { double displace = std::max(bboxes[2].LengthX() + bboxes[4].LengthX(), bboxes[2].LengthY() + bboxes[4].LengthY()); viewPtrs[2]->X.setValue(displace / 2.0 + xSpacing); viewPtrs[2]->Y.setValue(displace / 2.0 + ySpacing); } - if (viewPtrs[3] && - viewPtrs[3]->allowAutoPos() && + if (viewPtrs[3] && viewPtrs[3]->allowAutoPos() && bboxes[3].IsValid() && bboxes[4].IsValid()) { viewPtrs[3]->X.setValue((bboxes[3].LengthX() + bboxes[4].LengthX()) / -2.0 - xSpacing); } if (viewPtrs[4]) { // TODO: Move this check above, and figure out a sane bounding box based on other existing views } - if (viewPtrs[5] && - viewPtrs[5]->allowAutoPos() && + if (viewPtrs[5] && viewPtrs[5]->allowAutoPos() && bboxes[5].IsValid() && bboxes[4].IsValid()) { viewPtrs[5]->X.setValue((bboxes[5].LengthX() + bboxes[4].LengthX()) / 2.0 + xSpacing); } - if (viewPtrs[6] && - viewPtrs[6]->allowAutoPos() && + if (viewPtrs[6] && viewPtrs[6]->allowAutoPos() && bboxes[6].IsValid()) { //"Rear" if (viewPtrs[5] && bboxes[5].IsValid()) { @@ -529,22 +534,19 @@ bool DrawProjGroup::distributeProjections() viewPtrs[6]->X.setValue((bboxes[6].LengthX() + bboxes[4].LengthX()) / 2.0 + xSpacing); } } - if (viewPtrs[7] && - viewPtrs[7]->allowAutoPos() && + if (viewPtrs[7] && viewPtrs[7]->allowAutoPos() && bboxes[7].IsValid()) { double displace = std::max(bboxes[7].LengthX() + bboxes[4].LengthX(), bboxes[7].LengthY() + bboxes[4].LengthY()); viewPtrs[7]->X.setValue(displace / -2.0 - xSpacing); viewPtrs[7]->Y.setValue(displace / -2.0 - ySpacing); } - if (viewPtrs[8] && - viewPtrs[8]->allowAutoPos() && + if (viewPtrs[8] && viewPtrs[8]->allowAutoPos() && bboxes[8].IsValid() && bboxes[4].IsValid()) { viewPtrs[8]->Y.setValue((bboxes[8].LengthY() + bboxes[4].LengthY()) / -2.0 - ySpacing); } - if (viewPtrs[9] && - viewPtrs[9]->allowAutoPos() && + if (viewPtrs[9] && viewPtrs[9]->allowAutoPos() && bboxes[9].IsValid()) { double displace = std::max(bboxes[9].LengthX() + bboxes[4].LengthX(), bboxes[9].LengthY() + bboxes[4].LengthY()); @@ -555,16 +557,17 @@ bool DrawProjGroup::distributeProjections() return true; } -//!allow child DPGI's to be automatically positioned +//!allow all child DPGI's to be automatically positioned void DrawProjGroup::resetPositions(void) { - for( auto it : Views.getValues() ) { - auto view( dynamic_cast(it) ); - if( view ) { - view->setAutoPos(true); - //X,Y == 0?? - } - } + if (AutoDistribute.getValue()) { + for( auto it : Views.getValues() ) { + auto view( dynamic_cast(it) ); + if( view ) { + view->setAutoPos(true); + } + } + } } //TODO: Turn this into a command so it can be issued from python @@ -597,12 +600,14 @@ App::DocumentObjectExecReturn *DrawProjGroup::execute(void) if (!checkFit(page)) { newScale = calculateAutomaticScale(); if(std::abs(Scale.getValue() - newScale) > FLT_EPSILON) { + resetPositions(); Scale.setValue(newScale); } } } else if (ScaleType.isValue("Document")) { newScale = page->Scale.getValue(); if(std::abs(Scale.getValue() - newScale) > FLT_EPSILON) { + resetPositions(); Scale.setValue(newScale); } } else if (ScaleType.isValue("Custom")) { @@ -612,7 +617,7 @@ App::DocumentObjectExecReturn *DrawProjGroup::execute(void) // recalculate positions for children if (Views.getSize()) { updateChildren(newScale); - resetPositions(); + //resetPositions(); distributeProjections(); } return DrawViewCollection::execute(); diff --git a/src/Mod/TechDraw/App/DrawProjGroup.h b/src/Mod/TechDraw/App/DrawProjGroup.h index 0814fd976867..b84164fa2bbf 100644 --- a/src/Mod/TechDraw/App/DrawProjGroup.h +++ b/src/Mod/TechDraw/App/DrawProjGroup.h @@ -52,6 +52,7 @@ class TechDrawExport DrawProjGroup : public TechDraw::DrawViewCollection App::PropertyEnumeration ProjectionType; + App::PropertyBool AutoDistribute; /// Default horizontal spacing between adjacent views on Drawing, in mm App::PropertyFloat spacingX; /// Default vertical spacing between adjacent views on Drawing, in mm diff --git a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp index 7b43144d7bef..b03cb97aaad2 100644 --- a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp @@ -29,6 +29,7 @@ #include #include +#include "DrawProjGroup.h" #include "DrawProjGroupItem.h" #include // generated from DrawProjGroupItemPy.xml @@ -87,13 +88,25 @@ DrawProjGroupItem::~DrawProjGroupItem() void DrawProjGroupItem::onDocumentRestored() { - setAutoPos(false); //if restoring from file, use X,Y from file, not auto! +// setAutoPos(false); //if restoring from file, use X,Y from file, not auto! App::DocumentObjectExecReturn* rc = DrawProjGroupItem::execute(); if (rc) { delete rc; } } +DrawProjGroup* DrawProjGroupItem::getGroup() +{ + DrawProjGroup* result = nullptr; + std::vector parent = getInList(); + for (std::vector::iterator it = parent.begin(); it != parent.end(); ++it) { + if ((*it)->getTypeId().isDerivedFrom(DrawProjGroup::getClassTypeId())) { + result = dynamic_cast(*it); + break; + } + } + return result; +} PyObject *DrawProjGroupItem::getPyObject(void) { diff --git a/src/Mod/TechDraw/App/DrawProjGroupItem.h b/src/Mod/TechDraw/App/DrawProjGroupItem.h index b08f52f6f6cd..c6f6885bd312 100644 --- a/src/Mod/TechDraw/App/DrawProjGroupItem.h +++ b/src/Mod/TechDraw/App/DrawProjGroupItem.h @@ -30,6 +30,7 @@ namespace TechDraw { +class DrawProjGroup; class TechDrawExport DrawProjGroupItem : public TechDraw::DrawViewPart { @@ -50,6 +51,8 @@ class TechDrawExport DrawProjGroupItem : public TechDraw::DrawViewPart // virtual App::DocumentObjectExecReturn *execute(void); // TODO: Delete me too if we take out the implementation //@} + DrawProjGroup* getGroup(void); + /// returns the type name of the ViewProvider virtual const char* getViewProviderName(void) const { return "TechDrawGui::ViewProviderProjGroupItem"; diff --git a/src/Mod/TechDraw/App/DrawView.cpp b/src/Mod/TechDraw/App/DrawView.cpp index af06ae273895..d1dca4e2afff 100644 --- a/src/Mod/TechDraw/App/DrawView.cpp +++ b/src/Mod/TechDraw/App/DrawView.cpp @@ -129,8 +129,8 @@ void DrawView::onChanged(const App::Property* prop) } } else if (prop == &X || prop == &Y) { - if (isMouseMove()) { - setAutoPos(false); //should only be for manual changes? not programmatic changes? + if (isMouseMove()) { //actually "has mouse moved this item?" + setAutoPos(false); } } } @@ -226,6 +226,14 @@ bool DrawView::checkFit(TechDraw::DrawPage* p) const return result; } +void DrawView::setPosition(double x, double y) +{ + //recompute.lock() + X.setValue(x); + Y.setValue(y); + //recompute.unlock() +} + PyObject *DrawView::getPyObject(void) { if (PythonObject.is(Py::_None())) { diff --git a/src/Mod/TechDraw/App/DrawView.h b/src/Mod/TechDraw/App/DrawView.h index 4a4d7490d847..ad6e131cde0d 100644 --- a/src/Mod/TechDraw/App/DrawView.h +++ b/src/Mod/TechDraw/App/DrawView.h @@ -80,6 +80,7 @@ class TechDrawExport DrawView : public App::DocumentObject virtual QRectF getRect() const; //must be overridden by derived class virtual double autoScale(double w, double h) const; virtual bool checkFit(DrawPage*) const; + virtual void setPosition(double x, double y); protected: void onChanged(const App::Property* prop); diff --git a/src/Mod/TechDraw/Gui/QGIView.cpp b/src/Mod/TechDraw/Gui/QGIView.cpp index 2a53b4c3f58e..f7b14918b7e7 100644 --- a/src/Mod/TechDraw/Gui/QGIView.cpp +++ b/src/Mod/TechDraw/Gui/QGIView.cpp @@ -56,6 +56,8 @@ #include "QGIViewClip.h" #include +#include +#include using namespace TechDrawGui; @@ -67,6 +69,9 @@ QGIView::QGIView() locked(false), borderVisible(true), m_innerView(false) + //isAligned(false) + //alignMode("") + //alignAnchor(nullptr) { setCacheMode(QGraphicsItem::NoCache); setHandlesChildEvents(false); @@ -99,6 +104,9 @@ QGIView::QGIView() void QGIView::alignTo(QGraphicsItem*item, const QString &alignment) { +// isAligned = true; +// alignMode = alignment.toStdString(); +// alignAnchor = item; alignHash.clear(); alignHash.insert(alignment, item); } @@ -114,26 +122,33 @@ QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value) } // TODO find a better data structure for this - if(alignHash.size() == 1) { - 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 if(alignMode == QString::fromLatin1("45slash")) { - double dist = ( (newPos.x() - item->pos().x()) + - (item->pos().y() - newPos.y()) ) / 2.0; - - newPos.setX( item->pos().x() + dist); - newPos.setY( item->pos().y() - dist ); - } else if(alignMode == QString::fromLatin1("45backslash")) { - double dist = ( (newPos.x() - item->pos().x()) + - (newPos.y() - item->pos().y()) ) / 2.0; - - newPos.setX( item->pos().x() + dist); - newPos.setY( item->pos().y() + dist ); + // this is just a pair isn't it? + if (getViewObject()->isDerivedFrom(TechDraw::DrawProjGroupItem::getClassTypeId())) { + TechDraw::DrawProjGroupItem* dpgi = static_cast(getViewObject()); + TechDraw::DrawProjGroup* dpg = dpgi->getGroup(); + if ((dpg != nullptr) && dpg->AutoDistribute.getValue()) { + 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 if(alignMode == QString::fromLatin1("45slash")) { + double dist = ( (newPos.x() - item->pos().x()) + + (item->pos().y() - newPos.y()) ) / 2.0; + + newPos.setX( item->pos().x() + dist); + newPos.setY( item->pos().y() - dist ); + } else if(alignMode == QString::fromLatin1("45backslash")) { + double dist = ( (newPos.x() - item->pos().x()) + + (newPos.y() - item->pos().y()) ) / 2.0; + + newPos.setX( item->pos().x() + dist); + newPos.setY( item->pos().y() + dist ); + } + } } } return newPos; @@ -172,11 +187,13 @@ void QGIView::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) if (!isInnerView()) { double tempX = x(), tempY = getY(); - getViewObject()->X.setValue(tempX); - getViewObject()->Y.setValue(tempY); +// getViewObject()->X.setValue(tempX); +// getViewObject()->Y.setValue(tempY); + getViewObject()->setPosition(tempX,tempY); } else { - getViewObject()->X.setValue(x()); - getViewObject()->Y.setValue(getYInClip(y())); +// getViewObject()->X.setValue(x()); +// getViewObject()->Y.setValue(getYInClip(y())); + getViewObject()->setPosition(x(),getYInClip(y())); } getViewObject()->setMouseMove(false); } @@ -278,10 +295,10 @@ void QGIView::setViewFeature(TechDraw::DrawView *obj) viewObj = obj; viewName = obj->getNameInDocument(); - // Set the QGIGroup initial position based on the DrawView - float x = obj->X.getValue(); - float y = obj->Y.getValue(); - setPosition(x, y); + // Set the QGIGroup initial position based on the DrawView ( wrong. new views are always at Page center) +// float x = obj->X.getValue(); +// float y = obj->Y.getValue(); +// setPosition(x, y); } void QGIView::toggleCache(bool state) diff --git a/src/Mod/TechDraw/Gui/QGIView.h b/src/Mod/TechDraw/Gui/QGIView.h index 752d4ada164c..fa87f921afd7 100644 --- a/src/Mod/TechDraw/Gui/QGIView.h +++ b/src/Mod/TechDraw/Gui/QGIView.h @@ -110,6 +110,8 @@ class TechDrawGuiExport QGIView : public QGraphicsItemGroup std::string viewName; QHash alignHash; + //std::string alignMode; + //QGIView* alignAnchor; bool locked; bool borderVisible; bool m_visibility;