Seamly2D
Code documentation
vabstractspline.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * *
3  * Copyright (C) 2017 Seamly, LLC *
4  * *
5  * https://github.com/fashionfreedom/seamly2d *
6  * *
7  ***************************************************************************
8  **
9  ** Seamly2D is free software: you can redistribute it and/or modify
10  ** it under the terms of the GNU General Public License as published by
11  ** the Free Software Foundation, either version 3 of the License, or
12  ** (at your option) any later version.
13  **
14  ** Seamly2D is distributed in the hope that it will be useful,
15  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  ** GNU General Public License for more details.
18  **
19  ** You should have received a copy of the GNU General Public License
20  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
21  **
22  **************************************************************************
23 
24  ************************************************************************
25  **
26  ** @file vabstractspline.cpp
27  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
28  ** @date 4 3, 2014
29  **
30  ** @brief
31  ** @copyright
32  ** This source code is part of the Valentine project, a pattern making
33  ** program, whose allow create and modeling patterns of clothing.
34  ** Copyright (C) 2013-2015 Seamly2D project
35  ** <https://github.com/fashionfreedom/seamly2d> All Rights Reserved.
36  **
37  ** Seamly2D is free software: you can redistribute it and/or modify
38  ** it under the terms of the GNU General Public License as published by
39  ** the Free Software Foundation, either version 3 of the License, or
40  ** (at your option) any later version.
41  **
42  ** Seamly2D is distributed in the hope that it will be useful,
43  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
44  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45  ** GNU General Public License for more details.
46  **
47  ** You should have received a copy of the GNU General Public License
48  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
49  **
50  *************************************************************************/
51 
52 #include "vabstractspline.h"
53 
54 #include <QColor>
55 #include <QFlags>
56 #include <QGraphicsScene>
57 #include <QGraphicsSceneMouseEvent>
58 #include <QGuiApplication>
59 #include <QKeyEvent>
60 #include <QLineF>
61 #include <QPen>
62 #include <QSharedPointer>
63 #include <Qt>
64 #include <new>
65 
66 #include "../ifc/exception/vexception.h"
67 #include "../ifc/exception/vexceptionbadid.h"
68 #include "../ifc/xml/vabstractpattern.h"
69 #include "../qmuparser/qmutokenparser.h"
70 #include "../vgeometry/vgobject.h"
71 #include "../vgeometry/vpointf.h"
72 #include "../vgeometry/vspline.h"
73 #include "../vpatterndb/vcontainer.h"
74 #include "../vwidgets/vcontrolpointspline.h"
75 #include "../../../visualization/line/visline.h"
76 #include "../../vabstracttool.h"
77 #include "../vdrawtool.h"
78 
79 //---------------------------------------------------------------------------------------------------------------------
80 VAbstractSpline::VAbstractSpline(VAbstractPattern *doc, VContainer *data, quint32 id, QGraphicsItem *parent)
81  : VDrawTool(doc, data, id)
82  , QGraphicsPathItem(parent)
83  , controlPoints()
84  , sceneType(SceneObject::Unknown)
85  , m_isHovered(false)
86  , m_piecesMode(qApp->Settings()->getShowControlPoints())
87 {
88  InitDefShape();
89  setAcceptHoverEvents(true);
90 }
91 
92 //---------------------------------------------------------------------------------------------------------------------
93 QPainterPath VAbstractSpline::shape() const
94 {
96  const QVector<QPointF> points = curve->getPoints();
97 
98  QPainterPath path;
99  for (qint32 i = 0; i < points.count()-1; ++i)
100  {
101  path.moveTo(points.at(i));
102  path.lineTo(points.at(i+1));
103  }
104 
105  if (m_isHovered || m_piecesMode)
106  {
107  path.addPath(VAbstractCurve::ShowDirection(curve->DirectionArrows(),
109  sceneScale(scene()))));
110  }
111  path.setFillRule(Qt::WindingFill);
112  return ItemShapeFromPath(path, pen());
113 }
114 
115 //---------------------------------------------------------------------------------------------------------------------
116 void VAbstractSpline::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
117 {
118  //const qreal width = scaleWidth(m_isHovered ? widthMainLine : widthHairLine, sceneScale(scene()));
119 
120 
122  const qreal weight = ToPixel(doc->useGroupLineWeight(m_id, curve->getLineWeight()).toDouble(), Unit::Mm);
123  const qreal width = scaleWidth(m_isHovered ? weight + 4 : weight, sceneScale(scene()));
124 
125  setPen(QPen(correctColor(this, doc->useGroupColor(m_id, curve->getLineColor())), width,
126  lineTypeToPenStyle(doc->useGroupLineType(m_id, curve->GetPenStyle())), Qt::RoundCap));
127 
129 
130  if (m_isHovered || m_piecesMode)
131  {
132  painter->save();
133 
134  QPen arrowPen(pen());
135  arrowPen.setStyle(Qt::SolidLine);
136 
137  painter->setPen(arrowPen);
138  painter->setBrush(brush());
139 
140  painter->drawPath(VAbstractCurve::ShowDirection(curve->DirectionArrows(),
142  sceneScale(scene()))));
143 
144  painter->restore();
145  }
146 
147  QGraphicsPathItem::paint(painter, option, widget);
148 }
149 
150 //---------------------------------------------------------------------------------------------------------------------
152 {
154 }
155 
156 //---------------------------------------------------------------------------------------------------------------------
157 /**
158  * @brief FullUpdateFromFile update tool data form file.
159  */
161 {
162  ReadAttributes();
163  RefreshGeometry();
164 }
165 
166 //---------------------------------------------------------------------------------------------------------------------
167 void VAbstractSpline::Disable(bool disable, const QString &draftBlockName)
168 {
169  const bool enabled = !CorrectDisable(disable, draftBlockName);
170  this->setEnabled(enabled);
171  emit setEnabledPoint(enabled);
172 }
173 
174 //---------------------------------------------------------------------------------------------------------------------
176 {
177  m_piecesMode = mode;
178  RefreshGeometry();
180 }
181 
182 //---------------------------------------------------------------------------------------------------------------------
183 void VAbstractSpline::AllowHover(bool enabled)
184 {
185  setAcceptHoverEvents(enabled);
186 }
187 
188 //---------------------------------------------------------------------------------------------------------------------
190 {
191  setFlag(QGraphicsItem::ItemIsSelectable, enabled);
192 }
193 
194 //---------------------------------------------------------------------------------------------------------------------
196 {
198 
199  const QString toolTip = QString("<table>"
200  "<tr> <td><b> %4:</b> %5</td> </tr>"
201  "<tr> <td><b>%1:</b> %2 %3</td> </tr>"
202  "</table>")
203  .arg(tr("Length"))
204  .arg(qApp->fromPixel(curve->GetLength()))
205  .arg(UnitsToStr(qApp->patternUnit(), true))
206  .arg(tr("Name"))
207  .arg(curve->name());
208 
209  return toolTip;
210 }
211 
212 //---------------------------------------------------------------------------------------------------------------------
213 /**
214  * @brief ShowTool highlight tool.
215  * @param id object id in container
216  * @param enable enable or disable highlight.
217  */
218 void VAbstractSpline::ShowTool(quint32 id, bool enable)
219 {
220  ShowItem(this, id, enable);
221 }
222 
223 //---------------------------------------------------------------------------------------------------------------------
225 {
226  InitDefShape();
229 }
230 
231 //---------------------------------------------------------------------------------------------------------------------
232 /**
233  * @brief hoverEnterEvent handle hover enter events.
234  * @param event hover enter event.
235  */
236 // cppcheck-suppress unusedFunction
237 void VAbstractSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
238 {
239  m_isHovered = true;
240  setToolTip(makeToolTip());
241  QGraphicsPathItem::hoverEnterEvent(event);
242 }
243 
244 //---------------------------------------------------------------------------------------------------------------------
245 /**
246  * @brief hoverLeaveEvent handle hover leave events.
247  * @param event hover leave event.
248  */
249 // cppcheck-suppress unusedFunction
250 void VAbstractSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
251 {
252  m_isHovered = false;
253  QGraphicsPathItem::hoverLeaveEvent(event);
254 }
255 
256 //---------------------------------------------------------------------------------------------------------------------
257 /**
258  * @brief itemChange hadle item change.
259  * @param change change.
260  * @param value value.
261  * @return value.
262  */
263 QVariant VAbstractSpline::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
264 {
265  if (change == QGraphicsItem::ItemSelectedChange)
266  {
267  emit ChangedToolSelection(value.toBool(), m_id, m_id);
268  }
269 
270  return QGraphicsPathItem::itemChange(change, value);
271 }
272 
273 //---------------------------------------------------------------------------------------------------------------------
274 /**
275  * @brief keyReleaseEvent handle key release events.
276  * @param event key release event.
277  */
278 void VAbstractSpline::keyReleaseEvent(QKeyEvent *event)
279 {
280  switch (event->key())
281  {
282  case Qt::Key_Delete:
283  try
284  {
285  deleteTool();
286  }
287  catch(const VExceptionToolWasDeleted &e)
288  {
289  Q_UNUSED(e)
290  return;//Leave this method immediately!!!
291  }
292  break;
293  default:
294  break;
295  }
296  QGraphicsPathItem::keyReleaseEvent ( event );
297 }
298 
299 //---------------------------------------------------------------------------------------------------------------------
300 void VAbstractSpline::mousePressEvent(QGraphicsSceneMouseEvent *event)
301 {
302  // Special for not selectable item first need to call standard mousePressEvent then accept event
303  QGraphicsPathItem::mousePressEvent(event);
304 
305  // Somehow clicking on notselectable object do not clean previous selections.
306  if (not (flags() & ItemIsSelectable) && scene())
307  {
308  scene()->clearSelection();
309  }
310 
311  event->accept();// Special for not selectable item first need to call standard mousePressEvent then accept event
312 }
313 
314 //---------------------------------------------------------------------------------------------------------------------
315 /**
316  * @brief mouseReleaseEvent handle mouse release events.
317  * @param event mouse release event.
318  */
319 void VAbstractSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
320 {
321  if (event->button() == Qt::LeftButton)
322  {
323  emit chosenTool(m_id, sceneType);
324  }
325  QGraphicsPathItem::mouseReleaseEvent(event);
326 }
327 
328 //---------------------------------------------------------------------------------------------------------------------
329 void VAbstractSpline::ReadToolAttributes(const QDomElement &domElement)
330 {
331  Q_UNUSED(domElement)
332 }
333 
334 //---------------------------------------------------------------------------------------------------------------------
336 {
337  VDrawTool::SaveOptions(tag, obj);
338 
339  const QSharedPointer<VAbstractCurve> curve = qSharedPointerCast<VAbstractCurve>(obj);
340  doc->SetAttribute(tag, AttrColor, curve->getLineColor());
341  doc->SetAttribute(tag, AttrPenStyle, curve->GetPenStyle());
342  doc->SetAttribute(tag, AttrLineWeight, curve->getLineWeight());
343 }
344 
345 //---------------------------------------------------------------------------------------------------------------------
347 {
348  // do nothing
349 }
350 
351 //---------------------------------------------------------------------------------------------------------------------
352 void VAbstractSpline::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
353 {
354  showContextMenu(event);
355 }
356 
357 //---------------------------------------------------------------------------------------------------------------------
359  const QPointF &pos) const
360 {
361  VSpline spl;
362  if (position == SplinePointPosition::FirstPoint)
363  {
364  QLineF line(static_cast<QPointF>(spline.GetP1()), pos);
365  if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier)
366  {
367  line.setAngle(VisLine::CorrectAngle(line.angle()));
368  }
369 
370  qreal newAngle1 = line.angle();
371  QString newAngle1F = QString().setNum(newAngle1);
372 
373  qreal newLength1 = line.length();
374  QString newLength1F = QString().setNum(qApp->fromPixel(newLength1));
375 
377  {
378  newAngle1 = spline.GetStartAngle();
379  newAngle1F = spline.GetStartAngleFormula();
380  }
381 
383  {
384  newLength1 = spline.GetC1Length();
385  newLength1F = spline.GetC1LengthFormula();
386  }
387 
388  spl = VSpline(spline.GetP1(), spline.GetP4(), newAngle1, newAngle1F, spline.GetEndAngle(),
389  spline.GetEndAngleFormula(), newLength1, newLength1F, spline.GetC2Length(),
390  spline.GetC2LengthFormula());
391  }
392  else
393  {
394  QLineF line(static_cast<QPointF>(spline.GetP4()), pos);
395  if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier)
396  {
397  line.setAngle(VisLine::CorrectAngle(line.angle()));
398  }
399 
400  qreal newAngle2 = line.angle();
401  QString newAngle2F = QString().setNum(newAngle2);
402 
403  qreal newLength2 = line.length();
404  QString newLength2F = QString().setNum(qApp->fromPixel(newLength2));
405 
407  {
408  newAngle2 = spline.GetEndAngle();
409  newAngle2F = spline.GetEndAngleFormula();
410  }
411 
413  {
414  newLength2 = spline.GetC2Length();
415  newLength2F = spline.GetC2LengthFormula();
416  }
417  spl = VSpline(spline.GetP1(), spline.GetP4(), spline.GetStartAngle(), spline.GetStartAngleFormula(),
418  newAngle2, newAngle2F, spline.GetC1Length(), spline.GetC1LengthFormula(),
419  newLength2, newLength2F);
420  }
421 
422  return spl;
423 }
424 
425 //---------------------------------------------------------------------------------------------------------------------
427 {
429  this->setPath(curve->GetPath());
430 }
431 
432 //---------------------------------------------------------------------------------------------------------------------
434 {
435  for (int i = 0; i < controlPoints.size(); ++i)
436  {
437  controlPoints.at(i)->setVisible(show);
438  }
439 }
440 
441 //---------------------------------------------------------------------------------------------------------------------
443 {
445  return curve->getLineColor();
446 }
447 
448 //---------------------------------------------------------------------------------------------------------------------
449 void VAbstractSpline::setLineColor(const QString &value)
450 {
452  curve->setLineColor(value);
453  QSharedPointer<VGObject> obj = qSharedPointerCast<VGObject>(curve);
454  SaveOption(obj);
455 }
456 
457 //---------------------------------------------------------------------------------------------------------------------
459 {
461  return curve->GetPenStyle();
462 }
463 
464 //---------------------------------------------------------------------------------------------------------------------
465 void VAbstractSpline::SetPenStyle(const QString &value)
466 {
468  curve->SetPenStyle(value);
469  QSharedPointer<VGObject> obj = qSharedPointerCast<VGObject>(curve);
470  SaveOption(obj);
471 }
472 
473 //---------------------------------------------------------------------------------------------------------------------
474 /**
475  * @brief getLineWeight return line weight of the spline
476  * @return line weight
477  */
479 {
481  return curve->getLineWeight();
482 }
483 
484 //---------------------------------------------------------------------------------------------------------------------
485 /**
486  * @brief setLineWeight set line weight of the spline
487  * @param value line weight
488  */
489 void VAbstractSpline::setLineWeight(const QString &value)
490 {
492  curve->setLineWeight(value);
493  QSharedPointer<VGObject> obj = qSharedPointerCast<VGObject>(curve);
494  SaveOption(obj);
495 }
496 
497 //---------------------------------------------------------------------------------------------------------------------
498 QString VAbstractSpline::name() const
499 {
500  return ObjectName<VAbstractCurve>(m_id);
501 }
502 
503 //---------------------------------------------------------------------------------------------------------------------
504 void VAbstractSpline::GroupVisibility(quint32 object, bool visible)
505 {
506  Q_UNUSED(object)
507  setVisible(visible);
508 }
static const qreal lengthCurveDirectionArrow
static QPainterPath ShowDirection(const QVector< DirectionArrow > &arrows, qreal width)
static const QString TagSpline
QString useGroupColor(quint32 toolId, QString color)
QString useGroupLineWeight(quint32 toolId, QString weight)
QString useGroupLineType(quint32 toolId, QString type)
virtual void SaveOptions(QDomElement &tag, QSharedPointer< VGObject > &obj) Q_DECL_OVERRIDE
virtual QPainterPath shape() const Q_DECL_OVERRIDE
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE
mouseReleaseEvent handle mouse release events.
void setLineColor(const QString &value)
virtual void ReadToolAttributes(const QDomElement &domElement) Q_DECL_OVERRIDE
void SetPenStyle(const QString &value)
virtual void ShowTool(quint32 id, bool enable) Q_DECL_OVERRIDE
ShowTool highlight tool.
virtual void piecesMode(bool mode) Q_DECL_OVERRIDE
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) Q_DECL_OVERRIDE
void setEnabledPoint(bool enable)
setEnabledPoint disable control points.
virtual void RefreshGeometry()
RefreshGeometry refresh item on scene.
virtual void refreshCtrlPoints()
virtual void AllowSelecting(bool enabled) Q_DECL_OVERRIDE
virtual QString getTagName() const Q_DECL_OVERRIDE
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) Q_DECL_OVERRIDE
hoverEnterEvent handle hover enter events.
QString name() const
QString getLineColor() const
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE
void setLineWeight(const QString &value)
setLineWeight set line weight of the spline
SceneObject sceneType
virtual void FullUpdateFromFile() Q_DECL_OVERRIDE
FullUpdateFromFile update tool data form file.
virtual void AllowHover(bool enabled) Q_DECL_OVERRIDE
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) Q_DECL_OVERRIDE
hoverLeaveEvent handle hover leave events.
virtual void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE
keyReleaseEvent handle key release events.
virtual QString makeToolTip() const Q_DECL_OVERRIDE
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) Q_DECL_OVERRIDE
itemChange hadle item change.
QVector< VControlPointSpline * > controlPoints
controlPoints list pointers of control points.
virtual void Disable(bool disable, const QString &draftBlockName) Q_DECL_OVERRIDE
QString GetPenStyle() const
VAbstractSpline(VAbstractPattern *doc, VContainer *data, quint32 id, QGraphicsItem *parent=nullptr)
void ShowHandles(bool show)
virtual void GroupVisibility(quint32 object, bool visible) Q_DECL_OVERRIDE
QString getLineWeight() const
getLineWeight return line weight of the spline
VSpline CorrectedSpline(const VSpline &spline, const SplinePointPosition &position, const QPointF &pos) const
VAbstractPattern * doc
doc dom document container
virtual void deleteTool(bool ask=true)
deleteTool full delete object form scene and file.
void chosenTool(quint32 id, SceneObject type)
chosenTool emit if object was clicked.
const quint32 m_id
id object id.
virtual void SetVisualization()=0
The VContainer class container of all variables.
Definition: vcontainer.h:141
const QSharedPointer< T > GeometricObject(const quint32 &id) const
Definition: vcontainer.h:266
VContainer data
data container with data
Definition: vdatatool.h:84
void SetAttribute(QDomElement &domElement, const QString &name, const T &value) const
SetAttribute set attribute in pattern file. Replace "," by ".".
Definition: vdomdocument.h:185
The VDrawTool abstract class for all draw tool.
Definition: vdrawtool.h:68
virtual void showContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 id=NULL_ID)=0
void ShowItem(Item *item, quint32 id, bool enable)
ShowItem highlight tool.
Definition: vdrawtool.h:332
virtual void SaveOptions(QDomElement &tag, QSharedPointer< VGObject > &obj)
Definition: vdrawtool.cpp:163
void SaveOption(QSharedPointer< VGObject > &obj)
Definition: vdrawtool.cpp:142
bool CorrectDisable(bool disable, const QString &draftBlockName) const
Definition: vdrawtool.cpp:177
void ChangedToolSelection(bool selected, quint32 object, quint32 tool)
void ReadAttributes()
Definition: vdrawtool.cpp:190
VSpline class that implements the spline.
Definition: vspline.h:75
virtual qreal GetC2Length() const Q_DECL_OVERRIDE
Definition: vspline.cpp:385
virtual VPointF GetP4() const Q_DECL_OVERRIDE
GetP4 return last spline point.
Definition: vspline.cpp:321
QString GetC1LengthFormula() const
Definition: vspline.cpp:391
virtual qreal GetStartAngle() const Q_DECL_OVERRIDE
GetAngle1 return first angle control line.
Definition: vspline.cpp:337
virtual VPointF GetP1() const Q_DECL_OVERRIDE
GetP1 return first spline point.
Definition: vspline.cpp:281
QString GetStartAngleFormula() const
Definition: vspline.cpp:353
QString GetEndAngleFormula() const
Definition: vspline.cpp:359
virtual qreal GetC1Length() const Q_DECL_OVERRIDE
Definition: vspline.cpp:379
QString GetC2LengthFormula() const
Definition: vspline.cpp:397
virtual qreal GetEndAngle() const Q_DECL_OVERRIDE
GetAngle2 return second angle control line.
Definition: vspline.cpp:347
static qreal CorrectAngle(const qreal &angle)
Definition: visline.cpp:54
static bool IsSingle(const QString &formula)
IsSingle test formula and return true if it contain only one number.
double ToPixel(double val, const Unit &unit)
Definition: def.cpp:231
QString UnitsToStr(const Unit &unit, const bool translate)
UnitsToStr translate unit to string.
Definition: def.cpp:702
SceneObject
Definition: def.h:103
qreal sceneScale(QGraphicsScene *scene)
Definition: global.cpp:63
QPainterPath ItemShapeFromPath(const QPainterPath &path, const QPen &pen)
Definition: global.cpp:140
qreal scaleWidth(qreal width, qreal scale)
Definition: global.cpp:130
QColor correctColor(const QGraphicsItem *item, const QColor &color)
Definition: global.cpp:80
const QString AttrLineWeight
Definition: ifcdef.cpp:91
const QString AttrPenStyle
Definition: ifcdef.cpp:132
const QString AttrColor
Definition: ifcdef.cpp:131
Qt::PenStyle lineTypeToPenStyle(const QString &lineType)
LineStyle return pen style for current line style.
Definition: ifcdef.cpp:183
#define qApp
Definition: vapplication.h:67
SplinePointPosition
Definition: vgeometrydef.h:58