13#include <QStackedWidget>
30 m_transformMode(SYMMETRY),
33 m_mirrorVertically(false),
34 m_mirrorHorizontally(false),
36 m_translateRadius(100),
37 m_setupAxesFlag(false),
38 m_addSubbrushesMode(false),
41 , m_randomGenerator(QRandomGenerator::global()->generate())
178 const qreal axesAngle = 360.0 / float(axesCount);
179 float currentAngle = 0.0;
180 const float startingInsetLength = 20;
183 for(
int i=0; i < axesCount; i++) {
185 currentAngle = i*axesAngle;
188 currentAngle = currentAngle * 0.017453 +
m_angle;
190 const QPoint startingSpot = QPoint(
m_axesPoint.x()+ (sin(currentAngle)*startingInsetLength),
m_axesPoint.y()- (cos(currentAngle))*startingInsetLength );
191 path.moveTo(startingSpot.x(), startingSpot.y());
192 QPointF symmetryLinePoint(
m_axesPoint.x()+ (sin(currentAngle)*axisLength),
m_axesPoint.y()- (cos(currentAngle))*axisLength );
193 path.lineTo(symmetryLinePoint);
211 const int ellipsePreviewSize = 10;
213 path.addEllipse(
m_axesPoint.x()-(ellipsePreviewSize),
215 ellipsePreviewSize*2,
216 ellipsePreviewSize*2);
219 path.addEllipse(dPos, ellipsePreviewSize, ellipsePreviewSize);
230 const int ellipsePreviewSize = 10;
233 path.addEllipse(dPos, ellipsePreviewSize, ellipsePreviewSize);
253 path.addEllipse(dPos, 10, 10);
264 outlinePen.setColor(QColor(100,100,100,150));
265 outlinePen.setStyle(Qt::PenStyle::SolidLine);
266 gc.setPen(outlinePen);
274 QPainterPath dotPath;
275 const int dotRadius = 4;
277 dotPath.addEllipse(
m_axesPoint.x()- dotRadius*0.25,
m_axesPoint.y()- dotRadius*0.25, dotRadius, dotRadius);
280 fillBrush.setColor(QColor(255, 255, 255, 255));
281 fillBrush.setStyle(Qt::SolidPattern);
286 dotPath = QPainterPath();
287 dotPath.addEllipse(
m_axesPoint.x() - dotRadius*0.75,
m_axesPoint.y()- dotRadius*0.75, dotRadius, dotRadius);
288 fillBrush.setColor(QColor(120, 120, 120, 255));
305 m.rotateRadians(angle);
308 transformations << m;
314 transformations << m;
322 transformations << m;
332 transformations << m;
342 transformations << m;
355 m.rotateRadians(
m_angle-angleStep);
356 m.rotateRadians(angle);
358 m.rotateRadians(-
m_angle+angleStep);
361 transformations << m;
363 angle += angleStep*2;
366 m.rotateRadians(
m_angle-angleStep);
367 m.rotateRadians(angle);
368 m.rotateRadians(-
m_angle+angleStep);
371 transformations << m;
373 angle += angleStep*2;
395 transformations << m;
399 transformations << m;
402 m.translate(resPos.x(), resPos.y());
403 transformations << m;
412 const QPoint dPos =
bounds.topLeft() +
417 const QPointF resPos = pos - dPos;
418 m.translate(resPos.x(), resPos.y());
419 transformations << m;
435 customUI->smoothingOptionsLayout->addWidget(widget);
444 customUI->moveOriginButton->setCheckable(
true);
450 customUI->multihandTypeCombobox->addItem(i18nc(
"Label of Mirror in Multihand brush tool options",
"Mirror"),
int(
MIRROR));
459 customUI->axisRotationAngleSelector->setRange(0.0, 90.0);
460 customUI->axisRotationAngleSelector->setDecimals(1);
461 customUI->axisRotationAngleSelector->setWrapping(
false);
474 customUI->horizontalCheckbox->setChecked((
bool)
m_configGroup.readEntry(
"mirrorHorizontally",
false));
480 customUI->translationRadiusSpinbox->setRange(0, 200);
481 customUI->translationRadiusSpinbox->setSuffix(i18n(
" px"));
491 customUI->intervalXSpinBox->setRange(0, 2000);
492 customUI->intervalXSpinBox->setSuffix(i18n(
" px"));
493 customUI->intervalYSpinBox->setRange(0, 2000);
494 customUI->intervalYSpinBox->setSuffix(i18n(
" px"));
504 customUI->intervalAspectButton->setKeepAspectRatio(
m_configGroup.readEntry(
"intervalKeepAspect",
false));
509 return static_cast<QWidget*
>(
customUI);
514 if (
customUI->moveOriginButton->isChecked()){
533 customUI->moveOriginButton->setChecked(
false);
543 if(
customUI->moveOriginButton->isChecked())
546 , QString::number(this->
m_axesPoint.x(),
'f',1),QString::number(this->m_axesPoint.y(),
'f',1))
565 i18n(
"Multibrush Tool does not support more than %1 brushes; use a larger interval.",
604 bool vis = index ==
MIRROR;
605 customUI->horizontalCheckbox->setVisible(vis);
606 customUI->verticalCheckbox->setVisible(vis);
609 customUI->translationRadiusSpinbox->setVisible(vis);
610 customUI->radiusLabel->setVisible(vis);
611 customUI->brushCountSpinBox->setVisible(vis);
612 customUI->brushesLabel->setVisible(vis);
615 customUI->brushCountSpinBox->setVisible(vis);
616 customUI->brushesLabel->setVisible(vis);
619 customUI->subbrushLabel->setVisible(vis);
620 customUI->addSubbrushButton->setVisible(vis);
622 customUI->removeSubbrushButton->setVisible(vis);
625 customUI->intervalXLabel->setVisible(vis);
626 customUI->intervalYLabel->setVisible(vis);
627 customUI->intervalXSpinBox->setVisible(vis);
628 customUI->intervalYSpinBox->setVisible(vis);
629 customUI->intervalAspectButton->setVisible(vis);
633 customUI->moveOriginButton->setVisible(vis);
634 customUI->resetOriginButton->setVisible(vis);
635 customUI->axisRotationLabel->setVisible(vis);
636 customUI->axisRotationAngleSelector->setVisible(vis);
qreal length(const QPointF &vec)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
@ FlipOptionsMode_NoFlipOptions
There is no flip options available.
void connectSpinBoxes(SpinBoxType *spinOne, SpinBoxType *spinTwo, KoAspectButton *aspectButton)
KisImageWSP currentImage() const
void updateCanvas(const QRectF &rc) override
KisViewManager * viewManager() const
static QCursor crossCursor()
QRect bounds() const override
KisSelectionSP selection()
void showFloatingMessage(const QString &message, const QIcon &icon, int timeout=4500, KisFloatingMessage::Priority priority=KisFloatingMessage::Medium, int alignment=Qt::AlignCenter|Qt::TextWordWrap)
shows a floating message in the top right corner of the canvas
QPointer< KoCanvasResourceProvider > resourceManager
QPointF point
The point in document coordinates.
KUndo2MagicString kundo2_i18n(const char *text)
QRect selectedExactRect() const
Slow, but exact way of determining the rectangle that encloses the selection.