Improve creation by mouse for tool Spline.

This commit is contained in:
Roman Telezhynskyi 2022-02-07 11:42:53 +02:00
parent 038fbb3540
commit 3e59505da2
9 changed files with 339 additions and 317 deletions

View File

@ -34,6 +34,7 @@
- Allow size to have values from 1 to 100 if not a circumference.
- Fix tool True darts notes.
- New measurement type separator.
- Improve creation by mouse for tool Spline.
# Valentina 0.7.49 July 1, 2021
- Fix crash.

View File

@ -202,7 +202,7 @@ void DialogSpline::ChosenObject(quint32 id, const SceneObject &type)
{
++number;
path->setObject4Id(id);
path->SetObject4Id(id);
path->RefreshGeometry();
prepare = true;
}
@ -228,7 +228,7 @@ void DialogSpline::SaveData()
SCASSERT(path != nullptr)
path->setObject1Id(GetP1()->id());
path->setObject4Id(GetP4()->id());
path->SetObject4Id(GetP4()->id());
path->SetAngle1(spl.GetStartAngle());
path->SetAngle2(spl.GetEndAngle());
path->SetKAsm1(spl.GetKasm1());
@ -636,7 +636,7 @@ void DialogSpline::SetSpline(const VSpline &spline)
SCASSERT(path != nullptr)
path->setObject1Id(spl.GetP1().id());
path->setObject4Id(spl.GetP4().id());
path->SetObject4Id(spl.GetP4().id());
path->SetAngle1(spl.GetStartAngle());
path->SetAngle2(spl.GetEndAngle());
path->SetKAsm1(spl.GetKasm1());

View File

@ -179,7 +179,7 @@ void DialogSplinePath::SetPath(const VSplinePath &value)
auto visPath = qobject_cast<VisToolSplinePath *>(vis);
SCASSERT(visPath != nullptr)
visPath->setPath(path);
visPath->SetPath(path);
ui->listWidget->blockSignals(false);
flagError = IsPathValid();
@ -210,7 +210,7 @@ void DialogSplinePath::ChosenObject(quint32 id, const SceneObject &type)
auto visPath = qobject_cast<VisToolSplinePath *>(vis);
SCASSERT(visPath != nullptr)
visPath->setPath(path);
visPath->SetPath(path);
if (path.CountPoints() == 1)
{
@ -241,7 +241,7 @@ void DialogSplinePath::SaveData()
auto visPath = qobject_cast<VisToolSplinePath *>(vis);
SCASSERT(visPath != nullptr)
visPath->setPath(path);
visPath->SetPath(path);
visPath->SetMode(Mode::Show);
visPath->RefreshGeometry();
}

View File

@ -544,7 +544,7 @@ void VToolSpline::SetVisualization()
const QSharedPointer<VSpline> spl = VAbstractTool::data.GeometricObject<VSpline>(m_id);
visual->setObject1Id(spl->GetP1().id());
visual->setObject4Id(spl->GetP4().id());
visual->SetObject4Id(spl->GetP4().id());
visual->SetAngle1(spl->GetStartAngle());
visual->SetAngle2(spl->GetEndAngle());
visual->SetKAsm1(spl->GetKasm1());

View File

@ -752,7 +752,7 @@ void VToolSplinePath::SetVisualization()
SCASSERT(visual != nullptr)
QSharedPointer<VSplinePath> splPath = VAbstractTool::data.GeometricObject<VSplinePath>(m_id);
visual->setPath(*splPath.data());
visual->SetPath(*splPath.data());
visual->setLineStyle(LineStyleToPenStyle(splPath->GetPenStyle()));
visual->SetMode(Mode::Show);
visual->RefreshGeometry();

View File

