Seamly2D
Code documentation
dialogcubicbezierpath.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 dialogcubicbezierpath.cpp
27  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
28  ** @date 18 3, 2016
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) 2016 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 "dialogcubicbezierpath.h"
53 
54 #include <QColor>
55 #include <QComboBox>
56 #include <QDialogButtonBox>
57 #include <QFont>
58 #include <QLabel>
59 #include <QLineEdit>
60 #include <QListWidget>
61 #include <QListWidgetItem>
62 #include <QPointer>
63 #include <QPushButton>
64 #include <QSharedPointer>
65 #include <QVariant>
66 #include <QVector>
67 #include <Qt>
68 #include <new>
69 
70 #include "../../tools/vabstracttool.h"
71 #include "../../visualization/path/vistoolcubicbezierpath.h"
72 #include "../../visualization/visualization.h"
73 #include "../ifc/ifcdef.h"
74 #include "../vmisc/vabstractapplication.h"
75 #include "../vmisc/vmath.h"
76 #include "../vpatterndb/vcontainer.h"
77 #include "../vwidgets/vabstractmainwindow.h"
78 #include "dialogtool.h"
79 #include "ui_dialogcubicbezierpath.h"
80 
81 class QWidget;
82 
83 //---------------------------------------------------------------------------------------------------------------------
84 DialogCubicBezierPath::DialogCubicBezierPath(const VContainer *data, const quint32 &toolId, QWidget *parent)
85  : DialogTool(data, toolId, parent)
86  , ui(new Ui::DialogCubicBezierPath)
87  , path()
88  , newDuplicate(-1)
89 {
90  ui->setupUi(this);
91  setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
92  setWindowIcon(QIcon(":/toolicon/32x32/cubic_bezier_path.png"));
93 
95  ok_Button->setEnabled(false);
96 
97  FillComboBoxPoints(ui->comboBoxPoint);
98 
99  int index = ui->lineType_ComboBox->findData(LineTypeNone);
100  if (index != -1)
101  {
102  ui->lineType_ComboBox->removeItem(index);
103  }
104 
105  index = ui->lineColor_ComboBox->findData(qApp->getCurrentDocument()->getDefaultLineColor());
106  if (index != -1)
107  {
108  ui->lineColor_ComboBox->setCurrentIndex(index);
109  }
110 
111  index = ui->lineWeight_ComboBox->findData(qApp->getCurrentDocument()->getDefaultLineWeight());
112  if (index != -1)
113  {
114  ui->lineWeight_ComboBox->setCurrentIndex(index);
115  }
116 
117  index = ui->lineType_ComboBox->findData(qApp->getCurrentDocument()->getDefaultLineType());
118  if (index != -1)
119  {
120  ui->lineType_ComboBox->setCurrentIndex(index);
121  }
122 
123  connect(ui->listWidget, &QListWidget::currentRowChanged, this, &DialogCubicBezierPath::PointChanged);
124  connect(ui->comboBoxPoint, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
126 
128 }
129 
130 //---------------------------------------------------------------------------------------------------------------------
132 {
133  delete ui;
134 }
135 
136 //---------------------------------------------------------------------------------------------------------------------
138 {
139  return path;
140 }
141 
142 //---------------------------------------------------------------------------------------------------------------------
144 {
145  this->path = value;
146  ui->listWidget->blockSignals(true);
147  ui->listWidget->clear();
148  for (qint32 i = 0; i < path.CountPoints(); ++i)
149  {
150  NewItem(path.at(i));
151  }
152  ui->listWidget->setFocus(Qt::OtherFocusReason);
153  ui->lineEditSplPathName->setText(qApp->TrVars()->VarToUser(path.name()));
154 
155  auto visPath = qobject_cast<VisToolCubicBezierPath *>(vis);
156  SCASSERT(visPath != nullptr)
157  visPath->setPath(path);
158  ui->listWidget->blockSignals(false);
159 
160  if (ui->listWidget->count() > 0)
161  {
162  ui->listWidget->setCurrentRow(0);
163  }
164 }
165 
166 //---------------------------------------------------------------------------------------------------------------------
168 {
169  return GetComboBoxCurrentData(ui->lineType_ComboBox, LineTypeSolidLine);
170 }
171 
172 //---------------------------------------------------------------------------------------------------------------------
173 void DialogCubicBezierPath::setPenStyle(const QString &value)
174 {
175  ChangeCurrentData(ui->lineType_ComboBox, value);
176 }
177 
178 //---------------------------------------------------------------------------------------------------------------------
179 /**
180  * @brief getLineWeight return weight of the lines
181  * @return type
182  */
184 {
185  return GetComboBoxCurrentData(ui->lineWeight_ComboBox, "0.35");
186 }
187 
188 //---------------------------------------------------------------------------------------------------------------------
189 /**
190  * @brief setLineWeight set weight of the lines
191  * @param value type
192  */
193 void DialogCubicBezierPath::setLineWeight(const QString &value)
194 {
195  ChangeCurrentData(ui->lineWeight_ComboBox, value);
196 }
197 
198 //---------------------------------------------------------------------------------------------------------------------
200 {
201  return GetComboBoxCurrentData(ui->lineColor_ComboBox, ColorBlack);
202 }
203 
204 //---------------------------------------------------------------------------------------------------------------------
205 void DialogCubicBezierPath::setLineColor(const QString &value)
206 {
207  ChangeCurrentData(ui->lineColor_ComboBox, value);
208 }
209 
210 //---------------------------------------------------------------------------------------------------------------------
212 {
213  if (type == SceneObject::Point)
214  {
215  if (AllPathBackboneIds().contains(id))
216  {
217  return;
218  }
219 
220  const auto point = data->GeometricObject<VPointF>(id);
221  NewItem(*point);
222 
223  SavePath();
224 
225  auto visPath = qobject_cast<VisToolCubicBezierPath *>(vis);
226  SCASSERT(visPath != nullptr)
227  visPath->setPath(path);
228 
229  if (path.CountPoints() == 1)
230  {
231  visPath->VisualMode(NULL_ID);
232  VAbstractMainWindow *window = qobject_cast<VAbstractMainWindow *>(qApp->getMainWindow());
233  SCASSERT(window != nullptr)
235  }
236  else
237  {
238  visPath->RefreshGeometry();
239  }
240  }
241 }
242 
243 //---------------------------------------------------------------------------------------------------------------------
245 {
246  if (click == false)
247  {
248  const int size = path.CountPoints();
249  if (size >= 7)
250  {
252  {// Accept only if all subpaths are completed
253  emit ToolTip("");
254 
255  if (not data->IsUnique(path.name()))
256  {
258  }
259 
260  DialogAccepted();
261  }
262  }
263  }
264 }
265 
266 //---------------------------------------------------------------------------------------------------------------------
268 {
269  AddVisualization<VisToolCubicBezierPath>();
270 }
271 
272 //---------------------------------------------------------------------------------------------------------------------
274 {
275  const quint32 d = path.GetDuplicate();//Save previous value
276  SavePath();
277  newDuplicate <= -1 ? path.SetDuplicate(d) : path.SetDuplicate(static_cast<quint32>(newDuplicate));
278 
279  auto visPath = qobject_cast<VisToolCubicBezierPath *>(vis);
280  SCASSERT(visPath != nullptr)
281  visPath->setPath(path);
282  visPath->SetMode(Mode::Show);
283  visPath->RefreshGeometry();
284 }
285 
286 //---------------------------------------------------------------------------------------------------------------------
288 {
289  if (ui->listWidget->count() == 0)
290  {
291  return;
292  }
293 
294  const auto p = qvariant_cast<VPointF>(ui->listWidget->item(row)->data(Qt::UserRole));
295  DataPoint(p);
296 }
297 
298 //---------------------------------------------------------------------------------------------------------------------
300 {
301  const quint32 id = qvariant_cast<quint32>(ui->comboBoxPoint->itemData(index));
302  QListWidgetItem *item = ui->listWidget->item( ui->listWidget->currentRow() );
303  const auto point = data->GeometricObject<VPointF>(id);
304  DataPoint(*point);
305  item->setData(Qt::UserRole, QVariant::fromValue(*point));
306 
307  QColor color = okColor;
308  if (not IsPathValid())
309  {
310  flagError = false;
311  color = errorColor;
312 
313  ui->lineEditSplPathName->setText(tr("Invalid spline path"));
314  }
315  else
316  {
317  flagError = true;
318  color = okColor;
319 
320  auto first = qvariant_cast<VPointF>(ui->listWidget->item(0)->data(Qt::UserRole));
321  auto last = qvariant_cast<VPointF>(ui->listWidget->item(ui->listWidget->count()-1)->data(Qt::UserRole));
322 
323  if (first.id() == path.at(0).id() && last.id() == path.at(path.CountPoints()-1).id())
324  {
325  newDuplicate = -1;
326  ui->lineEditSplPathName->setText(qApp->TrVars()->VarToUser(path.name()));
327  }
328  else
329  {
330  VCubicBezierPath newPath = ExtractPath();
331 
332  if (not data->IsUnique(newPath.name()))
333  {
334  newDuplicate = static_cast<qint32>(DNumber(newPath.name()));
335  newPath.SetDuplicate(static_cast<quint32>(newDuplicate));
336  }
337 
338  ui->lineEditSplPathName->setText(qApp->TrVars()->VarToUser(newPath.name()));
339  }
340  }
341  ChangeColor(ui->name_Label, color);
342  ChangeColor(ui->point_Label, color);
343  CheckState();
344 }
345 
346 //---------------------------------------------------------------------------------------------------------------------
348 {
349  auto item = new QListWidgetItem(point.name());
350  item->setData(Qt::UserRole, QVariant::fromValue(point));
351 
352  ui->listWidget->addItem(item);
353  ui->listWidget->setCurrentItem(item);
354  if (ui->listWidget->count() >= 7)
355  {
356  ok_Button = ui->buttonBox->button(QDialogButtonBox::Ok);
357  ok_Button->setEnabled(true);
358  }
359 
360  DataPoint(point);
361 }
362 
363 //---------------------------------------------------------------------------------------------------------------------
365 {
366  ui->comboBoxPoint->blockSignals(true);
367  ChangeCurrentData(ui->comboBoxPoint, p.id());
368  ui->comboBoxPoint->blockSignals(false);
369 }
370 
371 //---------------------------------------------------------------------------------------------------------------------
373 {
374  path.Clear();
375  path = ExtractPath();
376 }
377 
378 //---------------------------------------------------------------------------------------------------------------------
380 {
381  QVector<quint32> points;
382  for (qint32 i = 0; i < ui->listWidget->count(); ++i)
383  {
384  points.append(qvariant_cast<VPointF>(ui->listWidget->item(i)->data(Qt::UserRole)).id());
385  }
386 
387  QSet<quint32> ids;
388  const qint32 count = VCubicBezierPath::CountSubSpl(points.size());// Count subpaths
389  for (qint32 i = 1; i <= count; ++i)
390  {
391  const qint32 base = VCubicBezierPath::SubSplOffset(i);
392  ids.insert(points.at(base));// The first subpath's point
393  ids.insert(points.at(base + 3));// The last subpath's point
394  }
395 
396  return ids;
397 }
398 
399 //---------------------------------------------------------------------------------------------------------------------
401 {
402  if (path.CountPoints() < 7)
403  {
404  return false;
405  }
406 
407  return (AllPathBackboneIds().size() == path.CountSubSpl() + 1);
408 }
409 
410 //---------------------------------------------------------------------------------------------------------------------
412 {
413  QVector<VPointF> points;
414  for (qint32 i = 0; i < ui->listWidget->count(); ++i)
415  {
416  points.append(qvariant_cast<VPointF>(ui->listWidget->item(i)->data(Qt::UserRole)));
417  }
418  return VCubicBezierPath(points);
419 }
void setPenStyle(const QString &value)
VCubicBezierPath ExtractPath() const
virtual void ShowVisualization() Q_DECL_OVERRIDE
void setLineWeight(const QString &value)
setLineWeight set weight of the lines
virtual void SaveData() Q_DECL_OVERRIDE
SaveData Put dialog data in local variables.
virtual void ChosenObject(quint32 id, const SceneObject &type) Q_DECL_OVERRIDE
VCubicBezierPath path
path cubic bezier path
void SetPath(const VCubicBezierPath &value)
QSet< quint32 > AllPathBackboneIds() const
QString getLineWeight() const
getLineWeight return weight of the lines
void NewItem(const VPointF &point)
VCubicBezierPath GetPath() const
void setLineColor(const QString &value)
DialogCubicBezierPath(const VContainer *data, const quint32 &toolId, QWidget *parent=nullptr)
virtual void ShowDialog(bool click) Q_DECL_OVERRIDE
void DataPoint(const VPointF &p)
Ui::DialogCubicBezierPath * ui
The DialogTool class parent for all dialog of tools.
Definition: dialogtool.h:107
void ChangeCurrentData(QComboBox *box, const QVariant &value) const
ChangeCurrentData select item in combobox by id.
Definition: dialogtool.cpp:419
quint32 DNumber(const QString &baseName) const
Definition: dialogtool.cpp:476
const QColor okColor
Definition: dialogtool.h:219
void ToolTip(const QString &toolTip)
ToolTip emit tooltipe for tool.
virtual void CheckState()
CheckState enable, when all is correct, or disable, when something wrong, button ok.
void FillComboBoxPoints(QComboBox *box, FillComboBox rule=FillComboBox::Whole, const quint32 &ch1=NULL_ID, const quint32 &ch2=NULL_ID) const
FillComboBoxPoints fill comboBox list of points.
Definition: dialogtool.cpp:242
QPushButton * ok_Button
ok_Button button ok
Definition: dialogtool.h:199
const QColor errorColor
Definition: dialogtool.h:220
virtual void DialogAccepted()
DialogAccepted save data and emit signal about closed dialog.
void initializeOkCancelApply(T *ui)
initializeOkCancelApply initialize OK / Cancel and Apply buttons
Definition: dialogtool.h:365
bool flagError
flagError use this flag if for you do not enought
Definition: dialogtool.h:193
const VContainer * data
data container with data
Definition: dialogtool.h:177
QString GetComboBoxCurrentData(const QComboBox *box, const QString &def) const
Definition: dialogtool.cpp:400
QPointer< Visualization > vis
Definition: dialogtool.h:236
void ChangeColor(QWidget *widget, const QColor &color)
void SetDuplicate(quint32 number)
quint32 GetDuplicate() const
virtual void ShowToolTip(const QString &toolTip)=0
The VContainer class container of all variables.
Definition: vcontainer.h:141
static bool IsUnique(const QString &name)
Definition: vcontainer.cpp:585
const QSharedPointer< T > GeometricObject(const quint32 &id) const
Definition: vcontainer.h:266
static qint32 SubSplPointsCount(qint32 countSubSpl)
virtual qint32 CountPoints() const Q_DECL_OVERRIDE
virtual qint32 CountSubSpl() const Q_DECL_OVERRIDE
const VPointF & at(int indx) const
virtual void Clear() Q_DECL_OVERRIDE
static qint32 SubSplOffset(qint32 subSplIndex)
virtual QString name() const
name return name graphical object.
Definition: vgobject.cpp:148
quint32 id() const
id return id object.
Definition: vgobject.cpp:205
The VPointF class keep data of point.
Definition: vpointf.h:75
void ToolTip(const QString &toolTip)
#define SCASSERT(cond)
Definition: def.h:317
SceneObject
Definition: def.h:103
const QString LineTypeSolidLine
Definition: ifcdef.cpp:159
const QString ColorBlack
Definition: ifcdef.cpp:373
const QString LineTypeNone
Definition: ifcdef.cpp:158
#define NULL_ID
Definition: ifcdef.h:76
#define qApp
Definition: vapplication.h:67