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 bool freeAngle1 = qmu::QmuTokenParser::IsSingle(spl->GetStartAngleFormula());
const bool freeLength1 = qmu::QmuTokenParser::IsSingle(spl->GetC1LengthFormula());
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,
&VToolSpline::ControlPointChangePosition);
connect(this, &VToolSpline::setEnabledPoint, controlPoint1, &VControlPointSpline::setEnabledPoint);
connect(controlPoint1, &VControlPointSpline::ShowContextMenu, this, &VToolSpline::contextMenuEvent);
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(),
spl->GetP4().toQPointF(), *data->GetPatternUnit(), this);
spl->GetP4().toQPointF(), *data->GetPatternUnit(), freeAngle2,
freeLength2, this);
connect(controlPoint2, &VControlPointSpline::ControlPointChangePosition, this,
&VToolSpline::ControlPointChangePosition);
connect(this, &VToolSpline::setEnabledPoint, controlPoint2, &VControlPointSpline::setEnabledPoint);
@ -247,11 +255,54 @@ void VToolSpline::ControlPointChangePosition(const qint32 &indexSpline, const Sp
VSpline spl;
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
{
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());
@ -544,13 +595,21 @@ void VToolSpline::RefreshGeometry()
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();
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();
controlPoints[1]->RefreshCtrlPoint(1, SplinePointPosition::LastPoint, spl->GetP3(), splinePoint);
controlPoints[1]->RefreshCtrlPoint(1, SplinePointPosition::LastPoint, spl->GetP3(), splinePoint, freeAngle2,
freeLength2);
}
controlPoints[0]->blockSignals(false);
@ -569,11 +628,7 @@ void VToolSpline::SetSplineAttributes(QDomElement &domElement, const VSpline &sp
{
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, AttrPoint4, spl.GetP4().id());
doc->SetAttribute(domElement, AttrAngle1, spl.GetStartAngleFormula());

View File

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

View File

@ -44,7 +44,9 @@ VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePointP
controlLine(nullptr),
indexSpline(indexSpline),
position(position),
patternUnit(patternUnit)
patternUnit(patternUnit),
freeAngle(true),
freeLength(true)
{
Init();
}
@ -60,13 +62,15 @@ VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePointP
*/
VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePointPosition position,
const QPointF &controlPoint, const QPointF &splinePoint, Unit patternUnit,
QGraphicsItem *parent)
bool freeAngle, bool freeLength, QGraphicsItem *parent)
:QGraphicsEllipseItem(parent),
radius(CircleRadius()),
controlLine(nullptr),
indexSpline(indexSpline),
position(position),
patternUnit(patternUnit)
patternUnit(patternUnit),
freeAngle(freeAngle),
freeLength(freeLength)
{
Init();
@ -107,7 +111,10 @@ void VControlPointSpline::paint(QPainter *painter, const QStyleOptionGraphicsIte
void VControlPointSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
this->setPen(QPen(Qt::black, ToPixel(WidthMainLine(patternUnit), patternUnit)));
SetOverrideCursor(cursorArrowOpenHand, 1, 1);
if (freeAngle || freeLength)
{
SetOverrideCursor(cursorArrowOpenHand, 1, 1);
}
QGraphicsEllipseItem::hoverEnterEvent(event);
}
@ -115,8 +122,11 @@ void VControlPointSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
void VControlPointSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
this->setPen(QPen(Qt::black, ToPixel(WidthHairLine(patternUnit), patternUnit)));
//Disable cursor-arrow-openhand
RestoreOverrideCursor(cursorArrowOpenHand);
if (freeAngle || freeLength)
{
//Disable cursor-arrow-openhand
RestoreOverrideCursor(cursorArrowOpenHand);
}
QGraphicsEllipseItem::hoverLeaveEvent(event);
}
@ -129,49 +139,81 @@ void VControlPointSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
*/
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
// 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)
case ItemPositionChange:
{
changeFinished = false;
// value - new position.
QPointF newPos = value.toPointF();
emit ControlPointChangePosition(indexSpline, position, newPos);
if (scene())
if (not freeAngle || not freeLength)
{
const QList<QGraphicsView *> viewList = scene()->views();
if (not viewList.isEmpty())
const QPointF splPoint = controlLine->line().p1() + pos();
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;
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())
if (QGraphicsView *view = viewList.at(0))
{
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));
const int xmargin = 50;
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);
}
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);
}
@ -181,7 +223,10 @@ void VControlPointSpline::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
SetOverrideCursor(cursorArrowCloseHand, 1, 1);
if (freeAngle || freeLength)
{
SetOverrideCursor(cursorArrowCloseHand, 1, 1);
}
}
QGraphicsEllipseItem::mousePressEvent(event);
}
@ -191,8 +236,11 @@ void VControlPointSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
//Disable cursor-arrow-closehand
RestoreOverrideCursor(cursorArrowCloseHand);
if (freeAngle || freeLength)
{
//Disable cursor-arrow-closehand
RestoreOverrideCursor(cursorArrowCloseHand);
}
}
QGraphicsEllipseItem::mouseReleaseEvent(event);
}
@ -235,10 +283,13 @@ void VControlPointSpline::SetCtrlLine(const QPointF &controlPoint, const QPointF
* @param splinePoint spline point.
*/
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)
{
this->freeAngle = freeAngle;
this->freeLength = freeLength;
this->setPos(controlPoint);
SetCtrlLine(controlPoint, splinePoint);
}

View File

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