27#include <klocalizedstring.h>
29#include <QDoubleSpinBox>
31#include <QStackedWidget>
88 if (!
m_shape && stroke && stroke->isVisible()) {
94 QPointF point =
event->point;
105 if (event->
buttons() & Qt::LeftButton)
127 QPointF point =
event->point;
190 useCursor((stroke && stroke->isVisible()) ? Qt::ArrowCursor : Qt::ForbiddenCursor);
213 qreal angle = atan2(
p2.y() -
p1.y(),
p2.x() -
p1.x());
217 return angle * 180.0 /
M_PI;
235 combineAngle = 0.50f;
242 float lastAngle =
lineAngle(complete[0], complete[1]);
245 for (
uint i = 2; i < pointCount; ++i) {
247 if (qAbs(angle - lastAngle) < combineAngle)
248 complete.removeLast();
265 uint pointCount = points->count();
266 path->moveTo(points->at(0));
267 for (
uint i = 1; i < pointCount; ++i)
268 path->lineTo(points->at(i));
290 QWidget *optionWidget =
new QWidget();
291 QVBoxLayout * layout =
new QVBoxLayout(optionWidget);
293 QHBoxLayout *modeLayout =
new QHBoxLayout;
294 modeLayout->setSpacing(3);
295 QLabel *modeLabel =
new QLabel(i18n(
"Precision:"), optionWidget);
296 QComboBox * modeBox =
new QComboBox(optionWidget);
297 modeBox->addItem(i18nc(
"The raw line data",
"Raw"));
298 modeBox->addItem(i18n(
"Curve"));
299 modeBox->addItem(i18n(
"Straight"));
300 modeLayout->addWidget(modeLabel);
301 modeLayout->addWidget(modeBox, 1);
302 layout->addLayout(modeLayout);
304 QStackedWidget * stackedWidget =
new QStackedWidget(optionWidget);
306 QWidget * rawBox =
new QWidget(stackedWidget);
307 QVBoxLayout * rawLayout =
new QVBoxLayout(rawBox);
308 QCheckBox * optimizeRaw =
new QCheckBox(i18n(
"Optimize"), rawBox);
310 rawLayout->addWidget(optimizeRaw);
311 rawLayout->setContentsMargins(0, 0, 0, 0);
313 QWidget * curveBox =
new QWidget(stackedWidget);
314 QHBoxLayout * curveLayout =
new QHBoxLayout(curveBox);
315 QCheckBox * optimizeCurve =
new QCheckBox(i18n(
"Optimize"), curveBox);
318 fittingError->setSingleStep(0.50);
319 fittingError->setMaximum(400.0);
320 fittingError->setMinimum(0.0);
322 fittingError->setToolTip(i18n(
"Exactness:"));
323 curveLayout->addWidget(optimizeCurve);
324 curveLayout->addWidget(fittingError);
325 curveLayout->setContentsMargins(0, 0, 0, 0);
327 QWidget *straightBox =
new QWidget(stackedWidget);
328 QVBoxLayout *straightLayout =
new QVBoxLayout(straightBox);
330 combineAngle->setSingleStep(0.50);
331 combineAngle->setMaximum(360.0);
332 combineAngle->setMinimum(0.0);
334 combineAngle->setSuffix(
" deg");
337 straightLayout->addWidget(combineAngle);
338 straightLayout->setContentsMargins(0, 0, 0, 0);
340 stackedWidget->addWidget(rawBox);
341 stackedWidget->addWidget(curveBox);
342 stackedWidget->addWidget(straightBox);
343 layout->addWidget(stackedWidget);
344 layout->addStretch(1);
346 connect(modeBox, SIGNAL(activated(
int)), stackedWidget, SLOT(setCurrentIndex(
int)));
347 connect(modeBox, SIGNAL(activated(
int)),
this, SLOT(
selectMode(
int)));
348 connect(optimizeRaw, SIGNAL(stateChanged(
int)),
this, SLOT(
setOptimize(
int)));
349 connect(optimizeCurve, SIGNAL(stateChanged(
int)),
this, SLOT(
setOptimize(
int)));
350 connect(fittingError, SIGNAL(valueChanged(
double)),
this, SLOT(
setDelta(
double)));
351 connect(combineAngle, SIGNAL(valueChanged(
double)),
this, SLOT(
setDelta(
double)));
353 modeBox->setCurrentIndex(
m_mode);
354 stackedWidget->setCurrentIndex(
m_mode);
355 optionWidget->setObjectName(i18n(
"Pencil"));
356 optionWidget->setWindowTitle(i18n(
"Pencil"));
357 widgets.append(optionWidget);
396 if (endShape && startShape != endShape)
457 qreal minDistance = HUGE_VAL;
460 Q_FOREACH(
KoShape * shape, shapes) {
469 uint subpathCount = path->subpathCount();
470 for (
uint i = 0; i < subpathCount; ++i) {
471 if (path->isClosedSubpath(i))
476 if (d < minDistance && d < maxDistance) {
483 if (d < minDistance && d < maxDistance) {
496 if (!pointAtStart && !pointAtEnd)
499 if (pointAtStart == pointAtEnd)
520 pathShape->
combine(startShape);
527 if (endShape != startShape) {
533 bool connectToSingleSubpath = (startShape == endShape && startIndex.first == endIndex.first);
535 if (startIndex.second == 0 && !connectToSingleSubpath) {
539 if (endIndex.second > 0 && !connectToSingleSubpath) {
556 if (existingStartPoint) {
563 if (existingEndPoint) {
KoPathShape * bezierFit(const QList< QPointF > &points, float error)
QPair< int, int > KoPathPointIndex
The KisDoubleParseSpinBox class is a cleverer doubleSpinBox, able to parse arithmetic expressions.
The KisHandlePainterHelper class is a special helper for painting handles around objects....
void setHandleStyle(const KisHandleStyle &style)
static KisHandleStyle & primarySelection(KisHandlePalette palette=KisHandlePalette())
QPointer< KoShapeController > shapeController
virtual KoShapeManager * shapeManager() const =0
virtual const KoViewConverter * viewConverter() const =0
virtual void updateCanvas(const QRectF &rc)=0
virtual void addCommand(KUndo2Command *command)=0
bool isParametricShape() const
Check if object is a parametric shape.
Describe a KoPathPoint by a KoPathShape and its indices.
The undo / redo command for merging two subpath end points.
void redo() override
redo the command
A KoPathPoint represents a point in a path.
KoPathShape * parent() const
Get the path shape the point belongs to.
void paint(KisHandlePainterHelper &handlesHelper, PointTypes types, bool active=true)
The position of a path point within a path shape.
int subpathPointCount(int subpathIndex) const
Returns the number of points in a subpath.
bool reverseSubpath(int subpathIndex)
Reverse subpath.
KoPathPoint * lineTo(const QPointF &p)
Adds a new line segment.
KoPathPoint * moveTo(const QPointF &p)
Starts a new Subpath.
bool moveSubpath(int oldSubpathIndex, int newSubpathIndex)
Moves the position of a subpath within a path.
void paint(QPainter &painter) const override
reimplemented
QRectF boundingRect() const override
reimplemented
int subpathCount() const
Returns the number of subpaths in the path.
KoPathPointIndex pathPointIndex(const KoPathPoint *point) const
Returns the path point index of a given path point.
KoPathPoint * pointByIndex(const KoPathPointIndex &pointIndex) const
Returns the path point specified by a path point index.
int combine(KoPathShape *path)
Combines two path shapes by appending the data of the specified path.
Qt::MouseButtons buttons() const
return buttons pressed (see QMouseEvent::buttons());
Qt::KeyboardModifiers modifiers() const
QPointF point
The point in document coordinates.
QList< KoShape * > shapesAt(const QRectF &rect, bool omitHiddenShapes=true, bool containedMode=false)
QPointF shapeToDocument(const QPointF &point) const
Transforms point from shape coordinates to document coordinates.
virtual KoShapeStrokeModelSP stroke() const
virtual void setStroke(KoShapeStrokeModelSP stroke)
QTransform absoluteTransformation() const
static KisHandlePainterHelper createHandlePainterHelperView(QPainter *painter, KoShape *shape, const KoViewConverter &converter, qreal handleRadius=0.0, int decorationThickness=1)
void setShapeId(const QString &id)
virtual qreal viewToDocumentX(qreal viewX) const
virtual QPointF documentToView(const QPointF &documentPoint) const