Block moving a control point if a formula was used.

--HG--
branch : feature
This commit is contained in:
Roman Telezhynskyi 2016-02-27 10:29:32 +02:00
parent 679f90d627
commit 53cb607f34
4 changed files with 167 additions and 57 deletions

View File

@ -69,16 +69,24 @@ VToolSpline::VToolSpline(VAbstractPattern *doc, VContainer *data, quint32 id, co
const auto spl = VAbstractTool::data.GeometricObject<VSpline>(id); const auto spl = VAbstractTool::data.GeometricObject<VSpline>(id);
const bool freeAngle1 = qmu::QmuTokenParser::IsSingle(spl->GetStartAngleFormula());
const bool freeLength1 = qmu::QmuTokenParser::IsSingle(spl->GetC1LengthFormula());
auto *controlPoint1 = new VControlPointSpline(1, SplinePointPosition::FirstPoint, spl->GetP2(), auto *controlPoint1 = new VControlPointSpline(1, SplinePointPosition::FirstPoint, spl->GetP2(),
spl->GetP1().toQPointF(), *data->GetPatternUnit(), this); spl->GetP1().toQPointF(), *data->GetPatternUnit(), freeAngle1,
freeLength1, this);
connect(controlPoint1, &VControlPointSpline::ControlPointChangePosition, this, connect(controlPoint1, &VControlPointSpline::ControlPointChangePosition, this,
&VToolSpline::ControlPointChangePosition); &VToolSpline::ControlPointChangePosition);
connect(this, &VToolSpline::setEnabledPoint, controlPoint1, &VControlPointSpline::setEnabledPoint); connect(this, &VToolSpline::setEnabledPoint, controlPoint1, &VControlPointSpline::setEnabledPoint);
connect(controlPoint1, &VControlPointSpline::ShowContextMenu, this, &VToolSpline::contextMenuEvent); connect(controlPoint1, &VControlPointSpline::ShowContextMenu, this, &VToolSpline::contextMenuEvent);
controlPoints.append(controlPoint1); controlPoints.append(controlPoint1);
const bool freeAngle2 = qmu::QmuTokenParser::IsSingle(spl->GetEndAngleFormula());
const bool freeLength2 = qmu::QmuTokenParser::IsSingle(spl->GetC2LengthFormula());
auto *controlPoint2 = new VControlPointSpline(1, SplinePointPosition::LastPoint, spl->GetP3(), auto *controlPoint2 = new VControlPointSpline(1, SplinePointPosition::LastPoint, spl->GetP3(),
spl->GetP4().toQPointF(), *data->GetPatternUnit(), this); spl->GetP4().toQPointF(), *data->GetPatternUnit(), freeAngle2,
freeLength2, this);
connect(controlPoint2, &VControlPointSpline::ControlPointChangePosition, this, connect(controlPoint2, &VControlPointSpline::ControlPointChangePosition, this,
&VToolSpline::ControlPointChangePosition); &VToolSpline::ControlPointChangePosition);
connect(this, &VToolSpline::setEnabledPoint, controlPoint2, &VControlPointSpline::setEnabledPoint); connect(this, &VToolSpline::setEnabledPoint, controlPoint2, &VControlPointSpline::setEnabledPoint);
@ -247,11 +255,54 @@ void VToolSpline::ControlPointChangePosition(const qint32 &indexSpline, const Sp
VSpline spl; VSpline spl;
if (position == SplinePointPosition::FirstPoint) if (position == SplinePointPosition::FirstPoint)
{ {
spl = VSpline(spline->GetP1(), pos, spline->GetP3(), spline->GetP4(), spline->GetKcurve()); QLineF line(spline->GetP1().toQPointF(), pos);
qreal newAngle1 = line.angle();
QString newAngle1F = QString().setNum(newAngle1);
qreal newLength1 = line.length();
QString newLength1F = QString().setNum(qApp->fromPixel(newLength1));
if (not qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()))
{
newAngle1 = spline->GetStartAngle();
newAngle1F = spline->GetStartAngleFormula();
}
if (not qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()))
{
newLength1 = spline->GetC1Length();
newLength1F = spline->GetC1LengthFormula();
}
spl = VSpline(spline->GetP1(), spline->GetP4(), newAngle1, newAngle1F, spline->GetEndAngle(),
spline->GetEndAngleFormula(), newLength1, newLength1F, spline->GetC2Length(),
spline->GetC2LengthFormula(), spline->GetKcurve());
} }
else else
{ {
spl = VSpline(spline->GetP1(), spline->GetP2(), pos, spline->GetP4(), spline->GetKcurve()); QLineF line(spline->GetP4().toQPointF(), pos);
qreal newAngle2 = line.angle();
QString newAngle2F = QString().setNum(newAngle2);
qreal newLength2 = line.length();
QString newLength2F = QString().setNum(qApp->fromPixel(newLength2));
if (not qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()))
{
newAngle2 = spline->GetEndAngle();
newAngle2F = spline->GetEndAngleFormula();
}
if (not qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula()))
{
newLength2 = spline->GetC2Length();
newLength2F = spline->GetC2LengthFormula();
}
spl = VSpline(spline->GetP1(), spline->GetP4(), spline->GetStartAngle(), spline->GetStartAngleFormula(),
newAngle2, newAngle2F, spline->GetC1Length(), spline->GetC1LengthFormula(),
newLength2, newLength2F, spline->GetKcurve());
} }
MoveSpline *moveSpl = new MoveSpline(doc, spline.data(), spl, id, this->scene()); MoveSpline *moveSpl = new MoveSpline(doc, spline.data(), spl, id, this->scene());
@ -544,13 +595,21 @@ void VToolSpline::RefreshGeometry()
const auto spl = VAbstractTool::data.GeometricObject<VSpline>(id); const auto spl = VAbstractTool::data.GeometricObject<VSpline>(id);
{ {
const bool freeAngle1 = qmu::QmuTokenParser::IsSingle(spl->GetStartAngleFormula());
const bool freeLength1 = qmu::QmuTokenParser::IsSingle(spl->GetC1LengthFormula());
const QPointF splinePoint = VAbstractTool::data.GeometricObject<VPointF>(spl->GetP1().id())->toQPointF(); const QPointF splinePoint = VAbstractTool::data.GeometricObject<VPointF>(spl->GetP1().id())->toQPointF();
controlPoints[0]->RefreshCtrlPoint(1, SplinePointPosition::FirstPoint, spl->GetP2(), splinePoint); controlPoints[0]->RefreshCtrlPoint(1, SplinePointPosition::FirstPoint, spl->GetP2(), splinePoint, freeAngle1,
freeLength1);
} }
{ {
const bool freeAngle2 = qmu::QmuTokenParser::IsSingle(spl->GetEndAngleFormula());
const bool freeLength2 = qmu::QmuTokenParser::IsSingle(spl->GetC2LengthFormula());
const QPointF splinePoint = VAbstractTool::data.GeometricObject<VPointF>(spl->GetP4().id())->toQPointF(); const QPointF splinePoint = VAbstractTool::data.GeometricObject<VPointF>(spl->GetP4().id())->toQPointF();
controlPoints[1]->RefreshCtrlPoint(1, SplinePointPosition::LastPoint, spl->GetP3(), splinePoint); controlPoints[1]->RefreshCtrlPoint(1, SplinePointPosition::LastPoint, spl->GetP3(), splinePoint, freeAngle2,
freeLength2);
} }
controlPoints[0]->blockSignals(false); controlPoints[0]->blockSignals(false);
@ -569,11 +628,7 @@ void VToolSpline::SetSplineAttributes(QDomElement &domElement, const VSpline &sp
{ {
SCASSERT(doc != nullptr); SCASSERT(doc != nullptr);
if (domElement.attribute(AttrType) == OldToolType) doc->SetAttribute(domElement, AttrType, ToolType);
{
doc->SetAttribute(domElement, AttrType, ToolType);
}
doc->SetAttribute(domElement, AttrPoint1, spl.GetP1().id()); doc->SetAttribute(domElement, AttrPoint1, spl.GetP1().id());
doc->SetAttribute(domElement, AttrPoint4, spl.GetP4().id()); doc->SetAttribute(domElement, AttrPoint4, spl.GetP4().id());
doc->SetAttribute(domElement, AttrAngle1, spl.GetStartAngleFormula()); doc->SetAttribute(domElement, AttrAngle1, spl.GetStartAngleFormula());

View File

@ -68,7 +68,7 @@ VToolSplinePath::VToolSplinePath(VAbstractPattern *doc, VContainer *data, quint3
{ {
VSpline spl = splPath->GetSpline(i); VSpline spl = splPath->GetSpline(i);
auto *controlPoint = new VControlPointSpline(i, SplinePointPosition::FirstPoint, spl.GetP2(), auto *controlPoint = new VControlPointSpline(i, SplinePointPosition::FirstPoint, spl.GetP2(),
spl.GetP1().toQPointF(), *data->GetPatternUnit(), this); spl.GetP1().toQPointF(), *data->GetPatternUnit(), true, true, this);
connect(controlPoint, &VControlPointSpline::ControlPointChangePosition, this, connect(controlPoint, &VControlPointSpline::ControlPointChangePosition, this,
&VToolSplinePath::ControlPointChangePosition); &VToolSplinePath::ControlPointChangePosition);
connect(this, &VToolSplinePath::setEnabledPoint, controlPoint, &VControlPointSpline::setEnabledPoint); connect(this, &VToolSplinePath::setEnabledPoint, controlPoint, &VControlPointSpline::setEnabledPoint);
@ -76,7 +76,7 @@ VToolSplinePath::VToolSplinePath(VAbstractPattern *doc, VContainer *data, quint3
controlPoints.append(controlPoint); controlPoints.append(controlPoint);
controlPoint = new VControlPointSpline(i, SplinePointPosition::LastPoint, spl.GetP3(), spl.GetP4().toQPointF(), controlPoint = new VControlPointSpline(i, SplinePointPosition::LastPoint, spl.GetP3(), spl.GetP4().toQPointF(),
*data->GetPatternUnit(), this); *data->GetPatternUnit(), true, true, this);
connect(controlPoint, &VControlPointSpline::ControlPointChangePosition, this, connect(controlPoint, &VControlPointSpline::ControlPointChangePosition, this,
&VToolSplinePath::ControlPointChangePosition); &VToolSplinePath::ControlPointChangePosition);
connect(this, &VToolSplinePath::setEnabledPoint, controlPoint, &VControlPointSpline::setEnabledPoint); connect(this, &VToolSplinePath::setEnabledPoint, controlPoint, &VControlPointSpline::setEnabledPoint);

View File

@ -44,7 +44,9 @@ VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePointP
controlLine(nullptr), controlLine(nullptr),
indexSpline(indexSpline), indexSpline(indexSpline),
position(position), position(position),
patternUnit(patternUnit) patternUnit(patternUnit),
freeAngle(true),
freeLength(true)
{ {
Init(); Init();
} }
@ -60,13 +62,15 @@ VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePointP
*/ */
VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePointPosition position, VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePointPosition position,
const QPointF &controlPoint, const QPointF &splinePoint, Unit patternUnit, const QPointF &controlPoint, const QPointF &splinePoint, Unit patternUnit,
QGraphicsItem *parent) bool freeAngle, bool freeLength, QGraphicsItem *parent)
:QGraphicsEllipseItem(parent), :QGraphicsEllipseItem(parent),
radius(CircleRadius()), radius(CircleRadius()),
controlLine(nullptr), controlLine(nullptr),
indexSpline(indexSpline), indexSpline(indexSpline),
position(position), position(position),
patternUnit(patternUnit) patternUnit(patternUnit),
freeAngle(freeAngle),
freeLength(freeLength)
{ {
Init(); Init();
@ -107,7 +111,10 @@ void VControlPointSpline::paint(QPainter *painter, const QStyleOptionGraphicsIte
void VControlPointSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event) void VControlPointSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{ {
this->setPen(QPen(Qt::black, ToPixel(WidthMainLine(patternUnit), patternUnit))); this->setPen(QPen(Qt::black, ToPixel(WidthMainLine(patternUnit), patternUnit)));
SetOverrideCursor(cursorArrowOpenHand, 1, 1); if (freeAngle || freeLength)
{
SetOverrideCursor(cursorArrowOpenHand, 1, 1);
}
QGraphicsEllipseItem::hoverEnterEvent(event); QGraphicsEllipseItem::hoverEnterEvent(event);
} }
@ -115,8 +122,11 @@ void VControlPointSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
void VControlPointSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) void VControlPointSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{ {
this->setPen(QPen(Qt::black, ToPixel(WidthHairLine(patternUnit), patternUnit))); this->setPen(QPen(Qt::black, ToPixel(WidthHairLine(patternUnit), patternUnit)));
//Disable cursor-arrow-openhand if (freeAngle || freeLength)
RestoreOverrideCursor(cursorArrowOpenHand); {
//Disable cursor-arrow-openhand
RestoreOverrideCursor(cursorArrowOpenHand);
}
QGraphicsEllipseItem::hoverLeaveEvent(event); QGraphicsEllipseItem::hoverLeaveEvent(event);
} }
@ -129,49 +139,81 @@ void VControlPointSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
*/ */
QVariant VControlPointSpline::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) QVariant VControlPointSpline::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{ {
if (change == ItemPositionChange && scene()) switch (change)
{ {
// Each time we move something we call recalculation scene rect. In some cases this can cause moving case ItemPositionChange:
// objects positions. And this cause infinite redrawing. That's why we wait the finish of saving the last move.
static bool changeFinished = true;
if (changeFinished)
{ {
changeFinished = false; if (not freeAngle || not freeLength)
// value - new position.
QPointF newPos = value.toPointF();
emit ControlPointChangePosition(indexSpline, position, newPos);
if (scene())
{ {
const QList<QGraphicsView *> viewList = scene()->views(); const QPointF splPoint = controlLine->line().p1() + pos();
if (not viewList.isEmpty())
QLineF newLine(splPoint, value.toPointF());// value - new position.
QLineF oldLine(splPoint, pos());// pos() - old position.
if (not freeAngle)
{ {
if (QGraphicsView *view = viewList.at(0)) newLine.setAngle(oldLine.angle());
}
if (not freeLength)
{
qreal length = controlLine->line().length();
qreal l2 = oldLine.length();
newLine.setLength(oldLine.length());
}
return newLine.p2();
}
break;
}
case ItemPositionHasChanged:
{
// Each time we move something we call recalculation scene rect. In some cases this can cause moving
// objects positions. And this cause infinite redrawing. That's why we wait the finish of saving the last
// move.
static bool changeFinished = true;
if (changeFinished)
{
changeFinished = false;
// value - new position.
emit ControlPointChangePosition(indexSpline, position, value.toPointF());
if (scene())
{
const QList<QGraphicsView *> viewList = scene()->views();
if (not viewList.isEmpty())
{ {
const int xmargin = 50; if (QGraphicsView *view = viewList.at(0))
const int ymargin = 50;
const QRectF viewRect = VMainGraphicsView::SceneVisibleArea(view);
const QRectF itemRect = mapToScene(boundingRect()).boundingRect();
// If item's rect is bigger than view's rect ensureVisible works very unstable.
if (itemRect.height() + 2*ymargin < viewRect.height() &&
itemRect.width() + 2*xmargin < viewRect.width())
{ {
view->ensureVisible(itemRect, xmargin, ymargin); const int xmargin = 50;
} const int ymargin = 50;
else
{ const QRectF viewRect = VMainGraphicsView::SceneVisibleArea(view);
// Ensure visible only small rect around a cursor const QRectF itemRect = mapToScene(boundingRect()).boundingRect();
VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(scene());
SCASSERT(currentScene); // If item's rect is bigger than view's rect ensureVisible works very unstable.
const QPointF cursorPosition = currentScene->getScenePos(); if (itemRect.height() + 2*ymargin < viewRect.height() &&
view->ensureVisible(QRectF(cursorPosition.x()-5, cursorPosition.y()-5, 10, 10)); itemRect.width() + 2*xmargin < viewRect.width())
{
view->ensureVisible(itemRect, xmargin, ymargin);
}
else
{
// Ensure visible only small rect around a cursor
VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(scene());
SCASSERT(currentScene);
const QPointF cursorPosition = currentScene->getScenePos();
view->ensureVisible(QRectF(cursorPosition.x()-5, cursorPosition.y()-5, 10, 10));
}
} }
} }
} }
changeFinished = true;
} }
changeFinished = true; break;
} }
default:
break;
} }
return QGraphicsItem::itemChange(change, value); return QGraphicsItem::itemChange(change, value);
} }
@ -181,7 +223,10 @@ void VControlPointSpline::mousePressEvent(QGraphicsSceneMouseEvent *event)
{ {
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{ {
SetOverrideCursor(cursorArrowCloseHand, 1, 1); if (freeAngle || freeLength)
{
SetOverrideCursor(cursorArrowCloseHand, 1, 1);
}
} }
QGraphicsEllipseItem::mousePressEvent(event); QGraphicsEllipseItem::mousePressEvent(event);
} }
@ -191,8 +236,11 @@ void VControlPointSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{ {
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{ {
//Disable cursor-arrow-closehand if (freeAngle || freeLength)
RestoreOverrideCursor(cursorArrowCloseHand); {
//Disable cursor-arrow-closehand
RestoreOverrideCursor(cursorArrowCloseHand);
}
} }
QGraphicsEllipseItem::mouseReleaseEvent(event); QGraphicsEllipseItem::mouseReleaseEvent(event);
} }
@ -235,10 +283,13 @@ void VControlPointSpline::SetCtrlLine(const QPointF &controlPoint, const QPointF
* @param splinePoint spline point. * @param splinePoint spline point.
*/ */
void VControlPointSpline::RefreshCtrlPoint(const qint32 &indexSpline, SplinePointPosition pos, void VControlPointSpline::RefreshCtrlPoint(const qint32 &indexSpline, SplinePointPosition pos,
const QPointF &controlPoint, const QPointF &splinePoint) const QPointF &controlPoint, const QPointF &splinePoint, bool freeAngle,
bool freeLength)
{ {
if (this->indexSpline == indexSpline && this->position == pos) if (this->indexSpline == indexSpline && this->position == pos)
{ {
this->freeAngle = freeAngle;
this->freeLength = freeLength;
this->setPos(controlPoint); this->setPos(controlPoint);
SetCtrlLine(controlPoint, splinePoint); SetCtrlLine(controlPoint, splinePoint);
} }

View File

@ -44,7 +44,8 @@ public:
VControlPointSpline(const qint32 &indexSpline, SplinePointPosition position, Unit patternUnit, VControlPointSpline(const qint32 &indexSpline, SplinePointPosition position, Unit patternUnit,
QGraphicsItem * parent = nullptr); QGraphicsItem * parent = nullptr);
VControlPointSpline(const qint32 &indexSpline, SplinePointPosition position, const QPointF &controlPoint, VControlPointSpline(const qint32 &indexSpline, SplinePointPosition position, const QPointF &controlPoint,
const QPointF &splinePoint, Unit patternUnit, QGraphicsItem * parent = nullptr); const QPointF &splinePoint, Unit patternUnit, bool freeAngle, bool freeLength,
QGraphicsItem * parent = nullptr);
virtual ~VControlPointSpline() Q_DECL_OVERRIDE; virtual ~VControlPointSpline() Q_DECL_OVERRIDE;
virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option,
QWidget * widget = 0) Q_DECL_OVERRIDE; QWidget * widget = 0) Q_DECL_OVERRIDE;
@ -66,7 +67,7 @@ signals:
void ShowContextMenu(QGraphicsSceneContextMenuEvent *event); void ShowContextMenu(QGraphicsSceneContextMenuEvent *event);
public slots: public slots:
void RefreshCtrlPoint(const qint32 &indexSpline, SplinePointPosition pos, const QPointF &controlPoint, void RefreshCtrlPoint(const qint32 &indexSpline, SplinePointPosition pos, const QPointF &controlPoint,
const QPointF &splinePoint); const QPointF &splinePoint, bool freeAngle = true, bool freeLength = true);
void setEnabledPoint(bool enable); void setEnabledPoint(bool enable);
protected: protected:
/** @brief radius radius circle. */ /** @brief radius radius circle. */
@ -91,6 +92,9 @@ private:
Unit patternUnit; Unit patternUnit;
bool freeAngle;
bool freeLength;
inline qreal CircleRadius() const; inline qreal CircleRadius() const;
void Init(); void Init();
void SetCtrlLine(const QPointF &controlPoint, const QPointF &splinePoint); void SetCtrlLine(const QPointF &controlPoint, const QPointF &splinePoint);