diff --git a/src/app/geometry/vspline.cpp b/src/app/geometry/vspline.cpp index 00e7ca219..8985f9c56 100644 --- a/src/app/geometry/vspline.cpp +++ b/src/app/geometry/vspline.cpp @@ -744,3 +744,134 @@ void VSpline::SetKcurve(qreal factor) d->kCurve = factor; } } + +//--------------------------------------------------------------------------------------------------------------------- +int VSpline::Sign(long double ld) const +{ + if(qAbs(ld)<0.00000000001) + { + return 0; + } + return (ld>0) ? 1 : -1; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Cubic Cubic equation solution. Real coefficients case. + * + * This method use method Vieta-Cardano for eval cubic equations. + * Cubic equation write in form x3+a*x2+b*x+c=0. + * + * Output: + * 3 real roots -> then x is filled with them; + * 1 real + 2 complex -> x[0] is real, x[1] is real part of complex roots, x[2] - non-negative imaginary part. + * + * @param x solution array (size 3). + * @param a coefficient + * @param b coefficient + * @param c coefficient + * @return 3 - 3 real roots; + * 1 - 1 real root + 2 complex; + * 2 - 1 real root + complex roots imaginary part is zero (i.e. 2 real roots). + */ +qint32 VSpline::Cubic(QVector &x, qreal a, qreal b, qreal c) const +{ + //To find cubic equation roots in the case of real coefficients, calculated at the beginning + const qreal q = (pow(a, 2) - 3*b)/9.; + const qreal r = (2*pow(a, 3) - 9*a*b + 27.*c)/54.; + if (pow(r, 2) < pow(q, 3)) + { // equation has three real roots, use formula Vieta + const qreal t = acos(r/sqrt(pow(q, 3)))/3.; + x.insert(0, -2.*sqrt(q)*cos(t)-a/3); + x.insert(1, -2.*sqrt(q)*cos(t + (2*M_2PI/3.)) - a/3.); + x.insert(2, -2.*sqrt(q)*cos(t - (2*M_2PI/3.)) - a/3.); + return(3); + } + else + { // 1 real root + 2 complex + //Formula Cardano + const qreal aa = -Sign(r)*pow(fabs(r)+sqrt(pow(r, 2)-pow(q, 3)), 1./3.); + const qreal bb = Sign(aa) == 0 ? 0 : q/aa; + + x.insert(0, aa+bb-a/3.); // Real root + x.insert(1, (-0.5)*(aa+bb)-a/3.); //Complex root + x.insert(2, (sqrt(3.)*0.5)*fabs(aa-bb)); // Complex root + if (qFuzzyCompare(x.at(2) + 1, 0. + 1)) + { + return(2); + } + return(1); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector VSpline::CalcT (qreal curveCoord1, qreal curveCoord2, qreal curveCoord3, + qreal curveCoord4, qreal pointCoord) const +{ + const qreal a = -curveCoord1 + 3*curveCoord2 - 3*curveCoord3 + curveCoord4; + const qreal b = 3*curveCoord1 - 6*curveCoord2 + 3*curveCoord3; + const qreal c = -3*curveCoord1 + 3*curveCoord2; + const qreal d = -pointCoord + curveCoord1; + + QVector t = QVector(3, -1); + Cubic(t, b/a, c/a, d/a); + + QVector retT; + for (int i=0; i < t.size(); ++i) + { + if ( t.at(i) >= 0 && t.at(i) <= 1 ) + { + retT.append(t.at(i)); + } + } + + return retT; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VSpline::ParamT calculate t coeffient that reprezent point on curve. + * + * Each point that belongs to Cubic Bézier curve can be shown by coefficient in interval [0; 1]. + * + * @param pBt point on curve + * @return t coeffient that reprezent this point on curve. Return -1 if point doesn't belongs to curve. + */ +qreal VSpline::ParamT (const QPointF &pBt) const +{ + QVector ts; + // Calculate t coefficient for each axis + ts += CalcT (GetP1().toQPointF().x(), d->p2.x(), d->p3.x(), GetP4().toQPointF().x(), pBt.x()); + ts += CalcT (GetP1().toQPointF().y(), d->p2.y(), d->p3.y(), GetP4().toQPointF().y(), pBt.y()); + + if(ts.isEmpty()) + { + return -1; // We don't have candidates + } + + qreal tx = -1; + qreal eps = 3; // Error calculation + + // In morst case we will have 6 result in interval [0; 1]. + // Here we try find closest to our point. + for (int i=0; i< ts.size(); ++i) + { + const qreal t = ts.at(i); + const QPointF p0 = GetP1().toQPointF(); + const QPointF p1 = d->p2; + const QPointF p2 = d->p3; + const QPointF p3 = GetP4().toQPointF(); + //The explicit form of the Cubic Bézier curve + const qreal pointX = pow(1-t, 3)*p0.x() + 3*pow(1-t, 2)*t*p1.x() + 3*(1-t)*pow(t, 2)*p2.x() + pow(t, 3)*p3.x(); + const qreal pointY = pow(1-t, 3)*p0.y() + 3*pow(1-t, 2)*t*p1.y() + 3*(1-t)*pow(t, 2)*p2.y() + pow(t, 3)*p3.y(); + + const QLineF line(pBt, QPointF(pointX, pointY)); + if (line.length() <= eps) + { + tx = t; + eps = line.length(); //Next point should be even closest + } + } + + return tx; +} diff --git a/src/app/geometry/vspline.h b/src/app/geometry/vspline.h index d363f8b0f..c01be8c88 100644 --- a/src/app/geometry/vspline.h +++ b/src/app/geometry/vspline.h @@ -71,6 +71,7 @@ public: // cppcheck-suppress unusedFunction static QVector SplinePoints(const QPointF &p1, const QPointF &p4, qreal angle1, qreal angle2, qreal kAsm1, qreal kAsm2, qreal kCurve); + qreal ParamT(const QPointF &pBt) const; protected: static QVector GetPoints (const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4 ); private: @@ -80,6 +81,10 @@ private: qint16 level, QVector &px, QVector &py); static qreal CalcSqDistance ( qreal x1, qreal y1, qreal x2, qreal y2); void CreateName(); + QVector CalcT(qreal curveCoord1, qreal curveCoord2, qreal curveCoord3, qreal curveCoord4, + qreal pointCoord) const; + qint32 Cubic(QVector &x, qreal a, qreal b, qreal c) const; + int Sign(long double ld) const; }; #endif // VSPLINE_H diff --git a/src/app/geometry/vsplinepath.cpp b/src/app/geometry/vsplinepath.cpp index 068c910cb..635653333 100644 --- a/src/app/geometry/vsplinepath.cpp +++ b/src/app/geometry/vsplinepath.cpp @@ -236,6 +236,30 @@ void VSplinePath::setMaxCountPoints(const qint32 &value) d->maxCountPoints = value; } +//--------------------------------------------------------------------------------------------------------------------- +int VSplinePath::Segment(const QPointF &p) const +{ + int index = -1; + for (qint32 i = 1; i <= Count(); ++i) + { + VSpline spl = VSpline(d->path.at(i-1).P(), d->path.at(i).P(), d->path.at(i-1).Angle2(), d->path.at(i).Angle1(), + d->path.at(i-1).KAsm2(), d->path.at(i).KAsm1(), d->kCurve); + + const qreal t = spl.ParamT(p); + + if (qFloor(t) == -1) + { + continue; + } + else + { + index = i; + break; + } + } + return index; +} + //--------------------------------------------------------------------------------------------------------------------- qint32 VSplinePath::CountPoint() const { diff --git a/src/app/geometry/vsplinepath.h b/src/app/geometry/vsplinepath.h index b3de10941..eec37a532 100644 --- a/src/app/geometry/vsplinepath.h +++ b/src/app/geometry/vsplinepath.h @@ -185,6 +185,8 @@ public: * @param value max count. */ void setMaxCountPoints(const qint32 &value); + + int Segment(const QPointF &p) const; private: QSharedDataPointer d; }; diff --git a/src/app/mainwindow.cpp b/src/app/mainwindow.cpp index 852d1ee03..4684e8abd 100644 --- a/src/app/mainwindow.cpp +++ b/src/app/mainwindow.cpp @@ -300,6 +300,7 @@ void MainWindow::SetToolButton(bool checked, Tool t, const QString &cursor, cons if (checked) { CancelTool(); + emit EnableItemMove(true); tool = t; QPixmap pixmap(cursor); QCursor cur(pixmap, 2, 3); @@ -340,6 +341,7 @@ void MainWindow::SetToolButtonWithApply(bool checked, Tool t, const QString &cur if (checked) { CancelTool(); + emit EnableItemMove(false); tool = t; QPixmap pixmap(cursor); QCursor cur(pixmap, 2, 3); @@ -1050,7 +1052,6 @@ void MainWindow::CancelTool() ui->actionArrowTool->setChecked(false); helpLabel->setText(""); ui->actionStopTool->setEnabled(true); - emit EnableItemMove(false); return; case Tool::SinglePoint: Q_UNREACHABLE(); @@ -1130,7 +1131,6 @@ void MainWindow::CancelTool() } currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); - emit EnableItemMove(true); } //--------------------------------------------------------------------------------------------------------------------- @@ -1998,13 +1998,13 @@ bool MainWindow::SavePattern(const QString &fileName, QString &error) setCurrentFile(fileName); helpLabel->setText(tr("File saved")); qCDebug(vMainWindow)<<"File"<setParentItem(this); connect(firstCurve, &VSimpleCurve::Choosed, this, &VToolCut::CurveChoosed); connect(firstCurve, &VSimpleCurve::HoverPath, this, &VToolCut::HoverPath); + // TODO: Now we only hide simple curves, but in future need totally delete them all. + firstCurve->setVisible(false); secondCurve = new VSimpleCurve(curve2id, QColor(lineColor), SimpleCurvePoint::FirstPoint, &factor); secondCurve->setParentItem(this); connect(secondCurve, &VSimpleCurve::Choosed, this, &VToolCut::CurveChoosed); connect(secondCurve, &VSimpleCurve::HoverPath, this, &VToolCut::HoverPath); + secondCurve->setVisible(false); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/tools/drawTools/vtoolsinglepoint.cpp b/src/app/tools/drawTools/vtoolsinglepoint.cpp index 0948cecc1..dde2a162c 100644 --- a/src/app/tools/drawTools/vtoolsinglepoint.cpp +++ b/src/app/tools/drawTools/vtoolsinglepoint.cpp @@ -33,6 +33,7 @@ #include "../../undocommands/addpatternpiece.h" #include "../../undocommands/deletepatternpiece.h" #include "../../geometry/vpointf.h" +#include "../../options.h" #include @@ -207,7 +208,7 @@ void VToolSinglePoint::hoverEnterEvent(QGraphicsSceneHoverEvent *event) if (flags() & QGraphicsItem::ItemIsMovable) { - VApplication::setOverrideCursor(QStringLiteral("://cursor/cursor-arrow-openhand.png"), 1, 1); + VApplication::setOverrideCursor(cursorArrowOpenHand, 1, 1); } } @@ -219,7 +220,7 @@ void VToolSinglePoint::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) if (flags() & QGraphicsItem::ItemIsMovable) { //Disable cursor-arrow-openhand - VApplication::restoreOverrideCursor(QStringLiteral("://cursor/cursor-arrow-openhand.png")); + VApplication::restoreOverrideCursor(cursorArrowOpenHand); } } @@ -230,7 +231,7 @@ void VToolSinglePoint::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) { - VApplication::setOverrideCursor(QStringLiteral("://cursor/cursor-arrow-closehand.png"), 1, 1); + VApplication::setOverrideCursor(cursorArrowCloseHand, 1, 1); } } VToolPoint::mousePressEvent(event); @@ -244,7 +245,7 @@ void VToolSinglePoint::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) { //Disable cursor-arrow-closehand - VApplication::restoreOverrideCursor(QStringLiteral("://cursor/cursor-arrow-closehand.png")); + VApplication::restoreOverrideCursor(cursorArrowCloseHand); } } VToolPoint::mouseReleaseEvent(event); diff --git a/src/app/tools/drawTools/vtoolspline.cpp b/src/app/tools/drawTools/vtoolspline.cpp index ce50c27a0..847077453 100644 --- a/src/app/tools/drawTools/vtoolspline.cpp +++ b/src/app/tools/drawTools/vtoolspline.cpp @@ -31,6 +31,8 @@ #include "../../dialogs/tools/dialogspline.h" #include "../../undocommands/movespline.h" #include "../../visualization/vistoolspline.h" +#include "../../options.h" +#include const QString VToolSpline::ToolType = QStringLiteral("simple"); @@ -45,7 +47,7 @@ const QString VToolSpline::ToolType = QStringLiteral("simple"); */ VToolSpline::VToolSpline(VPattern *doc, VContainer *data, quint32 id, const QString color, const Source &typeCreation, QGraphicsItem *parent) - :VAbstractSpline(doc, data, id, parent) + :VAbstractSpline(doc, data, id, parent), oldPosition() { sceneType = SceneObject::Spline; lineColor = color; @@ -53,6 +55,7 @@ VToolSpline::VToolSpline(VPattern *doc, VContainer *data, quint32 id, const QStr this->setPen(QPen(Qt::black, qApp->toPixel(qApp->widthHairLine())/factor)); this->setFlag(QGraphicsItem::ItemIsSelectable, true); this->setFlag(QGraphicsItem::ItemIsFocusable, true); + this->setFlag(QGraphicsItem::ItemIsMovable, true); this->setAcceptHoverEvents(true); this->setPath(ToolPath()); @@ -190,6 +193,7 @@ VToolSpline* VToolSpline::Create(const quint32 _id, const quint32 &p1, const qui connect(spl, &VToolSpline::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); connect(scene, &VMainGraphicsScene::NewFactor, spl, &VToolSpline::SetFactor); connect(scene, &VMainGraphicsScene::DisableItem, spl, &VToolSpline::Disable); + connect(scene, &VMainGraphicsScene::EnableToolMove, spl, &VToolSpline::EnableToolMove); doc->AddTool(id, spl); doc->IncrementReferens(p1); doc->IncrementReferens(p4); @@ -280,6 +284,12 @@ void VToolSpline::ControlPointChangePosition(const qint32 &indexSpline, const Sp qApp->getUndoStack()->push(moveSpl); } +//--------------------------------------------------------------------------------------------------------------------- +void VToolSpline::EnableToolMove(bool move) +{ + this->setFlag(QGraphicsItem::ItemIsMovable, move); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief contextMenuEvent handle context menu events. @@ -355,6 +365,111 @@ void VToolSpline::SaveOptions(QDomElement &tag, QSharedPointer &obj) doc->SetAttribute(tag, AttrColor, lineColor); } +//--------------------------------------------------------------------------------------------------------------------- +void VToolSpline::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (flags() & QGraphicsItem::ItemIsMovable) + { + if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) + { + VApplication::setOverrideCursor(cursorArrowCloseHand, 1, 1); + oldPosition = event->scenePos(); + event->accept(); + } + } + VAbstractSpline::mousePressEvent(event); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if (flags() & QGraphicsItem::ItemIsMovable) + { + if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) + { + //Disable cursor-arrow-closehand + VApplication::restoreOverrideCursor(cursorArrowCloseHand); + } + } + VAbstractSpline::mouseReleaseEvent(event); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSpline::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + // 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 + // mouse grabber.". + + // Magic Bezier Drag Equations follow! + // "weight" describes how the influence of the drag should be distributed + // among the handles; 0 = front handle only, 1 = back handle only. + + const QSharedPointer spline = VAbstractTool::data.GeometricObject(id); + const qreal t = spline->ParamT(oldPosition); + + if (qFloor(t) == -1) + { + return; + } + + double weight; + if (t <= 1.0 / 6.0) + { + weight = 0; + } + else if (t <= 0.5) + { + weight = (pow((6 * t - 1) / 2.0, 3)) / 2; + } + else if (t <= 5.0 / 6.0) + { + weight = (1 - pow((6 * (1-t) - 1) / 2.0, 3)) / 2 + 0.5; + } + else + { + weight = 1; + } + + const QPointF delta = event->scenePos() - oldPosition; + const QPointF offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; + const QPointF offset1 = (weight/(3*t*t*(1-t))) * delta; + + const QPointF p2 = spline->GetP2() + offset0; + const QPointF p3 = spline->GetP3() + offset1; + + oldPosition = event->scenePos(); // Now mouse here + + VSpline spl = VSpline(spline->GetP1(), p2, p3, spline->GetP4(), spline->GetKcurve()); + + MoveSpline *moveSpl = new MoveSpline(doc, spline.data(), spl, id, this->scene()); + connect(moveSpl, &MoveSpline::NeedLiteParsing, doc, &VPattern::LiteParseTree); + qApp->getUndoStack()->push(moveSpl); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + if (flags() & QGraphicsItem::ItemIsMovable) + { + VApplication::setOverrideCursor(cursorArrowOpenHand, 1, 1); + } + + VAbstractSpline::hoverEnterEvent(event); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + if (flags() & QGraphicsItem::ItemIsMovable) + { + //Disable cursor-arrow-openhand + VApplication::restoreOverrideCursor(cursorArrowOpenHand); + } + + VAbstractSpline::hoverLeaveEvent(event); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief RefreshGeometry refresh item on scene. diff --git a/src/app/tools/drawTools/vtoolspline.h b/src/app/tools/drawTools/vtoolspline.h index b10345fd6..fa1f95d51 100644 --- a/src/app/tools/drawTools/vtoolspline.h +++ b/src/app/tools/drawTools/vtoolspline.h @@ -58,14 +58,21 @@ public: public slots: void ControlPointChangePosition (const qint32 &indexSpline, const SplinePointPosition &position, const QPointF &pos); + virtual void EnableToolMove(bool move); protected: virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ); virtual void RemoveReferens(); virtual void SaveDialog(QDomElement &domElement); virtual void SaveOptions(QDomElement &tag, QSharedPointer &obj); + virtual void mousePressEvent(QGraphicsSceneMouseEvent * event); + virtual void mouseReleaseEvent ( QGraphicsSceneMouseEvent * event ); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event); + virtual void hoverEnterEvent ( QGraphicsSceneHoverEvent * event ); + virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ); private: Q_DISABLE_COPY(VToolSpline) void RefreshGeometry (); + QPointF oldPosition; }; #endif // VTOOLSPLINE_H diff --git a/src/app/tools/drawTools/vtoolsplinepath.cpp b/src/app/tools/drawTools/vtoolsplinepath.cpp index 9c7b4157f..6ca030ff5 100644 --- a/src/app/tools/drawTools/vtoolsplinepath.cpp +++ b/src/app/tools/drawTools/vtoolsplinepath.cpp @@ -44,7 +44,7 @@ const QString VToolSplinePath::ToolType = QStringLiteral("path"); */ VToolSplinePath::VToolSplinePath(VPattern *doc, VContainer *data, quint32 id, const QString &color, const Source &typeCreation, QGraphicsItem *parent) - :VAbstractSpline(doc, data, id, parent) + :VAbstractSpline(doc, data, id, parent), oldPosition() { sceneType = SceneObject::SplinePath; @@ -52,6 +52,7 @@ VToolSplinePath::VToolSplinePath(VPattern *doc, VContainer *data, quint32 id, co this->setPen(QPen(Qt::black, qApp->toPixel(qApp->widthHairLine())/factor)); this->setFlag(QGraphicsItem::ItemIsSelectable, true); this->setFlag(QGraphicsItem::ItemIsFocusable, true); + this->setFlag(QGraphicsItem::ItemIsMovable, true); this->setAcceptHoverEvents(true); const QSharedPointer splPath = data->GeometricObject(id); @@ -167,6 +168,7 @@ VToolSplinePath* VToolSplinePath::Create(const quint32 _id, VSplinePath *path, c connect(spl, &VToolSplinePath::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); connect(scene, &VMainGraphicsScene::NewFactor, spl, &VToolSplinePath::SetFactor); connect(scene, &VMainGraphicsScene::DisableItem, spl, &VToolSplinePath::Disable); + connect(scene, &VMainGraphicsScene::EnableToolMove, spl, &VToolSplinePath::EnableToolMove); doc->AddTool(id, spl); return spl; } @@ -202,6 +204,12 @@ void VToolSplinePath::ControlPointChangePosition(const qint32 &indexSpline, cons qApp->getUndoStack()->push(moveSplPath); } +//--------------------------------------------------------------------------------------------------------------------- +void VToolSplinePath::EnableToolMove(bool move) +{ + this->setFlag(QGraphicsItem::ItemIsMovable, move); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief UpdateControlPoints update position points control points in file. @@ -414,6 +422,121 @@ void VToolSplinePath::SaveOptions(QDomElement &tag, QSharedPointer &ob } } +//--------------------------------------------------------------------------------------------------------------------- +void VToolSplinePath::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (flags() & QGraphicsItem::ItemIsMovable) + { + if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) + { + VApplication::setOverrideCursor(cursorArrowCloseHand, 1, 1); + oldPosition = event->scenePos(); + event->accept(); + } + } + VAbstractSpline::mousePressEvent(event); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSplinePath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if (flags() & QGraphicsItem::ItemIsMovable) + { + if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) + { + //Disable cursor-arrow-closehand + VApplication::restoreOverrideCursor(cursorArrowCloseHand); + } + } + VAbstractSpline::mouseReleaseEvent(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 + // event, you can be certain that this item also received a mouse press event, and that this item is the current + // mouse grabber.". + + VSplinePath oldSplPath = *VAbstractTool::data.GeometricObject(id); + VSplinePath newSplPath = oldSplPath; + int indexSpline = oldSplPath.Segment(oldPosition); + if (indexSpline == -1) + { + return; + } + + VSpline spline = newSplPath.GetSpline(indexSpline); + const qreal t = spline.ParamT(oldPosition); + + if (qFloor(t) == -1) + { + return; + } + + // Magic Bezier Drag Equations follow! + // "weight" describes how the influence of the drag should be distributed + // among the handles; 0 = front handle only, 1 = back handle only. + + double weight; + if (t <= 1.0 / 6.0) + { + weight = 0; + } + else if (t <= 0.5) + { + weight = (pow((6 * t - 1) / 2.0, 3)) / 2; + } + else if (t <= 5.0 / 6.0) + { + weight = (1 - pow((6 * (1-t) - 1) / 2.0, 3)) / 2 + 0.5; + } + else + { + weight = 1; + } + + const QPointF delta = event->scenePos() - oldPosition; + const QPointF offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; + const QPointF offset1 = (weight/(3*t*t*(1-t))) * delta; + + const QPointF p2 = spline.GetP2() + offset0; + const QPointF p3 = spline.GetP3() + offset1; + + oldPosition = event->scenePos(); // Now mouse here + + const VSpline spl = VSpline(spline.GetP1(), p2, p3, spline.GetP4(), spline.GetKcurve()); + + UpdateControlPoints(spl, newSplPath, indexSpline); + + MoveSplinePath *moveSplPath = new MoveSplinePath(doc, oldSplPath, newSplPath, id, this->scene()); + connect(moveSplPath, &VUndoCommand::NeedLiteParsing, doc, &VPattern::LiteParseTree); + qApp->getUndoStack()->push(moveSplPath); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSplinePath::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + if (flags() & QGraphicsItem::ItemIsMovable) + { + VApplication::setOverrideCursor(cursorArrowOpenHand, 1, 1); + } + + VAbstractSpline::hoverEnterEvent(event); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSplinePath::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + if (flags() & QGraphicsItem::ItemIsMovable) + { + //Disable cursor-arrow-openhand + VApplication::restoreOverrideCursor(cursorArrowOpenHand); + } + + VAbstractSpline::hoverLeaveEvent(event); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief RefreshGeometry refresh item on scene. diff --git a/src/app/tools/drawTools/vtoolsplinepath.h b/src/app/tools/drawTools/vtoolsplinepath.h index 9b3dfd3c9..1566149c0 100644 --- a/src/app/tools/drawTools/vtoolsplinepath.h +++ b/src/app/tools/drawTools/vtoolsplinepath.h @@ -73,13 +73,21 @@ public slots: void ControlPointChangePosition(const qint32 &indexSpline, const SplinePointPosition &position, const QPointF &pos); + virtual void EnableToolMove(bool move); protected: virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ); virtual void RefreshDataInFile(); virtual void RemoveReferens(); virtual void SaveDialog(QDomElement &domElement); virtual void SaveOptions(QDomElement &tag, QSharedPointer &obj); + virtual void mousePressEvent(QGraphicsSceneMouseEvent * event); + virtual void mouseReleaseEvent ( QGraphicsSceneMouseEvent * event ); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event); + virtual void hoverEnterEvent ( QGraphicsSceneHoverEvent * event ); + virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ); private: + QPointF oldPosition; + void RefreshGeometry(); static void AddPathPoint(VPattern *doc, QDomElement &domElement, const VSplinePoint &splPoint); void UpdateControlPoints(const VSpline &spl, VSplinePath &splPath, const qint32 &indexSpline) const; diff --git a/src/app/visualization/vcontrolpointspline.cpp b/src/app/visualization/vcontrolpointspline.cpp index 31c22d7aa..5fb35504a 100644 --- a/src/app/visualization/vcontrolpointspline.cpp +++ b/src/app/visualization/vcontrolpointspline.cpp @@ -90,7 +90,7 @@ void VControlPointSpline::paint(QPainter *painter, const QStyleOptionGraphicsIte void VControlPointSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { this->setPen(QPen(Qt::black, qApp->toPixel(qApp->widthMainLine()))); - VApplication::setOverrideCursor(QStringLiteral("://cursor/cursor-arrow-openhand.png"), 1, 1); + VApplication::setOverrideCursor(cursorArrowOpenHand, 1, 1); QGraphicsEllipseItem::hoverEnterEvent(event); } @@ -99,7 +99,7 @@ void VControlPointSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { this->setPen(QPen(Qt::black, qApp->toPixel(qApp->widthHairLine()))); //Disable cursor-arrow-openhand - VApplication::restoreOverrideCursor(QStringLiteral("://cursor/cursor-arrow-openhand.png")); + VApplication::restoreOverrideCursor(cursorArrowOpenHand); QGraphicsEllipseItem::hoverLeaveEvent(event); } @@ -126,7 +126,7 @@ void VControlPointSpline::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) { - VApplication::setOverrideCursor(QStringLiteral("://cursor/cursor-arrow-closehand.png"), 1, 1); + VApplication::setOverrideCursor(cursorArrowCloseHand, 1, 1); } QGraphicsEllipseItem::mousePressEvent(event); } @@ -137,7 +137,7 @@ void VControlPointSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) { //Disable cursor-arrow-closehand - VApplication::restoreOverrideCursor(QStringLiteral("://cursor/cursor-arrow-closehand.png")); + VApplication::restoreOverrideCursor(cursorArrowCloseHand); } QGraphicsEllipseItem::mouseReleaseEvent(event); } diff --git a/src/app/visualization/vgraphicssimpletextitem.cpp b/src/app/visualization/vgraphicssimpletextitem.cpp index 85f07a71d..c937519fd 100644 --- a/src/app/visualization/vgraphicssimpletextitem.cpp +++ b/src/app/visualization/vgraphicssimpletextitem.cpp @@ -124,7 +124,7 @@ void VGraphicsSimpleTextItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { this->setBrush(Qt::green); - VApplication::setOverrideCursor(QStringLiteral("://cursor/cursor-arrow-openhand.png"), 1, 1); + VApplication::setOverrideCursor(cursorArrowOpenHand, 1, 1); QGraphicsSimpleTextItem::hoverEnterEvent(event); } @@ -139,7 +139,7 @@ void VGraphicsSimpleTextItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) this->setBrush(Qt::black); //Disable cursor-arrow-openhand - VApplication::restoreOverrideCursor(QStringLiteral("://cursor/cursor-arrow-openhand.png")); + VApplication::restoreOverrideCursor(cursorArrowOpenHand); QGraphicsSimpleTextItem::hoverLeaveEvent(event); } @@ -158,7 +158,7 @@ void VGraphicsSimpleTextItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) { - VApplication::setOverrideCursor(QStringLiteral("://cursor/cursor-arrow-closehand.png"), 1, 1); + VApplication::setOverrideCursor(cursorArrowCloseHand, 1, 1); } QGraphicsSimpleTextItem::mousePressEvent(event); } @@ -169,7 +169,7 @@ void VGraphicsSimpleTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) { //Disable cursor-arrow-closehand - VApplication::restoreOverrideCursor(QStringLiteral("://cursor/cursor-arrow-closehand.png")); + VApplication::restoreOverrideCursor(cursorArrowCloseHand); } QGraphicsSimpleTextItem::mouseReleaseEvent(event); } diff --git a/src/app/visualization/vsimplecurve.cpp b/src/app/visualization/vsimplecurve.cpp index 33031f3eb..095f6c2db 100644 --- a/src/app/visualization/vsimplecurve.cpp +++ b/src/app/visualization/vsimplecurve.cpp @@ -144,6 +144,12 @@ void VSimpleCurve::SetCurrentColor(const QColor &value) setPen(QPen(CorrectColor(currentColor), pen().widthF())); } +//--------------------------------------------------------------------------------------------------------------------- +void VSimpleCurve::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + event->ignore(); +} + //--------------------------------------------------------------------------------------------------------------------- QColor VSimpleCurve::CorrectColor(const QColor &color) const { diff --git a/src/app/visualization/vsimplecurve.h b/src/app/visualization/vsimplecurve.h index a013727c2..96cefdca2 100644 --- a/src/app/visualization/vsimplecurve.h +++ b/src/app/visualization/vsimplecurve.h @@ -60,6 +60,7 @@ signals: void Choosed(quint32 id); void HoverPath(quint32 id, SimpleCurvePoint curvePosition, PathDirection direction); protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent * event); virtual void mouseReleaseEvent ( QGraphicsSceneMouseEvent * event ); virtual void hoverMoveEvent ( QGraphicsSceneHoverEvent * event ); virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ); diff --git a/src/libs/ifc/schema/pattern/v0.1.3.xsd b/src/libs/ifc/schema/pattern/v0.1.3.xsd index 18cf62b78..6d72527c3 100644 --- a/src/libs/ifc/schema/pattern/v0.1.3.xsd +++ b/src/libs/ifc/schema/pattern/v0.1.3.xsd @@ -122,6 +122,7 @@ +