From 254d9b7b7ad96641325fe801c6f0fd7858274d12 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 12 Feb 2015 12:55:09 +0200 Subject: [PATCH 1/8] Now spline can move by mouse. --HG-- branch : feature --- src/app/geometry/vspline.cpp | 131 ++++++++++++++++++++++++ src/app/geometry/vspline.h | 5 + src/app/tools/drawTools/vtoolspline.cpp | 70 ++++++++++++- src/app/tools/drawTools/vtoolspline.h | 3 + 4 files changed, 208 insertions(+), 1 deletion(-) 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/tools/drawTools/vtoolspline.cpp b/src/app/tools/drawTools/vtoolspline.cpp index ce50c27a0..99415a3ae 100644 --- a/src/app/tools/drawTools/vtoolspline.cpp +++ b/src/app/tools/drawTools/vtoolspline.cpp @@ -31,6 +31,7 @@ #include "../../dialogs/tools/dialogspline.h" #include "../../undocommands/movespline.h" #include "../../visualization/vistoolspline.h" +#include const QString VToolSpline::ToolType = QStringLiteral("simple"); @@ -45,7 +46,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 +54,8 @@ 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->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); this->setAcceptHoverEvents(true); this->setPath(ToolPath()); @@ -355,6 +358,71 @@ void VToolSpline::SaveOptions(QDomElement &tag, QSharedPointer &obj) doc->SetAttribute(tag, AttrColor, lineColor); } +//--------------------------------------------------------------------------------------------------------------------- +void VToolSpline::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + { + oldPosition = event->scenePos(); + event->accept(); + } + VAbstractSpline::mousePressEvent(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); + +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief RefreshGeometry refresh item on scene. diff --git a/src/app/tools/drawTools/vtoolspline.h b/src/app/tools/drawTools/vtoolspline.h index b10345fd6..ba17cc7cc 100644 --- a/src/app/tools/drawTools/vtoolspline.h +++ b/src/app/tools/drawTools/vtoolspline.h @@ -63,9 +63,12 @@ protected: virtual void RemoveReferens(); virtual void SaveDialog(QDomElement &domElement); virtual void SaveOptions(QDomElement &tag, QSharedPointer &obj); + virtual void mousePressEvent(QGraphicsSceneMouseEvent * event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event); private: Q_DISABLE_COPY(VToolSpline) void RefreshGeometry (); + QPointF oldPosition; }; #endif // VTOOLSPLINE_H From d5eded4eda2f468fab4ad1c24478bdfa2c10c484 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 12 Feb 2015 13:43:38 +0200 Subject: [PATCH 2/8] Show "move cursor". --HG-- branch : feature --- src/app/mainwindow.cpp | 4 +- src/app/tools/drawTools/vtoolspline.cpp | 54 +++++++++++++++++++++++-- src/app/tools/drawTools/vtoolspline.h | 4 ++ 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/app/mainwindow.cpp b/src/app/mainwindow.cpp index 852d1ee03..8162572cf 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); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/tools/drawTools/vtoolspline.cpp b/src/app/tools/drawTools/vtoolspline.cpp index 99415a3ae..f6f4c6b71 100644 --- a/src/app/tools/drawTools/vtoolspline.cpp +++ b/src/app/tools/drawTools/vtoolspline.cpp @@ -55,7 +55,6 @@ VToolSpline::VToolSpline(VPattern *doc, VContainer *data, quint32 id, const QStr this->setFlag(QGraphicsItem::ItemIsSelectable, true); this->setFlag(QGraphicsItem::ItemIsFocusable, true); this->setFlag(QGraphicsItem::ItemIsMovable, true); - //this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); this->setAcceptHoverEvents(true); this->setPath(ToolPath()); @@ -193,6 +192,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); @@ -283,6 +283,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. @@ -361,14 +367,32 @@ void VToolSpline::SaveOptions(QDomElement &tag, QSharedPointer &obj) //--------------------------------------------------------------------------------------------------------------------- void VToolSpline::mousePressEvent(QGraphicsSceneMouseEvent *event) { - if (event->button() == Qt::LeftButton) + if (flags() & QGraphicsItem::ItemIsMovable) { - oldPosition = event->scenePos(); - event->accept(); + if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick) + { + VApplication::setOverrideCursor(QStringLiteral("://cursor/cursor-arrow-closehand.png"), 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(QStringLiteral("://cursor/cursor-arrow-closehand.png")); + } + } + VAbstractSpline::mouseReleaseEvent(event); +} + //--------------------------------------------------------------------------------------------------------------------- void VToolSpline::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { @@ -420,7 +444,29 @@ void VToolSpline::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 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(QStringLiteral("://cursor/cursor-arrow-openhand.png"), 1, 1); + } + + VAbstractSpline::hoverEnterEvent(event); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + if (flags() & QGraphicsItem::ItemIsMovable) + { + //Disable cursor-arrow-openhand + VApplication::restoreOverrideCursor(QStringLiteral("://cursor/cursor-arrow-openhand.png")); + } + + VAbstractSpline::hoverLeaveEvent(event); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/tools/drawTools/vtoolspline.h b/src/app/tools/drawTools/vtoolspline.h index ba17cc7cc..fa1f95d51 100644 --- a/src/app/tools/drawTools/vtoolspline.h +++ b/src/app/tools/drawTools/vtoolspline.h @@ -58,13 +58,17 @@ 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 (); From d6069c920112426a65a45b070fc845a63eb4e32f Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 12 Feb 2015 13:55:35 +0200 Subject: [PATCH 3/8] Avoid declaring the same literal in multiple places. --HG-- branch : feature --- src/app/options.cpp | 3 +++ src/app/options.h | 3 +++ src/app/tools/drawTools/vtoolsinglepoint.cpp | 9 +++++---- src/app/tools/drawTools/vtoolspline.cpp | 9 +++++---- src/app/visualization/vcontrolpointspline.cpp | 8 ++++---- src/app/visualization/vgraphicssimpletextitem.cpp | 8 ++++---- 6 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/app/options.cpp b/src/app/options.cpp index 0f102247f..6d5b8fa53 100644 --- a/src/app/options.cpp +++ b/src/app/options.cpp @@ -37,6 +37,9 @@ const QString nameRegExp = QStringLiteral("^([^0-9-*/^+=\\s\\(\\)%:;!.,`'\"]){1, // furthermore blows up the binary sizes. const QString degreeSymbol = QStringLiteral("°"); +const QString cursorArrowOpenHand = QStringLiteral("://cursor/cursor-arrow-openhand.png"); +const QString cursorArrowCloseHand = QStringLiteral("://cursor/cursor-arrow-closehand.png"); + // Keep synchronize all names with initialization in VApllication class!!!!! //measurements //head and neck diff --git a/src/app/options.h b/src/app/options.h index 2a4e72fa0..6024d2d09 100644 --- a/src/app/options.h +++ b/src/app/options.h @@ -50,6 +50,9 @@ class QStringList; extern const QString nameRegExp; extern const QString degreeSymbol; +extern const QString cursorArrowOpenHand; +extern const QString cursorArrowCloseHand; + enum class SceneObject : char { Point, Line, Spline, Arc, SplinePath, Detail, Unknown }; enum class Tool : unsigned char { 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 f6f4c6b71..847077453 100644 --- a/src/app/tools/drawTools/vtoolspline.cpp +++ b/src/app/tools/drawTools/vtoolspline.cpp @@ -31,6 +31,7 @@ #include "../../dialogs/tools/dialogspline.h" #include "../../undocommands/movespline.h" #include "../../visualization/vistoolspline.h" +#include "../../options.h" #include const QString VToolSpline::ToolType = QStringLiteral("simple"); @@ -371,7 +372,7 @@ void VToolSpline::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); oldPosition = event->scenePos(); event->accept(); } @@ -387,7 +388,7 @@ void VToolSpline::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); } } VAbstractSpline::mouseReleaseEvent(event); @@ -451,7 +452,7 @@ void VToolSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { if (flags() & QGraphicsItem::ItemIsMovable) { - VApplication::setOverrideCursor(QStringLiteral("://cursor/cursor-arrow-openhand.png"), 1, 1); + VApplication::setOverrideCursor(cursorArrowOpenHand, 1, 1); } VAbstractSpline::hoverEnterEvent(event); @@ -463,7 +464,7 @@ void VToolSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) if (flags() & QGraphicsItem::ItemIsMovable) { //Disable cursor-arrow-openhand - VApplication::restoreOverrideCursor(QStringLiteral("://cursor/cursor-arrow-openhand.png")); + VApplication::restoreOverrideCursor(cursorArrowOpenHand); } VAbstractSpline::hoverLeaveEvent(event); 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); } From f16cccd89fecb179c2fe1651bbdad9e04a0e3eeb Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 12 Feb 2015 17:42:44 +0200 Subject: [PATCH 4/8] Curved path can move by mouse. --HG-- branch : feature --- src/app/geometry/vsplinepath.cpp | 24 ++++ src/app/geometry/vsplinepath.h | 2 + src/app/tools/drawTools/vtoolsplinepath.cpp | 119 +++++++++++++++++++- src/app/tools/drawTools/vtoolsplinepath.h | 7 ++ 4 files changed, 151 insertions(+), 1 deletion(-) 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/tools/drawTools/vtoolsplinepath.cpp b/src/app/tools/drawTools/vtoolsplinepath.cpp index 9c7b4157f..d40c258bf 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; } @@ -414,6 +416,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..52fb849db 100644 --- a/src/app/tools/drawTools/vtoolsplinepath.h +++ b/src/app/tools/drawTools/vtoolsplinepath.h @@ -79,7 +79,14 @@ protected: 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; From ee0f8d51be1213e5ed9d4474de5307203ac80c9f Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 12 Feb 2015 17:47:53 +0200 Subject: [PATCH 5/8] Auto save should not change "was modefied" sign (*). --HG-- branch : feature --- src/app/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/mainwindow.cpp b/src/app/mainwindow.cpp index 8162572cf..4684e8abd 100644 --- a/src/app/mainwindow.cpp +++ b/src/app/mainwindow.cpp @@ -1998,13 +1998,13 @@ bool MainWindow::SavePattern(const QString &fileName, QString &error) setCurrentFile(fileName); helpLabel->setText(tr("File saved")); qCDebug(vMainWindow)<<"File"< Date: Thu, 12 Feb 2015 18:02:23 +0200 Subject: [PATCH 6/8] Cut tools use attribute "color" instead "lineColor". --HG-- branch : feature --- src/libs/ifc/schema/pattern/v0.1.3.xsd | 1 + 1 file changed, 1 insertion(+) 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 @@ + From 99ebbc3ed9f150b1ccd2c9cc54ed105bf47ddb2f Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 12 Feb 2015 18:10:47 +0200 Subject: [PATCH 7/8] Simple curve ignore press event and allow move curve by mouse. --HG-- branch : feature --- src/app/tools/drawTools/vtoolsplinepath.cpp | 6 ++++++ src/app/tools/drawTools/vtoolsplinepath.h | 1 + src/app/visualization/vsimplecurve.cpp | 6 ++++++ src/app/visualization/vsimplecurve.h | 1 + 4 files changed, 14 insertions(+) diff --git a/src/app/tools/drawTools/vtoolsplinepath.cpp b/src/app/tools/drawTools/vtoolsplinepath.cpp index d40c258bf..6ca030ff5 100644 --- a/src/app/tools/drawTools/vtoolsplinepath.cpp +++ b/src/app/tools/drawTools/vtoolsplinepath.cpp @@ -204,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. diff --git a/src/app/tools/drawTools/vtoolsplinepath.h b/src/app/tools/drawTools/vtoolsplinepath.h index 52fb849db..1566149c0 100644 --- a/src/app/tools/drawTools/vtoolsplinepath.h +++ b/src/app/tools/drawTools/vtoolsplinepath.h @@ -73,6 +73,7 @@ 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(); 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 ); From 7db74d4f20143ccbaeb82be160ee1370cdf0c053 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Fri, 13 Feb 2015 11:26:02 +0200 Subject: [PATCH 8/8] We don't need anymore simple curves. First step just hide them. --HG-- branch : feature --- src/app/tools/drawTools/vtoolcut.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/app/tools/drawTools/vtoolcut.cpp b/src/app/tools/drawTools/vtoolcut.cpp index 7eefbc110..dabc5deb3 100644 --- a/src/app/tools/drawTools/vtoolcut.cpp +++ b/src/app/tools/drawTools/vtoolcut.cpp @@ -47,11 +47,14 @@ VToolCut::VToolCut(VPattern *doc, VContainer *data, const quint32 &id, const QSt firstCurve->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); } //---------------------------------------------------------------------------------------------------------------------