@ -48,34 +48,30 @@
const int EMPTY_ANGLE = -1;
namespace
{
inline auto TriggerRadius() -> qreal
{
return ScaledRadius(SceneScale(VAbstractValApplication::VApp()->getCurrentScene()))*1.5;
}
}
//---------------------------------------------------------------------------------------------------------------------
VisToolSpline::VisToolSpline(const VContainer *data, QGraphicsItem *parent)
: VisPath(data, parent),
object4Id(NULL_ID),
point1(nullptr),
point4(nullptr),
angle1(EMPTY_ANGLE),
angle2(EMPTY_ANGLE),
kAsm1(1),
kAsm2(1),
kCurve(1),
isLeftMousePressed(false),
p2Selected(false),
p3Selected(false),
p2(),
p3(),
controlPoints()
m_angle1(EMPTY_ANGLE),
m_angle2(EMPTY_ANGLE)
{
point1 = InitPoint(supportColor, this);
point4 = InitPoint(supportColor, this); //-V656
m_point1 = InitPoint(supportColor, this);
m_point4 = InitPoint(supportColor, this); //-V656
auto *controlPoint1 = new VControlPointSpline(1, SplinePointPosition::FirstPoint, this);
controlPoint1->hide();
controlPoints.append(controlPoint1);
m_controlPoints.append(controlPoint1);
auto *controlPoint2 = new VControlPointSpline(1, SplinePointPosition::LastPoint, this);
controlPoint2->hide();
controlPoints.append(controlPoint2);
m_controlPoints.append(controlPoint2);
}
//---------------------------------------------------------------------------------------------------------------------
@ -87,88 +83,41 @@ VisToolSpline::~VisToolSpline()
//---------------------------------------------------------------------------------------------------------------------
void VisToolSpline::RefreshGeometry()
{
//Radius of point circle, but little bigger. Need handle with hover sizes.
const static qreal radius = ScaledRadius(SceneScale(VAbstractValApplication::VApp()->getCurrentScene()))*1.5;
if (object1Id > NULL_ID)
{
const auto first = Visualization::data->GeometricObject<VPointF>(object1Id);
DrawPoint(point1, static_cast<QPointF>(*first), supportColor);
DrawPoint(m_point1, static_cast<QPointF>(*first), supportColor);
if (mode == Mode::Creation)
{
if (isLeftMousePressed && not p2Selected)
{
p2 = Visualization::scenePos;
controlPoints[0]->RefreshCtrlPoint(1, SplinePointPosition::FirstPoint, p2,
static_cast<QPointF>(*first));
if (not controlPoints[0]->isVisible())
{
if (QLineF(static_cast<QPointF>(*first), p2).length() > radius)
{
controlPoints[0]->show();
}
else
{
p2 = static_cast<QPointF>(*first);
}
}
}
else
{
p2Selected = true;
}
DragFirstControlPoint(static_cast<QPointF>(*first));
}
if (object4Id <= NULL_ID)
if (m_object4Id <= NULL_ID)
{
VSpline spline(*first, p2, Visualization::scenePos, VPointF(Visualization::scenePos));
VSpline spline(*first, m_p2, Visualization::scenePos, VPointF(Visualization::scenePos));
spline.SetApproximationScale(m_approximationScale);
DrawPath(this, spline.GetPath(), mainColor, lineStyle, Qt::RoundCap);
}
else
{
const auto second = Visualization::data->GeometricObject<VPointF>(object4Id);
DrawPoint(point4, static_cast<QPointF>(*second), supportColor);
const auto second = Visualization::data->GeometricObject<VPointF>(m_object4Id);
DrawPoint(m_point4, static_cast<QPointF>(*second), supportColor);
if (mode == Mode::Creation)
{
if (isLeftMousePressed && not p3Selected)
{
QLineF ctrlLine (static_cast<QPointF>(*second), Visualization::scenePos);
ctrlLine.setAngle(ctrlLine.angle()+180);
p3 = ctrlLine.p2();
controlPoints[1]->RefreshCtrlPoint(1, SplinePointPosition::LastPoint, p3,
static_cast<QPointF>(*second));
if (not controlPoints[1]->isVisible())
{
if (QLineF(static_cast<QPointF>(*second), p3).length() > radius)
{
controlPoints[1]->show();
}
else
{
p3 = static_cast<QPointF>(*second);
}
}
}
else
{
p3Selected = true;
}
DragLastControlPoint(static_cast<QPointF>(*second));
}
if (VFuzzyComparePossibleNulls(angle1, EMPTY_ANGLE) || VFuzzyComparePossibleNulls(angle2, EMPTY_ANGLE))
if (VFuzzyComparePossibleNulls(m_angle1, EMPTY_ANGLE) || VFuzzyComparePossibleNulls(m_angle2, EMPTY_ANGLE))
{
VSpline spline(*first, p2, p3, *second);
VSpline spline(*first, m_p2, m_p3, *second);
spline.SetApproximationScale(m_approximationScale);
DrawPath(this, spline.GetPath(), mainColor, lineStyle, Qt::RoundCap);
}
else
{
VSpline spline(*first, *second, angle1, angle2, kAsm1, kAsm2, kCurve);
VSpline spline(*first, *second, m_angle1, m_angle2, m_kAsm1, m_kAsm2, m_kCurve);
spline.SetApproximationScale(m_approximationScale);
DrawPath(this, spline.GetPath(), spline.DirectionArrows(), mainColor, lineStyle, Qt::RoundCap);
Visualization::toolTip = tr("Use <b>%1</b> for sticking angle!")
@ -180,51 +129,51 @@ void VisToolSpline::RefreshGeometry()
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolSpline::setObject4Id(const quint32 &value)
void VisToolSpline::SetObject4Id(quint32 value)
{
object4Id = value;
m_object4Id = value;
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolSpline::SetAngle1(const qreal &value)
void VisToolSpline::SetAngle1(qreal value)
{
angle1 = value;
m_angle1 = value;
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolSpline::SetAngle2(const qreal &value)
void VisToolSpline::SetAngle2(qreal value)
{
angle2 = value;
m_angle2 = value;
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolSpline::SetKAsm1(const qreal &value)
void VisToolSpline::SetKAsm1(qreal value)
{
kAsm1 = value;
m_kAsm1 = value;
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolSpline::SetKAsm2(const qreal &value)
void VisToolSpline::SetKAsm2(qreal value)
{
kAsm2 = value;
m_kAsm2 = value;
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolSpline::SetKCurve(const qreal &value)
void VisToolSpline::SetKCurve(qreal value)
{
kCurve = value;
m_kCurve = value;
}
//---------------------------------------------------------------------------------------------------------------------
QPointF VisToolSpline::GetP2() const
auto VisToolSpline::GetP2() const -> QPointF
{
return p2;
return m_p2;
}
//---------------------------------------------------------------------------------------------------------------------
QPointF VisToolSpline::GetP3() const
auto VisToolSpline::GetP3() const -> QPointF
{
return p3;
return m_p3;
}
//---------------------------------------------------------------------------------------------------------------------
@ -232,7 +181,7 @@ void VisToolSpline::MouseLeftPressed()
{
if (mode == Mode::Creation)
{
isLeftMousePressed = true;
m_isLeftMousePressed = true;
}
}
@ -241,7 +190,59 @@ void VisToolSpline::MouseLeftReleased()
{
if (mode == Mode::Creation)
{
isLeftMousePressed = false;
m_isLeftMousePressed = false;
RefreshGeometry();
}
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolSpline::DragFirstControlPoint(const QPointF &point)
{
if (m_isLeftMousePressed && not m_p2Selected)
{
m_p2 = Visualization::scenePos;
m_controlPoints.at(0)->RefreshCtrlPoint(1, SplinePointPosition::FirstPoint, m_p2, point);
if (not m_controlPoints.at(0)->isVisible())
{
if (QLineF(point, m_p2).length() > TriggerRadius())
{
m_controlPoints.at(0)->show();
}
else
{
m_p2 = point;
}
}
}
else
{
m_p2Selected = true;
}
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolSpline::DragLastControlPoint(const QPointF &point)
{
if (m_isLeftMousePressed && not m_p3Selected)
{
m_p3 = Visualization::scenePos;
m_controlPoints.at(1)->RefreshCtrlPoint(1, SplinePointPosition::LastPoint, m_p3, point);
if (not m_controlPoints.at(1)->isVisible())
{
if (QLineF(point, m_p3).length() > TriggerRadius())
{
m_controlPoints.at(1)->show();
}
else
{
m_p3 = point;
}
}
}
else
{
m_p3Selected = true;
}
}

View File

@ -41,52 +41,59 @@
#include "../vmisc/def.h"
#include "vispath.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
#include "../vmisc/defglobal.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
class VControlPointSpline;
class VisToolSpline : public VisPath
class VisToolSpline : public VisPath // clazy:exclude=ctor-missing-parent-argument
{
Q_OBJECT
Q_OBJECT // NOLINT
public:
explicit VisToolSpline(const VContainer *data, QGraphicsItem *parent = nullptr);
virtual ~VisToolSpline();
~VisToolSpline() override;
virtual void RefreshGeometry() override;
void RefreshGeometry() override;
void setObject4Id(const quint32 &value);
void SetAngle1(const qreal &value);
void SetAngle2(const qreal &value);
void SetKAsm1(const qreal &value);
void SetKAsm2(const qreal &value);
void SetKCurve(const qreal &value);
void SetObject4Id(quint32 value);
void SetAngle1(qreal value);
void SetAngle2(qreal value);
void SetKAsm1(qreal value);
void SetKAsm2(qreal value);
void SetKCurve(qreal value);
QPointF GetP2() const;
QPointF GetP3() const;
auto GetP2() const -> QPointF;
auto GetP3() const -> QPointF;
virtual int type() const override {return Type;}
auto type() const -> int override {return Type;}
enum { Type = UserType + static_cast<int>(Vis::ToolSpline)};
public slots:
void MouseLeftPressed();
void MouseLeftReleased();
protected:
Q_DISABLE_COPY(VisToolSpline)
quint32 object4Id;
VScaledEllipse *point1;
VScaledEllipse *point4;
qreal angle1;
qreal angle2;
qreal kAsm1;
qreal kAsm2;
qreal kCurve;
private:
Q_DISABLE_COPY_MOVE(VisToolSpline) // NOLINT
quint32 m_object4Id{NULL_ID};
VScaledEllipse *m_point1{nullptr};
VScaledEllipse *m_point4{nullptr};
qreal m_angle1;
qreal m_angle2;
qreal m_kAsm1{1};
qreal m_kAsm2{1};
qreal m_kCurve{1};
bool isLeftMousePressed;
bool p2Selected;
bool p3Selected;
bool m_isLeftMousePressed{false};
bool m_p2Selected{false};
bool m_p3Selected{false};
QPointF p2;
QPointF p3;
QPointF m_p2{};
QPointF m_p3{};
QVector<VControlPointSpline *> controlPoints;
QVector<VControlPointSpline *> m_controlPoints{};
void DragFirstControlPoint(const QPointF &point);
void DragLastControlPoint(const QPointF &point);
};
#endif // VISTOOLSPLINE_H

View File

@ -47,18 +47,19 @@
#include "vispath.h"
#include "../vmisc/vmodifierkey.h"
namespace
{
inline auto TriggerRadius() -> qreal
{
return ScaledRadius(SceneScale(VAbstractValApplication::VApp()->getCurrentScene()))*1.5;
}
}
//---------------------------------------------------------------------------------------------------------------------
VisToolSplinePath::VisToolSplinePath(const VContainer *data, QGraphicsItem *parent)
: VisPath(data, parent),
points(),
ctrlPoints(),
newCurveSegment(nullptr),
path(),
isLeftMousePressed(false),
pointSelected(false),
ctrlPoint()
: VisPath(data, parent)
{
newCurveSegment = InitItem<VCurvePathItem>(mainColor, this);
m_newCurveSegment = InitItem<VCurvePathItem>(mainColor, this);
}
//---------------------------------------------------------------------------------------------------------------------
@ -70,75 +71,83 @@ VisToolSplinePath::~VisToolSplinePath()
//---------------------------------------------------------------------------------------------------------------------
void VisToolSplinePath::RefreshGeometry()
{
if (path.CountPoints() > 0)
if (m_path.CountPoints() == 0)
{
const QVector<VSplinePoint> pathPoints = path.GetSplinePath();
const int size = pathPoints.size();
return;
}
for (int i = 0; i < size; ++i)
{
VScaledEllipse *point = this->getPoint(static_cast<unsigned>(i));
DrawPoint(point, static_cast<QPointF>(pathPoints.at(i).P()), supportColor);
}
const QVector<VSplinePoint> pathPoints = m_path.GetSplinePath();
const int size = pathPoints.size();
if (mode == Mode::Creation)
{
if (size > 1)
{
for (qint32 i = 1; i<=path.CountSubSpl(); ++i)
{
const int preLastPoint = (path.CountSubSpl() - 1) * 2;
const int lastPoint = preLastPoint + 1;
VSpline spl = path.GetSpline(i);
ctrlPoints[preLastPoint]->RefreshCtrlPoint(i, SplinePointPosition::FirstPoint,
static_cast<QPointF>(spl.GetP2()),
static_cast<QPointF>(spl.GetP1()));
ctrlPoints[lastPoint]->RefreshCtrlPoint(i, SplinePointPosition::LastPoint,
static_cast<QPointF>(spl.GetP3()),
static_cast<QPointF>(spl.GetP4()));
}
}
Creating(static_cast<QPointF>(pathPoints.at(size-1).P()), size);
}
for (int i = 0; i < size; ++i)
{
VScaledEllipse *point = GetPoint(static_cast<unsigned>(i));
DrawPoint(point, static_cast<QPointF>(pathPoints.at(i).P()), supportColor);
}
if (mode == Mode::Creation)
{
if (size > 1)
{
DrawPath(this, path.GetPath(), path.DirectionArrows(), mainColor, lineStyle, Qt::RoundCap);
for (qint32 i = 1; i<=m_path.CountSubSpl(); ++i)
{
const int preLastPoint = (m_path.CountSubSpl() - 1) * 2;
const int lastPoint = preLastPoint + 1;
VSpline spl = m_path.GetSpline(i);
m_ctrlPoints.at(preLastPoint)->RefreshCtrlPoint(i, SplinePointPosition::FirstPoint,
static_cast<QPointF>(spl.GetP2()),
static_cast<QPointF>(spl.GetP1()));
m_ctrlPoints.at(lastPoint)->RefreshCtrlPoint(i, SplinePointPosition::LastPoint,
static_cast<QPointF>(spl.GetP3()),
static_cast<QPointF>(spl.GetP4()));
}
}
if (path.CountPoints() < 3)
{
Visualization::toolTip = tr("<b>Curved path</b>: select three or more points");
}
else
{
Visualization::toolTip = tr("<b>Curved path</b>: select three or more points, "
"<b>%1</b> - finish creation")
.arg(VModifierKey::EnterKey());
}
if (mode == Mode::Show)
{
Visualization::toolTip = tr("Use <b>%1</b> for sticking angle!")
.arg(VModifierKey::Shift());
emit ToolTip(Visualization::toolTip);
}
Creating(static_cast<QPointF>(pathPoints.at(size-1).P()), size);
}
if (size == 1)
{
VSpline spline(pathPoints.at(0).P(), m_ctrlPoint, Visualization::scenePos, VPointF(Visualization::scenePos));
spline.SetApproximationScale(m_approximationScale);
DrawPath(this, spline.GetPath(), mainColor, lineStyle, Qt::RoundCap);
}
else if (size > 1)
{
DrawPath(this, m_path.GetPath(), m_path.DirectionArrows(), mainColor, lineStyle, Qt::RoundCap);
}
if (m_path.CountPoints() < 3)
{
Visualization::toolTip = tr("<b>Curved path</b>: select three or more points");
}
else
{
Visualization::toolTip = tr("<b>Curved path</b>: select three or more points, "
"<b>%1</b> - finish creation")
.arg(VModifierKey::EnterKey());
}
if (mode == Mode::Show)
{
Visualization::toolTip = tr("Use <b>%1</b> for sticking angle!")
.arg(VModifierKey::Shift());
emit ToolTip(Visualization::toolTip);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolSplinePath::setPath(const VSplinePath &value)
void VisToolSplinePath::SetPath(const VSplinePath &value)
{
path = value;
m_path = value;
}
//---------------------------------------------------------------------------------------------------------------------
// cppcheck-suppress unusedFunction
VSplinePath VisToolSplinePath::getPath()
auto VisToolSplinePath::GetPath() -> VSplinePath
{
return path;
return m_path;
}
//---------------------------------------------------------------------------------------------------------------------
@ -146,7 +155,7 @@ void VisToolSplinePath::MouseLeftPressed()
{
if (mode == Mode::Creation)
{
isLeftMousePressed = true;
m_isLeftMousePressed = true;
}
}
@ -155,45 +164,123 @@ void VisToolSplinePath::MouseLeftReleased()
{
if (mode == Mode::Creation)
{
isLeftMousePressed = false;
m_isLeftMousePressed = false;
RefreshGeometry();
}
}
//---------------------------------------------------------------------------------------------------------------------
VScaledEllipse *VisToolSplinePath::getPoint(quint32 i)
auto VisToolSplinePath::GetPoint(quint32 i) -> VScaledEllipse *
{
if (static_cast<quint32>(points.size() - 1) >= i && points.isEmpty() == false)
if (static_cast<quint32>(m_points.size() - 1) >= i && not m_points.isEmpty())
{
return points.at(static_cast<int>(i));
return m_points.at(static_cast<int>(i));
}
m_pointSelected = false;
auto *point = InitPoint(supportColor, this);
m_points.append(point);
if (m_points.size() == 1)
{
auto *controlPoint1 = new VControlPointSpline(m_points.size(), SplinePointPosition::FirstPoint, this);
controlPoint1->hide();
m_ctrlPoints.append(controlPoint1);
}
else
{
pointSelected = false;
auto *controlPoint1 = new VControlPointSpline(m_points.size()-1, SplinePointPosition::LastPoint, this);
controlPoint1->hide();
m_ctrlPoints.append(controlPoint1);
auto point = InitPoint(supportColor, this);
points.append(point);
auto *controlPoint2 = new VControlPointSpline(m_points.size(), SplinePointPosition::FirstPoint, this);
controlPoint2->hide();
m_ctrlPoints.append(controlPoint2);
}
if (points.size() == 1)
return point;
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolSplinePath::DragControlPoint(int lastPoint, int preLastPoint, const QPointF &pSpl, int size)
{
if (not m_ctrlPoints.at(lastPoint)->isVisible())
{
//Radius of point circle, but little bigger. Need handle with hover sizes.
if (QLineF(pSpl, m_ctrlPoint).length() > TriggerRadius())
{
auto *controlPoint1 = new VControlPointSpline(points.size(), SplinePointPosition::FirstPoint, this);
controlPoint1->hide();
ctrlPoints.append(controlPoint1);
if (size == 1)
{
m_ctrlPoints.at(lastPoint)->show();
}
else
{
m_ctrlPoints.at(preLastPoint)->show();
m_ctrlPoints.at(lastPoint)->show();
}
}
else
{
auto *controlPoint1 = new VControlPointSpline(points.size()-1, SplinePointPosition::LastPoint, this);
controlPoint1->hide();
ctrlPoints.append(controlPoint1);
auto *controlPoint2 = new VControlPointSpline(points.size(), SplinePointPosition::FirstPoint, this);
controlPoint2->hide();
ctrlPoints.append(controlPoint2);
m_ctrlPoint = pSpl;
}
return point;
}
return nullptr;
QLineF ctrlLine (pSpl, Visualization::scenePos);
ctrlLine.setAngle(ctrlLine.angle()+180);
if (size == 1)
{
m_ctrlPoints.at(lastPoint)->RefreshCtrlPoint(size, SplinePointPosition::FirstPoint, m_ctrlPoint, pSpl);
}
else
{
m_ctrlPoints.at(preLastPoint)->RefreshCtrlPoint(size-1, SplinePointPosition::LastPoint, ctrlLine.p2(), pSpl);
m_ctrlPoints.at(lastPoint)->RefreshCtrlPoint(size, SplinePointPosition::FirstPoint, m_ctrlPoint, pSpl);
}
VSpline spline(VPointF(pSpl), m_ctrlPoint, Visualization::scenePos, VPointF(Visualization::scenePos));
if (size == 1)
{
NewCurveSegment(spline, pSpl, size);
}
else
{
const VSpline spl = m_path.GetSpline(size - 1);
VSpline preSpl(spl.GetP1(), static_cast<QPointF>(spl.GetP2()), ctrlLine.p2(), VPointF(pSpl));
m_path[size-1].SetAngle2(spline.GetStartAngle(), spline.GetStartAngleFormula());
if (m_ctrlPoint != pSpl)
{
m_path[size-1].SetLength1(preSpl.GetC2Length(), preSpl.GetC2LengthFormula());
m_path[size-1].SetLength2(spline.GetC1Length(), spline.GetC1LengthFormula());
}
else
{
m_path[size-1].SetLength1(0, QChar('0'));
m_path[size-1].SetLength2(0, QChar('0'));
}
emit PathChanged(m_path);
}
DrawPath(m_newCurveSegment, spline.GetPath(), mainColor, Qt::SolidLine, Qt::RoundCap);
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolSplinePath::NewCurveSegment(const VSpline &spline, const QPointF &pSpl, int size)
{
m_path[size-1].SetAngle2(spline.GetStartAngle(), spline.GetStartAngleFormula());
if (m_ctrlPoint != pSpl)
{
m_path[size-1].SetLength2(spline.GetC1Length(), spline.GetC1LengthFormula());
}
else
{
m_path[size-1].SetLength2(0, QChar('0'));
}
emit PathChanged(m_path);
}
//---------------------------------------------------------------------------------------------------------------------
@ -208,99 +295,19 @@ void VisToolSplinePath::Creating(const QPointF &pSpl, int size)
preLastPoint = lastPoint - 1;
}
if (isLeftMousePressed && not pointSelected)
if (m_isLeftMousePressed && not m_pointSelected)
{
newCurveSegment->hide();
m_newCurveSegment->hide();
m_ctrlPoint = Visualization::scenePos;
ctrlPoint = Visualization::scenePos;
if (not ctrlPoints[lastPoint]->isVisible())
{
//Radius of point circle, but little bigger. Need handle with hover sizes.
if (QLineF(pSpl, ctrlPoint).length() >
ScaledRadius(SceneScale(VAbstractValApplication::VApp()->getCurrentScene()))*1.5)
{
if (size == 1)
{
ctrlPoints[lastPoint]->show();
}
else
{
ctrlPoints[preLastPoint]->show();
ctrlPoints[lastPoint]->show();
}
}
else
{
ctrlPoint = pSpl;
}
}
QLineF ctrlLine (pSpl, Visualization::scenePos);
ctrlLine.setAngle(ctrlLine.angle()+180);
if (size == 1)
{
ctrlPoints[lastPoint]->RefreshCtrlPoint(size, SplinePointPosition::FirstPoint, ctrlPoint, pSpl);
}
else
{
ctrlPoints[preLastPoint]->RefreshCtrlPoint(size-1, SplinePointPosition::LastPoint, ctrlLine.p2(), pSpl);
ctrlPoints[lastPoint]->RefreshCtrlPoint(size, SplinePointPosition::FirstPoint, ctrlPoint, pSpl);
}
VSpline spline(VPointF(pSpl), ctrlPoint, Visualization::scenePos, VPointF(Visualization::scenePos));
if (size == 1)
{
path[size-1].SetAngle2(spline.GetStartAngle(), spline.GetStartAngleFormula());
if (ctrlPoint != pSpl)
{
path[size-1].SetLength2(spline.GetC1Length(), spline.GetC1LengthFormula());
}
else
{
path[size-1].SetLength2(0, QChar('0'));
}
emit PathChanged(path);
}
else
{
const VSpline spl = path.GetSpline(size - 1);
VSpline preSpl(spl.GetP1(), static_cast<QPointF>(spl.GetP2()), ctrlLine.p2(), VPointF(pSpl));
path[size-1].SetAngle2(spline.GetStartAngle(), spline.GetStartAngleFormula());
if (ctrlPoint != pSpl)
{
path[size-1].SetLength1(preSpl.GetC2Length(), preSpl.GetC2LengthFormula());
path[size-1].SetLength2(spline.GetC1Length(), spline.GetC1LengthFormula());
}
else
{
path[size-1].SetLength1(0, QChar('0'));
path[size-1].SetLength2(0, QChar('0'));
}
emit PathChanged(path);
}
DragControlPoint(lastPoint, preLastPoint, pSpl, size);
}
else
{
pointSelected = true;
m_pointSelected = true;
VSpline spline(VPointF(pSpl), ctrlPoint, Visualization::scenePos, VPointF(Visualization::scenePos));
path[size-1].SetAngle2(spline.GetStartAngle(), spline.GetStartAngleFormula());
if (ctrlPoint != pSpl)
{
path[size-1].SetLength2(spline.GetC1Length(), spline.GetC1LengthFormula());
}
else
{
path[size-1].SetLength2(0, QChar('0'));
}
emit PathChanged(path);
DrawPath(newCurveSegment, spline.GetPath(), mainColor, Qt::SolidLine, Qt::RoundCap);
VSpline spline(VPointF(pSpl), m_ctrlPoint, Visualization::scenePos, VPointF(Visualization::scenePos));
NewCurveSegment(spline, pSpl, size);
DrawPath(m_newCurveSegment, spline.GetPath(), mainColor, Qt::SolidLine, Qt::RoundCap);
}
}

View File

@ -42,21 +42,25 @@
#include "../vmisc/def.h"
#include "vispath.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
#include "../vmisc/defglobal.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
class VControlPointSpline;
class VisToolSplinePath : public VisPath
class VisToolSplinePath : public VisPath // clazy:exclude=ctor-missing-parent-argument
{
Q_OBJECT
Q_OBJECT // NOLINT
public:
explicit VisToolSplinePath(const VContainer *data, QGraphicsItem *parent = nullptr);
virtual ~VisToolSplinePath();
~VisToolSplinePath() override;
virtual void RefreshGeometry() override;
void RefreshGeometry() override;
void setPath(const VSplinePath &value);
VSplinePath getPath();
void SetPath(const VSplinePath &value);
auto GetPath() -> VSplinePath;
virtual int type() const override {return Type;}
auto type() const -> int override {return Type;}
enum { Type = UserType + static_cast<int>(Vis::ToolSplinePath)};
signals:
void PathChanged(const VSplinePath &path);
@ -65,19 +69,21 @@ public slots:
void MouseLeftPressed();
void MouseLeftReleased();
protected:
Q_DISABLE_COPY(VisToolSplinePath)
QVector<VScaledEllipse *> points;
QVector<VControlPointSpline *> ctrlPoints;
VCurvePathItem *newCurveSegment;
VSplinePath path;
private:
Q_DISABLE_COPY_MOVE(VisToolSplinePath) // NOLINT
QVector<VScaledEllipse *> m_points{};
QVector<VControlPointSpline *> m_ctrlPoints{};
VCurvePathItem* m_newCurveSegment{nullptr};
VSplinePath m_path{};
bool isLeftMousePressed;
bool pointSelected;
bool m_isLeftMousePressed{false};
bool m_pointSelected{false};
QPointF ctrlPoint;
QPointF m_ctrlPoint{};
VScaledEllipse * getPoint(quint32 i);
auto GetPoint(quint32 i) -> VScaledEllipse*;
void DragControlPoint(int lastPoint, int preLastPoint, const QPointF &pSpl, int size);
void NewCurveSegment(const VSpline &spline, const QPointF &pSpl, int size);
void Creating(const QPointF &pSpl, int size);
};