Movable spline path.

--HG--
branch : feature
This commit is contained in:
Roman Telezhynskyi 2016-03-05 23:06:54 +02:00
parent 2b3c13eb1d
commit f53fe379c6
6 changed files with 126 additions and 95 deletions

View File

@ -28,6 +28,8 @@
#include "vsplinepoint.h"
#include "vsplinepoint_p.h"
#include "../qmuparser/qmutokenparser.h"
#include <QDebug>
#include <QLineF>
@ -322,3 +324,10 @@ void VSplinePoint::SetLength2(const qreal &value, const QString &length2F)
d->length2 = value;
d->length2F = length2F;
}
//---------------------------------------------------------------------------------------------------------------------
bool VSplinePoint::IsMovable() const
{
return qmu::QmuTokenParser::IsSingle(d->angle1F) && qmu::QmuTokenParser::IsSingle(d->angle2F) &&
qmu::QmuTokenParser::IsSingle(d->length1F) && qmu::QmuTokenParser::IsSingle(d->length2F);
}

View File

@ -98,6 +98,8 @@ public:
qreal Length2() const;
QString Length2Formula() const;
void SetLength2(const qreal &value, const QString &length2F);
bool IsMovable() const;
protected:
QSharedDataPointer<VSplinePointData> d;
};

View File

@ -336,12 +336,7 @@ void VToolSpline::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
if (qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula()))
if (IsMovable())
{
SetOverrideCursor(cursorArrowCloseHand, 1, 1);
oldPosition = event->scenePos();
@ -359,12 +354,7 @@ void VToolSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
if (qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula()))
if (IsMovable())
{
//Disable cursor-arrow-closehand
RestoreOverrideCursor(cursorArrowCloseHand);
@ -377,12 +367,7 @@ void VToolSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
//---------------------------------------------------------------------------------------------------------------------
void VToolSpline::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
if (qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula()))
if (IsMovable())
{
// Don't need check if left mouse button was pressed. According to the Qt documentation "If you do receive this
// event, you can be certain that this item also received a mouse press event, and that this item is the current
@ -392,6 +377,7 @@ void VToolSpline::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
// "weight" describes how the influence of the drag should be distributed
// among the handles; 0 = front handle only, 1 = back handle only.
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
const qreal t = spline->ParamT(oldPosition);
if (qFloor(t) == -1)
@ -460,12 +446,7 @@ void VToolSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
if (flags() & QGraphicsItem::ItemIsMovable)
{
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
if (qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula()))
if (IsMovable())
{
SetOverrideCursor(cursorArrowOpenHand, 1, 1);
}
@ -479,12 +460,7 @@ void VToolSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
if (flags() & QGraphicsItem::ItemIsMovable)
{
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
if (qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula()))
if (IsMovable())
{
//Disable cursor-arrow-openhand
RestoreOverrideCursor(cursorArrowOpenHand);
@ -515,6 +491,17 @@ void VToolSpline::SetVisualization()
}
}
//---------------------------------------------------------------------------------------------------------------------
bool VToolSpline::IsMovable() const
{
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
return qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula());
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief RefreshGeometry refresh item on scene.

View File

@ -80,6 +80,7 @@ private:
Q_DISABLE_COPY(VToolSpline)
QPointF oldPosition;
bool IsMovable() const;
void RefreshGeometry ();
void SetSplineAttributes(QDomElement &domElement, const VSpline &spl);
};

View File

