Skip to content

Commit

Permalink
Allow manual repositioning of ProjGroup views
Browse files Browse the repository at this point in the history
  • Loading branch information
WandererFan authored and yorikvanhavre committed Oct 31, 2016
1 parent 70b5c24 commit cd87af3
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 62 deletions.
67 changes: 36 additions & 31 deletions src/Mod/TechDraw/App/DrawProjGroup.cpp
Expand Up @@ -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()));
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -465,6 +471,9 @@ void DrawProjGroup::makeViewBbs(DrawProjGroupItem *viewPtrs[10],

bool DrawProjGroup::distributeProjections()
{
if (!AutoDistribute.getValue()) {
return true;
}
DrawProjGroupItem *viewPtrs[10];

arrangeViewPointers(viewPtrs);
Expand All @@ -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()) {
Expand All @@ -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());
Expand All @@ -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<DrawProjGroupItem *>(it) );
if( view ) {
view->setAutoPos(true);
//X,Y == 0??
}
}
if (AutoDistribute.getValue()) {
for( auto it : Views.getValues() ) {
auto view( dynamic_cast<DrawProjGroupItem *>(it) );
if( view ) {
view->setAutoPos(true);
}
}
}
}

//TODO: Turn this into a command so it can be issued from python
Expand Down Expand Up @@ -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")) {
Expand All @@ -612,7 +617,7 @@ App::DocumentObjectExecReturn *DrawProjGroup::execute(void)
// recalculate positions for children
if (Views.getSize()) {
updateChildren(newScale);
resetPositions();
//resetPositions();
distributeProjections();
}
return DrawViewCollection::execute();
Expand Down
1 change: 1 addition & 0 deletions src/Mod/TechDraw/App/DrawProjGroup.h
Expand Up @@ -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
Expand Down
15 changes: 14 additions & 1 deletion src/Mod/TechDraw/App/DrawProjGroupItem.cpp
Expand Up @@ -29,6 +29,7 @@
#include <Base/Console.h>
#include <Base/Writer.h>

#include "DrawProjGroup.h"
#include "DrawProjGroupItem.h"

#include <Mod/TechDraw/App/DrawProjGroupItemPy.h> // generated from DrawProjGroupItemPy.xml
Expand Down Expand Up @@ -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<App::DocumentObject*> parent = getInList();
for (std::vector<App::DocumentObject*>::iterator it = parent.begin(); it != parent.end(); ++it) {
if ((*it)->getTypeId().isDerivedFrom(DrawProjGroup::getClassTypeId())) {
result = dynamic_cast<TechDraw::DrawProjGroup *>(*it);
break;
}
}
return result;
}

PyObject *DrawProjGroupItem::getPyObject(void)
{
Expand Down
3 changes: 3 additions & 0 deletions src/Mod/TechDraw/App/DrawProjGroupItem.h
Expand Up @@ -30,6 +30,7 @@

namespace TechDraw
{
class DrawProjGroup;

class TechDrawExport DrawProjGroupItem : public TechDraw::DrawViewPart
{
Expand All @@ -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";
Expand Down
12 changes: 10 additions & 2 deletions src/Mod/TechDraw/App/DrawView.cpp
Expand Up @@ -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);
}
}
}
Expand Down Expand Up @@ -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())) {
Expand Down
1 change: 1 addition & 0 deletions src/Mod/TechDraw/App/DrawView.h
Expand Up @@ -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);
Expand Down
73 changes: 45 additions & 28 deletions src/Mod/TechDraw/Gui/QGIView.cpp
Expand Up @@ -56,6 +56,8 @@
#include "QGIViewClip.h"

#include <Mod/TechDraw/App/DrawViewClip.h>
#include <Mod/TechDraw/App/DrawProjGroup.h>
#include <Mod/TechDraw/App/DrawProjGroupItem.h>

using namespace TechDrawGui;

Expand All @@ -67,6 +69,9 @@ QGIView::QGIView()
locked(false),
borderVisible(true),
m_innerView(false)
//isAligned(false)
//alignMode("")
//alignAnchor(nullptr)
{
setCacheMode(QGraphicsItem::NoCache);
setHandlesChildEvents(false);
Expand Down Expand Up @@ -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);
}
Expand All @@ -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<TechDraw::DrawProjGroupItem*>(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;
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions src/Mod/TechDraw/Gui/QGIView.h
Expand Up @@ -110,6 +110,8 @@ class TechDrawGuiExport QGIView : public QGraphicsItemGroup
std::string viewName;

QHash<QString, QGraphicsItem*> alignHash;
//std::string alignMode;
//QGIView* alignAnchor;
bool locked;
bool borderVisible;
bool m_visibility;
Expand Down

0 comments on commit cd87af3

Please sign in to comment.