Allow manual repositioning of ProjGroup views
This commit is contained in:
parent
70b5c241d1
commit
cd87af3746
|
@ -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");
|
||||
|
||||
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<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
|
||||
|
@ -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();
|
||||
|
|
|
@ -52,6 +52,7 @@ public:
|
|||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
namespace TechDraw
|
||||
{
|
||||
class DrawProjGroup;
|
||||
|
||||
class TechDrawExport DrawProjGroupItem : public TechDraw::DrawViewPart
|
||||
{
|
||||
|
@ -50,6 +51,8 @@ public:
|
|||
// 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";
|
||||
|
|
|
@ -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())) {
|
||||
|
|
|
@ -80,6 +80,7 @@ public:
|
|||
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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
// 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;
|
||||
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 );
|
||||
} 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 );
|
||||
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)
|
||||
|
|
|
@ -110,6 +110,8 @@ protected:
|
|||
std::string viewName;
|
||||
|
||||
QHash<QString, QGraphicsItem*> alignHash;
|
||||
//std::string alignMode;
|
||||
//QGIView* alignAnchor;
|
||||
bool locked;
|
||||
bool borderVisible;
|
||||
bool m_visibility;
|
||||
|
|
Loading…
Reference in New Issue
Block a user