@ -53,7 +53,9 @@ const QString VToolSplinePath::OldToolType = QStringLiteral("path");
*/
VToolSplinePath::VToolSplinePath(VAbstractPattern *doc, VContainer *data, quint32 id, const QString &color,
const Source &typeCreation, QGraphicsItem *parent)
:VAbstractSpline(doc, data, id, parent), oldPosition()
: VAbstractSpline(doc, data, id, parent),
oldPosition(),
splIndex(-1)
{
sceneType = SceneObject::SplinePath;
lineColor = color;
@ -256,7 +258,7 @@ void VToolSplinePath::UpdateControlPoints(const VSpline &spl, VSplinePath &splPa
{
VSplinePoint p = splPath.GetSplinePoint(indexSpline, SplinePointPosition::FirstPoint);
p.SetAngle2(spl.GetStartAngle(), spl.GetStartAngleFormula());
p.SetLength2(spl.GetC2Length(), spl.GetC2LengthFormula());
p.SetLength2(spl.GetC1Length(), spl.GetC1LengthFormula());
splPath.UpdatePoint(indexSpline, SplinePointPosition::FirstPoint, p);
p = splPath.GetSplinePoint(indexSpline, SplinePointPosition::LastPoint);
@ -442,11 +444,16 @@ void VToolSplinePath::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
SetOverrideCursor(cursorArrowCloseHand, 1, 1);
oldPosition = event->scenePos();
const auto splPath = VAbstractTool::data.GeometricObject<VSplinePath>(id);
splIndex = splPath->Segment(oldPosition);
if (IsMovable(splIndex))
{
SetOverrideCursor(cursorArrowCloseHand, 1, 1);
event->accept();
}
}
}
VAbstractSpline::mousePressEvent(event);
}
@ -457,6 +464,7 @@ void VToolSplinePath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
oldPosition = event->scenePos();
//Disable cursor-arrow-closehand
RestoreOverrideCursor(cursorArrowCloseHand);
}
@ -467,19 +475,16 @@ void VToolSplinePath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
//---------------------------------------------------------------------------------------------------------------------
void VToolSplinePath::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
// Don't need check if left mouse button was pressed. According to the Qt documentation "If you do receive this
// Don't need to check if left mouse button was pressed. According to the Qt documentation "If you do receive this
// event, you can be certain that this item also received a mouse press event, and that this item is the current
// mouse grabber.".
if (IsMovable(splIndex))
{
VSplinePath oldSplPath = *VAbstractTool::data.GeometricObject<VSplinePath>(id);
VSplinePath newSplPath = oldSplPath;
int indexSpline = oldSplPath.Segment(oldPosition);
if (indexSpline == -1)
{
return;
}
VSpline spline = newSplPath.GetSpline(indexSpline);
VSpline spline = newSplPath.GetSpline(splIndex);
const qreal t = spline.ParamT(oldPosition);
if (qFloor(t) == -1)
@ -520,7 +525,7 @@ void VToolSplinePath::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
const VSpline spl = VSpline(spline.GetP1(), p2, p3, spline.GetP4());
UpdateControlPoints(spl, newSplPath, indexSpline);
UpdateControlPoints(spl, newSplPath, splIndex);
MoveSplinePath *moveSplPath = new MoveSplinePath(doc, oldSplPath, newSplPath, id, this->scene());
connect(moveSplPath, &VUndoCommand::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree);
@ -546,15 +551,22 @@ void VToolSplinePath::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
}
changeFinished = true;
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VToolSplinePath::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
if (flags() & QGraphicsItem::ItemIsMovable)
{
oldPosition = event->scenePos();
const auto splPath = VAbstractTool::data.GeometricObject<VSplinePath>(id);
splIndex = splPath->Segment(oldPosition);
if (IsMovable(splIndex))
{
SetOverrideCursor(cursorArrowOpenHand, 1, 1);
}
}
VAbstractSpline::hoverEnterEvent(event);
}
@ -564,6 +576,7 @@ void VToolSplinePath::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
if (flags() & QGraphicsItem::ItemIsMovable)
{
oldPosition = event->scenePos();
//Disable cursor-arrow-openhand
RestoreOverrideCursor(cursorArrowOpenHand);
}
@ -586,6 +599,23 @@ void VToolSplinePath::SetVisualization()
}
}
//---------------------------------------------------------------------------------------------------------------------
bool VToolSplinePath::IsMovable(int index) const
{
const auto splPath = VAbstractTool::data.GeometricObject<VSplinePath>(id);
//index == -1 - can delete, but decided to left
if (index == -1 || index < 1 || index > splPath->Count())
{
return false;
}
const VSplinePoint p1 = splPath->GetSplinePoint(index, SplinePointPosition::FirstPoint);
const VSplinePoint p2 = splPath->GetSplinePoint(index, SplinePointPosition::LastPoint);
return p1.IsMovable() && p2.IsMovable();
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief RefreshGeometry refresh item on scene.

View File

@ -101,7 +101,9 @@ protected:
virtual void SetVisualization() Q_DECL_OVERRIDE;
private:
QPointF oldPosition;
int splIndex;
bool IsMovable(int index) const;
void RefreshGeometry();
static void AddPathPoint(VAbstractPattern *doc, QDomElement &domElement, const VSplinePoint &splPoint);
void UpdateControlPoints(const VSpline &spl, VSplinePath &splPath, const qint32 &indexSpline) const;