9 #include <compositeops/KoVcMultiArchBuildSupport.h>
13 #include <ksharedconfig.h>
14 #include <kconfiggroup.h>
17 #include <kis_debug.h>
19 #include <QToolButton>
24 #include <QResizeEvent>
26 #include <kis_fixed_paint_device.h>
27 #include <kis_mask_generator.h>
28 #include <kis_slider_spin_box.h>
29 #include "kis_signals_blocker.h"
30 #include "kis_signal_compressor.h"
31 #include "kis_aspect_ratio_locker.h"
32 #include <KisAngleSelector.h>
35 #define showSlider(input, step) input->setRange(input->minimum(), input->maximum(), step)
36 #include <kis_cubic_curve.h>
41 , m_updateCompressor(new KisSignalCompressor(100, KisSignalCompressor::FIRST_ACTIVE))
42 , m_fadeAspectLocker(new KisAspectRatioLocker())
44 connect(m_updateCompressor.
data(), SIGNAL(timeout()), SLOT(paramChanged()));
46 connect((
QObject*)comboBoxShape, SIGNAL(activated(
int)), m_updateCompressor.
data(), SLOT(start()));
48 inputRadius->setRange(0.01, KSharedConfig::openConfig()->group(
"").readEntry(
"maximumBrushSize", 1000), 2);
49 inputRadius->setExponentRatio(3.0);
50 inputRadius->setSingleStep(1);
51 inputRadius->setValue(5);
52 inputRadius->setSuffix(i18n(
" px"));
53 inputRadius->setBlockUpdateSignalOnDrag(
true);
54 connect(inputRadius, SIGNAL(valueChanged(qreal)), m_updateCompressor.
data(), SLOT(start()));
56 inputRatio->setRange(0.01, 1.0, 2);
57 inputRatio->setSingleStep(0.1);
58 inputRatio->setValue(1.0);
59 inputRatio->setBlockUpdateSignalOnDrag(
true);
60 connect(inputRatio, SIGNAL(valueChanged(qreal)), m_updateCompressor.
data(), SLOT(start()));
62 inputHFade->setRange(0.0, 1.0, 2);
63 inputHFade->setSingleStep(0.1);
64 inputHFade->setValue(0.5);
66 inputVFade->setRange(0.0, 1.0, 2);
67 inputVFade->setSingleStep(0.1);
68 inputVFade->setValue(0.5);
70 aspectButton->setKeepAspectRatio(
true);
72 m_fadeAspectLocker->connectSpinBoxes(inputHFade, inputVFade, aspectButton);
73 m_fadeAspectLocker->setBlockUpdateSignalOnDrag(
true);
74 connect(m_fadeAspectLocker.
data(), SIGNAL(sliderValueChanged()), m_updateCompressor.
data(), SLOT(start()));
75 connect(m_fadeAspectLocker.
data(), SIGNAL(aspectButtonChanged()), m_updateCompressor.
data(), SLOT(start()));
77 inputSpikes->setRange(2, 20);
78 inputSpikes->setValue(2);
79 inputSpikes->setBlockUpdateSignalOnDrag(
true);
80 connect(inputSpikes, SIGNAL(valueChanged(
int)), m_updateCompressor.
data(), SLOT(start()));
82 inputRandomness->setRange(0, 100);
83 inputRandomness->setValue(0);
84 inputRandomness->setBlockUpdateSignalOnDrag(
true);
85 connect(inputRandomness, SIGNAL(valueChanged(qreal)), m_updateCompressor.
data(), SLOT(start()));
87 inputAngle->setDecimals(0);
88 connect(inputAngle, SIGNAL(angleChanged(qreal)), m_updateCompressor.
data(), SLOT(start()));
90 connect(spacingWidget, SIGNAL(sigSpacingChanged()), m_updateCompressor.
data(), SLOT(start()));
92 density->setRange(0, 100, 0);
93 density->setSingleStep(1);
94 density->setValue(100);
95 density->setSuffix(i18n(
"%"));
96 density->setBlockUpdateSignalOnDrag(
true);
97 connect(density, SIGNAL(valueChanged(qreal)), m_updateCompressor.
data(), SLOT(start()));
99 KisCubicCurve topLeftBottomRightLinearCurve;
100 topLeftBottomRightLinearCurve.setPoint(0,
QPointF(0.0, 1.0));
101 topLeftBottomRightLinearCurve.setPoint(1,
QPointF(1.0, 0.0));
103 bool blockedBefore = softnessCurve->blockSignals(
true);
104 softnessCurve->setCurve(topLeftBottomRightLinearCurve);
105 softnessCurve->blockSignals(blockedBefore);
107 connect(softnessCurve, SIGNAL(modified()), m_updateCompressor.
data(), SLOT(start()));
109 m_brush =
QImage(1, 1, QImage::Format_RGB32);
111 connect(brushPreview, SIGNAL(clicked()), m_updateCompressor.
data(), SLOT(start()));
113 QList<KoID> ids = KisMaskGenerator::maskGeneratorIds();
114 for (
int i = 0; i < ids.size(); i++) {
115 comboBoxMaskType->insertItem(i, ids[i].
name());
118 connect(comboBoxMaskType, SIGNAL(activated(
int)), m_updateCompressor.
data(), SLOT(start()));
119 connect(comboBoxMaskType, SIGNAL(currentIndexChanged(
int)), SLOT(setStackedWidget(
int)));
120 setStackedWidget(comboBoxMaskType->currentIndex());
122 brushPreview->setIconSize(
QSize(100, 100));
124 connect(btnAntialiasing, SIGNAL(toggled(
bool)), m_updateCompressor.
data(), SLOT(start()));
126 m_updateCompressor->start();
136 brushPreview->setMinimumHeight(brushPreview->width());
137 brushPreview->setMaximumHeight(brushPreview->width());
142 m_updateCompressor->start();
145 void KisAutoBrushWidget::paramChanged()
147 KisMaskGenerator* kas;
149 bool antialiasEdges = btnAntialiasing->isChecked();
151 if (comboBoxMaskType->currentIndex() == 2) {
152 if (comboBoxShape->currentIndex() == 0) {
153 kas =
new KisGaussCircleMaskGenerator(inputRadius->value(), inputRatio->value(), inputHFade->value(), inputVFade->value(), inputSpikes->value(), antialiasEdges);
156 kas =
new KisGaussRectangleMaskGenerator(inputRadius->value(), inputRatio->value(), inputHFade->value(), inputVFade->value(), inputSpikes->value(), antialiasEdges);
159 else if (comboBoxMaskType->currentIndex() == 1) {
160 if (comboBoxShape->currentIndex() == 0) {
161 kas =
new KisCurveCircleMaskGenerator(inputRadius->value(), inputRatio->value(), inputHFade->value(), inputVFade->value(), inputSpikes->value(), softnessCurve->curve(), antialiasEdges);
164 kas =
new KisCurveRectangleMaskGenerator(inputRadius->value(), inputRatio->value(), inputHFade->value(), inputVFade->value(), inputSpikes->value(), softnessCurve->curve(), antialiasEdges);
168 if (comboBoxShape->currentIndex() == 0) {
169 kas =
new KisCircleMaskGenerator(inputRadius->value(), inputRatio->value(), inputHFade->value(), inputVFade->value(), inputSpikes->value(), antialiasEdges);
172 kas =
new KisRectangleMaskGenerator(inputRadius->value(), inputRatio->value(), inputHFade->value(), inputVFade->value(), inputSpikes->value(), antialiasEdges);
177 m_autoBrush =
KisBrushSP(
new KisAutoBrush(kas, inputAngle->angle() / 180.0 * M_PI, inputRandomness->value() / 100.0, density->value() / 100.0));
178 m_autoBrush->setSpacing(spacingWidget->spacing());
179 m_autoBrush->setAutoSpacing(spacingWidget->autoSpacingActive(), spacingWidget->autoSpacingCoeff());
180 m_brush = m_autoBrush->image();
190 int bPw = brushPreview->width() - 3;
191 if (pi.
width() > bPw) {
192 coeff = bPw / (double)pi.
width();
194 int bPh = brushPreview->height() - 3;
195 if (pi.
height() > coeff * bPh) {
196 coeff = bPh / (double)pi.
height();
199 pi = pi.
scaled((
int)(coeff * pi.
width()) , (
int)(coeff * pi.
height()), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
203 brushPreview->setIcon(
QIcon(p));
206 void KisAutoBrushWidget::setStackedWidget(
int index)
209 stackedWidget->setCurrentIndex(1);
212 stackedWidget->setCurrentIndex(0);
224 m_brush =
brush->image();
226 KisAutoBrush* aBrush = dynamic_cast<KisAutoBrush*>(
brush.
data());
228 KisSignalsBlocker b1(comboBoxShape, comboBoxMaskType);
229 KisSignalsBlocker b2(inputRadius, inputRatio, inputHFade, inputVFade, inputAngle, inputSpikes);
230 KisSignalsBlocker b3(spacingWidget, inputRandomness, density, softnessCurve, btnAntialiasing);
232 if (aBrush->maskGenerator()->type() == KisMaskGenerator::CIRCLE) {
233 comboBoxShape->setCurrentIndex(0);
235 else if (aBrush->maskGenerator()->type() == KisMaskGenerator::RECTANGLE) {
236 comboBoxShape->setCurrentIndex(1);
239 comboBoxShape->setCurrentIndex(2);
242 const int mastTypeIndex = comboBoxMaskType->findText(aBrush->maskGenerator()->name());
243 comboBoxMaskType->setCurrentIndex(mastTypeIndex);
244 setStackedWidget(mastTypeIndex);
246 inputRadius->setValue(aBrush->maskGenerator()->diameter());
247 inputRatio->setValue(aBrush->maskGenerator()->ratio());
248 inputHFade->setValue(aBrush->maskGenerator()->horizontalFade());
249 inputVFade->setValue(aBrush->maskGenerator()->verticalFade());
250 inputAngle->setAngle(aBrush->angle() * 180 / M_PI);
251 inputSpikes->setValue(aBrush->maskGenerator()->spikes());
252 spacingWidget->setSpacing(aBrush->autoSpacingActive(),
253 aBrush->autoSpacingActive() ?
254 aBrush->autoSpacingCoeff() : aBrush->spacing());
255 inputRandomness->setValue(aBrush->randomness() * 100);
256 density->setValue(aBrush->density() * 100);
258 if (!aBrush->maskGenerator()->curveString().isEmpty()) {
260 curve.fromString(aBrush->maskGenerator()->curveString());
261 softnessCurve->setCurve(curve);
264 btnAntialiasing->setChecked(aBrush->maskGenerator()->antialiasEdges());
274 qreal newWidth = inputRadius->value() + dxPixels;
275 newWidth = qMax(newWidth, qreal(0.1));
277 inputRadius->setValue(newWidth);
282 return QSizeF(inputRadius->value(), inputRadius->value() * inputRatio->value());
285 #include "moc_kis_auto_brush_widget.cpp"