diff --git a/libs/image/brushengine/kis_paintop_settings.cpp b/libs/image/brushengine/kis_paintop_settings.cpp index e2da9fcc34..f051704aad 100644 --- a/libs/image/brushengine/kis_paintop_settings.cpp +++ b/libs/image/brushengine/kis_paintop_settings.cpp @@ -1,524 +1,527 @@ /* * Copyright (c) 2007 Boudewijn Rempt * Copyright (c) 2008 Lukáš Tvrdý * Copyright (c) 2014 Mohit Goyal * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include "kis_paintop_preset.h" #include "kis_paint_layer.h" #include "kis_image.h" #include "kis_painter.h" #include "kis_paint_device.h" #include "kis_paintop_registry.h" #include "kis_timing_information.h" #include #include "kis_paintop_config_widget.h" #include #include "kis_paintop_settings_update_proxy.h" #include #include #include #include #include #include "KisPaintopSettingsIds.h" #include "kis_algebra_2d.h" struct Q_DECL_HIDDEN KisPaintOpSettings::Private { Private() : disableDirtyNotifications(false) {} QPointer settingsWidget; QString modelName; QPointer updateProxy; QList uniformProperties; KisResourcesInterfaceSP resourcesInterface = 0; bool disableDirtyNotifications; class DirtyNotificationsLocker { public: DirtyNotificationsLocker(KisPaintOpSettings::Private *d) : m_d(d), m_oldNotificationsState(d->disableDirtyNotifications) { m_d->disableDirtyNotifications = true; } ~DirtyNotificationsLocker() { m_d->disableDirtyNotifications = m_oldNotificationsState; } private: KisPaintOpSettings::Private *m_d; bool m_oldNotificationsState; Q_DISABLE_COPY(DirtyNotificationsLocker) }; }; KisPaintOpSettings::KisPaintOpSettings(KisResourcesInterfaceSP resourcesInterface) : d(new Private) { d->updateProxy = 0; d->resourcesInterface = resourcesInterface; } KisPaintOpSettings::~KisPaintOpSettings() { } KisPaintOpSettings::KisPaintOpSettings(const KisPaintOpSettings &rhs) : KisPropertiesConfiguration(rhs) , d(new Private) { d->settingsWidget = 0; d->updateProxy = rhs.updateProxy(); d->modelName = rhs.modelName(); d->resourcesInterface = rhs.d->resourcesInterface; } void KisPaintOpSettings::setOptionsWidget(KisPaintOpConfigWidget* widget) { d->settingsWidget = widget; } void KisPaintOpSettings::setUpdateProxy(const QPointer proxy) { d->updateProxy = proxy; } QPointer KisPaintOpSettings::updateProxy() const { return d->updateProxy; } bool KisPaintOpSettings::mousePressEvent(const KisPaintInformation &paintInformation, Qt::KeyboardModifiers modifiers, KisNodeWSP currentNode) { Q_UNUSED(modifiers); Q_UNUSED(currentNode); setRandomOffset(paintInformation); return true; // ignore the event by default } bool KisPaintOpSettings::mouseReleaseEvent() { return true; // ignore the event by default } void KisPaintOpSettings::setRandomOffset(const KisPaintInformation &paintInformation) { bool disableDirtyBefore = d->disableDirtyNotifications; d->disableDirtyNotifications = true; if (getBool("Texture/Pattern/Enabled")) { if (getBool("Texture/Pattern/isRandomOffsetX")) { setProperty("Texture/Pattern/OffsetX", paintInformation.randomSource()->generate(0, KisPropertiesConfiguration::getInt("Texture/Pattern/MaximumOffsetX"))); } if (getBool("Texture/Pattern/isRandomOffsetY")) { setProperty("Texture/Pattern/OffsetY", paintInformation.randomSource()->generate(0, KisPropertiesConfiguration::getInt("Texture/Pattern/MaximumOffsetY"))); } } d->disableDirtyNotifications = disableDirtyBefore; } bool KisPaintOpSettings::hasMaskingSettings() const { return getBool(KisPaintOpUtils::MaskingBrushEnabledTag, false); } KisPaintOpSettingsSP KisPaintOpSettings::createMaskingSettings() const { if (!hasMaskingSettings()) return KisPaintOpSettingsSP(); const KoID pixelBrushId(KisPaintOpUtils::MaskingBrushPaintOpId, QString()); KisPaintOpSettingsSP maskingSettings = KisPaintOpRegistry::instance()->createSettings(pixelBrushId, resourcesInterface()); this->getPrefixedProperties(KisPaintOpUtils::MaskingBrushPresetPrefix, maskingSettings); const bool useMasterSize = this->getBool(KisPaintOpUtils::MaskingBrushUseMasterSizeTag, true); if (useMasterSize) { const qreal masterSizeCoeff = getDouble(KisPaintOpUtils::MaskingBrushMasterSizeCoeffTag, 1.0); - maskingSettings->setPaintOpSize(masterSizeCoeff * paintOpSize()); + int newSize = masterSizeCoeff * paintOpSize(); + if (newSize > 1000) + newSize = 1000; + maskingSettings->setPaintOpSize(newSize); } return maskingSettings; } bool KisPaintOpSettings::hasPatternSettings() const { return false; } QString KisPaintOpSettings::maskingBrushCompositeOp() const { return getString(KisPaintOpUtils::MaskingBrushCompositeOpTag, COMPOSITE_MULT); } KisResourcesInterfaceSP KisPaintOpSettings::resourcesInterface() const { return d->resourcesInterface; } void KisPaintOpSettings::setResourcesInterface(KisResourcesInterfaceSP resourcesInterface) { d->resourcesInterface = resourcesInterface; } KisPaintOpSettingsSP KisPaintOpSettings::clone() const { QString paintopID = getString("paintop"); if (paintopID.isEmpty()) return 0; KisPaintOpSettingsSP settings = KisPaintOpRegistry::instance()->createSettings(KoID(paintopID), resourcesInterface()); QMapIterator i(getProperties()); while (i.hasNext()) { i.next(); settings->setProperty(i.key(), QVariant(i.value())); } settings->setUpdateProxy(this->updateProxy()); return settings; } void KisPaintOpSettings::resetSettings(const QStringList &preserveProperties) { QStringList allKeys = preserveProperties; allKeys << "paintop"; QHash preserved; Q_FOREACH (const QString &key, allKeys) { if (hasProperty(key)) { preserved[key] = getProperty(key); } } clearProperties(); for (auto it = preserved.constBegin(); it != preserved.constEnd(); ++it) { setProperty(it.key(), it.value()); } } void KisPaintOpSettings::activate() { } void KisPaintOpSettings::setPaintOpOpacity(qreal value) { KisLockedPropertiesProxySP proxy( KisLockedPropertiesServer::instance()->createLockedPropertiesProxy(this)); proxy->setProperty("OpacityValue", value); } void KisPaintOpSettings::setPaintOpFlow(qreal value) { KisLockedPropertiesProxySP proxy( KisLockedPropertiesServer::instance()->createLockedPropertiesProxy(this)); proxy->setProperty("FlowValue", value); } void KisPaintOpSettings::setPaintOpCompositeOp(const QString &value) { KisLockedPropertiesProxySP proxy( KisLockedPropertiesServer::instance()->createLockedPropertiesProxy(this)); proxy->setProperty("CompositeOp", value); } qreal KisPaintOpSettings::paintOpOpacity() { KisLockedPropertiesProxySP proxy = KisLockedPropertiesServer::instance()->createLockedPropertiesProxy(this); return proxy->getDouble("OpacityValue", 1.0); } qreal KisPaintOpSettings::paintOpFlow() { KisLockedPropertiesProxySP proxy( KisLockedPropertiesServer::instance()->createLockedPropertiesProxy(this)); return proxy->getDouble("FlowValue", 1.0); } qreal KisPaintOpSettings::paintOpPatternSize() { KisLockedPropertiesProxySP proxy( KisLockedPropertiesServer::instance()->createLockedPropertiesProxy(this)); return proxy->getDouble("Texture/Pattern/Scale", 0.5); } QString KisPaintOpSettings::paintOpCompositeOp() { KisLockedPropertiesProxySP proxy( KisLockedPropertiesServer::instance()->createLockedPropertiesProxy(this)); return proxy->getString("CompositeOp", COMPOSITE_OVER); } void KisPaintOpSettings::setEraserMode(bool value) { KisLockedPropertiesProxySP proxy( KisLockedPropertiesServer::instance()->createLockedPropertiesProxy(this)); proxy->setProperty("EraserMode", value); } bool KisPaintOpSettings::eraserMode() { KisLockedPropertiesProxySP proxy( KisLockedPropertiesServer::instance()->createLockedPropertiesProxy(this)); return proxy->getBool("EraserMode", false); } QString KisPaintOpSettings::effectivePaintOpCompositeOp() { return !eraserMode() ? paintOpCompositeOp() : COMPOSITE_ERASE; } qreal KisPaintOpSettings::savedEraserSize() const { return getDouble("SavedEraserSize", 0.0); } void KisPaintOpSettings::setSavedEraserSize(qreal value) { setProperty("SavedEraserSize", value); setPropertyNotSaved("SavedEraserSize"); } qreal KisPaintOpSettings::savedBrushSize() const { return getDouble("SavedBrushSize", 0.0); } void KisPaintOpSettings::setSavedBrushSize(qreal value) { setProperty("SavedBrushSize", value); setPropertyNotSaved("SavedBrushSize"); } qreal KisPaintOpSettings::savedEraserOpacity() const { return getDouble("SavedEraserOpacity", 0.0); } void KisPaintOpSettings::setSavedEraserOpacity(qreal value) { setProperty("SavedEraserOpacity", value); setPropertyNotSaved("SavedEraserOpacity"); } qreal KisPaintOpSettings::savedBrushOpacity() const { return getDouble("SavedBrushOpacity", 0.0); } void KisPaintOpSettings::setSavedBrushOpacity(qreal value) { setProperty("SavedBrushOpacity", value); setPropertyNotSaved("SavedBrushOpacity"); } QString KisPaintOpSettings::modelName() const { return d->modelName; } void KisPaintOpSettings::setModelName(const QString & modelName) { d->modelName = modelName; } KisPaintOpConfigWidget* KisPaintOpSettings::optionsWidget() const { if (d->settingsWidget.isNull()) return 0; return d->settingsWidget.data(); } bool KisPaintOpSettings::isValid() const { return true; } QString KisPaintOpSettings::indirectPaintingCompositeOp() const { return COMPOSITE_ALPHA_DARKEN; } bool KisPaintOpSettings::isAirbrushing() const { return getBool(AIRBRUSH_ENABLED, false); } qreal KisPaintOpSettings::airbrushInterval() const { qreal rate = getDouble(AIRBRUSH_RATE, 1.0); if (rate == 0.0) { return LONG_TIME; } else { return 1000.0 / rate; } } bool KisPaintOpSettings::useSpacingUpdates() const { return getBool(SPACING_USE_UPDATES, false); } bool KisPaintOpSettings::needsAsynchronousUpdates() const { return false; } QPainterPath KisPaintOpSettings::brushOutline(const KisPaintInformation &info, const OutlineMode &mode, qreal alignForZoom) { QPainterPath path; if (mode.isVisible) { path = ellipseOutline(10, 10, 1.0, 0); if (mode.showTiltDecoration) { path.addPath(makeTiltIndicator(info, QPointF(0.0, 0.0), 0.0, 2.0)); } path.translate(KisAlgebra2D::alignForZoom(info.pos(), alignForZoom)); } return path; } QPainterPath KisPaintOpSettings::ellipseOutline(qreal width, qreal height, qreal scale, qreal rotation) { QPainterPath path; QRectF ellipse(0, 0, width * scale, height * scale); ellipse.translate(-ellipse.center()); path.addEllipse(ellipse); QTransform m; m.reset(); m.rotate(rotation); path = m.map(path); return path; } QPainterPath KisPaintOpSettings::makeTiltIndicator(KisPaintInformation const& info, QPointF const& start, qreal maxLength, qreal angle) { if (maxLength == 0.0) maxLength = 50.0; maxLength = qMax(maxLength, 50.0); qreal const length = maxLength * (1 - info.tiltElevation(info, 60.0, 60.0, true)); qreal const baseAngle = 360.0 - fmod(KisPaintInformation::tiltDirection(info, true) * 360.0 + 270.0, 360.0); QLineF guideLine = QLineF::fromPolar(length, baseAngle + angle); guideLine.translate(start); QPainterPath ret; ret.moveTo(guideLine.p1()); ret.lineTo(guideLine.p2()); guideLine.setAngle(baseAngle - angle); ret.lineTo(guideLine.p2()); ret.lineTo(guideLine.p1()); return ret; } void KisPaintOpSettings::setProperty(const QString & name, const QVariant & value) { if (value != KisPropertiesConfiguration::getProperty(name) && !d->disableDirtyNotifications) { if (d->updateProxy) { d->updateProxy->setDirty(true); } } KisPropertiesConfiguration::setProperty(name, value); onPropertyChanged(); } void KisPaintOpSettings::onPropertyChanged() { if (d->updateProxy) { d->updateProxy->notifySettingsChanged(); } } bool KisPaintOpSettings::isLodUserAllowed(const KisPropertiesConfigurationSP config) { return config->getBool("lodUserAllowed", true); } void KisPaintOpSettings::setLodUserAllowed(KisPropertiesConfigurationSP config, bool value) { config->setProperty("lodUserAllowed", value); } bool KisPaintOpSettings::lodSizeThresholdSupported() const { return true; } qreal KisPaintOpSettings::lodSizeThreshold() const { return getDouble("lodSizeThreshold", 100.0); } void KisPaintOpSettings::setLodSizeThreshold(qreal value) { setProperty("lodSizeThreshold", value); } #include "kis_standard_uniform_properties_factory.h" QList KisPaintOpSettings::uniformProperties(KisPaintOpSettingsSP settings) { QList props = listWeakToStrong(d->uniformProperties); if (props.isEmpty()) { using namespace KisStandardUniformPropertiesFactory; props.append(createProperty(opacity, settings, d->updateProxy)); props.append(createProperty(size, settings, d->updateProxy)); props.append(createProperty(flow, settings, d->updateProxy)); d->uniformProperties = listStrongToWeak(props); } return props; } diff --git a/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp b/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp index f1bfb917b7..085f9f892d 100644 --- a/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp +++ b/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp @@ -1,130 +1,140 @@ /* * Copyright (c) 2017 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "KisMaskingBrushOption.h" #include "kis_brush_chooser.h" #include "kis_brush_selection_widget.h" #include #include #include #include #include #include "kis_brush.h" #include "kis_image.h" #include "kis_brush_option.h" #include "KisMaskingBrushOptionProperties.h" #include #include #include struct KisMaskingBrushOption::Private { Private() : ui(new QWidget()) { QVBoxLayout *l = new QVBoxLayout(); QHBoxLayout *compositeOpLayout = new QHBoxLayout(); compositeSelector = new QComboBox(ui.data()); const QStringList supportedComposites = KisMaskingBrushCompositeOpFactory::supportedCompositeOpIds(); Q_FOREACH (const QString &id, supportedComposites) { const QString name = KoCompositeOpRegistry::instance().getKoID(id).name(); compositeSelector->addItem(name, id); } compositeSelector->setCurrentIndex(0); compositeOpLayout->addWidget(new QLabel(i18n("Blending Mode:")), 0); compositeOpLayout->addWidget(compositeSelector, 1); l->addLayout(compositeOpLayout, 0); brushChooser = new KisBrushSelectionWidget(ui.data()); l->addWidget(brushChooser, 1); ui->setLayout(l); } QScopedPointer ui; KisBrushSelectionWidget *brushChooser = 0; QComboBox *compositeSelector = 0; MasterBrushSizeAdapter masterBrushSizeAdapter; }; KisMaskingBrushOption::KisMaskingBrushOption(MasterBrushSizeAdapter masterBrushSizeAdapter) : KisPaintOpOption(KisPaintOpOption::MASKING_BRUSH, false), m_d(new Private()) { m_d->masterBrushSizeAdapter = masterBrushSizeAdapter; setObjectName("KisMaskingBrushOption"); setConfigurationPage(m_d->ui.data()); connect(m_d->brushChooser, SIGNAL(sigBrushChanged()), SLOT(emitSettingChanged())); connect(m_d->compositeSelector, SIGNAL(currentIndexChanged(int)), SLOT(emitSettingChanged())); } KisMaskingBrushOption::~KisMaskingBrushOption() { } void KisMaskingBrushOption::writeOptionSetting(KisPropertiesConfigurationSP setting) const { KisMaskingBrushOptionProperties props; props.isEnabled = isChecked(); props.brush = m_d->brushChooser->brush(); props.compositeOpId = m_d->compositeSelector->currentData().toString(); + qreal effectiveSize = props.brush->userEffectiveSize(); + + if (effectiveSize > 1000) + props.brush->setUserEffectiveSize(1000); + props.write(setting.data(), m_d->masterBrushSizeAdapter()); } void KisMaskingBrushOption::readOptionSetting(const KisPropertiesConfigurationSP setting) { KisMaskingBrushOptionProperties props; props.read(setting.data(), m_d->masterBrushSizeAdapter(), KisGlobalResourcesInterface::instance()); setChecked(props.isEnabled); const int selectedIndex = qMax(0, m_d->compositeSelector->findData(props.compositeOpId)); m_d->compositeSelector->setCurrentIndex(selectedIndex); if (props.brush) { + qreal effectiveSize = props.brush->userEffectiveSize(); + + if (effectiveSize > 1000) + props.brush->setUserEffectiveSize(1000); + m_d->brushChooser->setCurrentBrush(props.brush); } } void KisMaskingBrushOption::setImage(KisImageWSP image) { m_d->brushChooser->setImage(image); } void KisMaskingBrushOption::lodLimitations(KisPaintopLodLimitations *l) const { KisBrushSP brush = m_d->brushChooser->brush(); if (brush) { brush->lodLimitations(l); } } diff --git a/plugins/paintops/libpaintop/kis_brush_based_paintop_settings.cpp b/plugins/paintops/libpaintop/kis_brush_based_paintop_settings.cpp index 987e043995..e3a40afb49 100644 --- a/plugins/paintops/libpaintop/kis_brush_based_paintop_settings.cpp +++ b/plugins/paintops/libpaintop/kis_brush_based_paintop_settings.cpp @@ -1,343 +1,345 @@ /* * Copyright (c) 2010 Sven Langkamp * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_brush_based_paintop_settings.h" #include #include #include "kis_brush_based_paintop_options_widget.h" #include #include "KisBrushServerProvider.h" #include #include "kis_signals_blocker.h" #include "kis_brush_option.h" #include #include #include struct BrushReader { BrushReader(const KisBrushBasedPaintOpSettings *parent) : m_parent(parent) { m_option.readOptionSetting(m_parent, parent->resourcesInterface()); } KisBrushSP brush() { return m_option.brush(); } const KisBrushBasedPaintOpSettings *m_parent; KisBrushOptionProperties m_option; }; struct BrushWriter { BrushWriter(KisBrushBasedPaintOpSettings *parent) : m_parent(parent) { m_option.readOptionSetting(m_parent, parent->resourcesInterface()); } ~BrushWriter() { m_option.writeOptionSetting(m_parent); } KisBrushSP brush() { return m_option.brush(); } KisBrushBasedPaintOpSettings *m_parent; KisBrushOptionProperties m_option; }; KisBrushBasedPaintOpSettings::KisBrushBasedPaintOpSettings(KisResourcesInterfaceSP resourcesInterface) : KisOutlineGenerationPolicy(KisCurrentOutlineFetcher::SIZE_OPTION | KisCurrentOutlineFetcher::ROTATION_OPTION | KisCurrentOutlineFetcher::MIRROR_OPTION | KisCurrentOutlineFetcher::SHARPNESS_OPTION, resourcesInterface) { } bool KisBrushBasedPaintOpSettings::paintIncremental() { if (hasProperty("PaintOpAction")) { return (enumPaintActionType)getInt("PaintOpAction", WASH) == BUILDUP; } return true; } KisPaintOpSettingsSP KisBrushBasedPaintOpSettings::clone() const { KisPaintOpSettingsSP _settings = KisOutlineGenerationPolicy::clone(); KisBrushBasedPaintOpSettingsSP settings = dynamic_cast(_settings.data()); settings->m_savedBrush = 0; return settings; } KisBrushSP KisBrushBasedPaintOpSettings::brush() const { KisBrushSP brush = m_savedBrush; if (!brush) { BrushReader w(this); brush = w.brush(); m_savedBrush = brush; } return brush; } QPainterPath KisBrushBasedPaintOpSettings::brushOutlineImpl(const KisPaintInformation &info, const OutlineMode &mode, qreal alignForZoom, qreal additionalScale) { QPainterPath path; if (mode.isVisible) { KisBrushSP brush = this->brush(); if (!brush) return path; qreal finalScale = brush->scale() * additionalScale; QPainterPath realOutline = brush->outline(); if (mode.forceCircle) { QPainterPath ellipse; ellipse.addEllipse(realOutline.boundingRect()); realOutline = ellipse; } path = outlineFetcher()->fetchOutline(info, this, realOutline, mode, alignForZoom, finalScale, brush->angle()); if (mode.showTiltDecoration) { const QPainterPath tiltLine = makeTiltIndicator(info, realOutline.boundingRect().center(), realOutline.boundingRect().width() * 0.5, 3.0); path.addPath(outlineFetcher()->fetchOutline(info, this, tiltLine, mode, alignForZoom, finalScale, 0.0, true, realOutline.boundingRect().center().x(), realOutline.boundingRect().center().y())); } } return path; } QPainterPath KisBrushBasedPaintOpSettings::brushOutline(const KisPaintInformation &info, const OutlineMode &mode, qreal alignForZoom) { return brushOutlineImpl(info, mode, alignForZoom, 1.0); } bool KisBrushBasedPaintOpSettings::isValid() const { QStringList files = getStringList(KisPaintOpUtils::RequiredBrushFilesListTag); files << getString(KisPaintOpUtils::RequiredBrushFileTag); Q_FOREACH (const QString &file, files) { if (!file.isEmpty()) { KisBrushSP brush = resourcesInterface()->source(ResourceType::Brushes).resourceForFilename(file); if (!brush) { return false; } } } return true; } void KisBrushBasedPaintOpSettings::setAngle(qreal value) { BrushWriter w(this); if (!w.brush()) return; w.brush()->setAngle(value); } qreal KisBrushBasedPaintOpSettings::angle() { return this->brush()->angle(); } void KisBrushBasedPaintOpSettings::setSpacing(qreal value) { BrushWriter w(this); if (!w.brush()) return; w.brush()->setSpacing(value); } qreal KisBrushBasedPaintOpSettings::spacing() { return this->brush()->spacing(); } void KisBrushBasedPaintOpSettings::setAutoSpacing(bool active, qreal coeff) { BrushWriter w(this); if (!w.brush()) return; w.brush()->setAutoSpacing(active, coeff); } bool KisBrushBasedPaintOpSettings::autoSpacingActive() { return this->brush()->autoSpacingActive(); } qreal KisBrushBasedPaintOpSettings::autoSpacingCoeff() { return this->brush()->autoSpacingCoeff(); } void KisBrushBasedPaintOpSettings::setPaintOpSize(qreal value) { + if (value > 1000) + value = 1000; BrushWriter w(this); if (!w.brush()) return; w.brush()->setUserEffectiveSize(value); } qreal KisBrushBasedPaintOpSettings::paintOpSize() const { return this->brush()->userEffectiveSize(); } #include #include "kis_paintop_preset.h" #include "kis_paintop_settings_update_proxy.h" QList KisBrushBasedPaintOpSettings::uniformProperties(KisPaintOpSettingsSP settings) { QList props = listWeakToStrong(m_uniformProperties); if (props.isEmpty()) { { KisIntSliderBasedPaintOpPropertyCallback *prop = new KisIntSliderBasedPaintOpPropertyCallback( KisIntSliderBasedPaintOpPropertyCallback::Int, "angle", "Angle", settings, 0); prop->setRange(0, 360); prop->setReadCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast(prop->settings().data()); const qreal angleResult = kisRadiansToDegrees(s->angle()); prop->setValue(angleResult); }); prop->setWriteCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast(prop->settings().data()); s->setAngle(kisDegreesToRadians(prop->value().toReal())); }); QObject::connect(updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue())); prop->requestReadValue(); props << toQShared(prop); } { KisUniformPaintOpPropertyCallback *prop = new KisUniformPaintOpPropertyCallback( KisUniformPaintOpPropertyCallback::Bool, "auto_spacing", "Auto Spacing", settings, 0); prop->setReadCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast(prop->settings().data()); prop->setValue(s->autoSpacingActive()); }); prop->setWriteCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast(prop->settings().data()); s->setAutoSpacing(prop->value().toBool(), s->autoSpacingCoeff()); }); QObject::connect(updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue())); prop->requestReadValue(); props << toQShared(prop); } { KisDoubleSliderBasedPaintOpPropertyCallback *prop = new KisDoubleSliderBasedPaintOpPropertyCallback( KisDoubleSliderBasedPaintOpPropertyCallback::Double, "spacing", "Spacing", settings, 0); prop->setRange(0.01, 10); prop->setSingleStep(0.01); prop->setExponentRatio(3.0); prop->setReadCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast(prop->settings().data()); if (s) { const qreal value = s->autoSpacingActive() ? s->autoSpacingCoeff() : s->spacing(); prop->setValue(value); } }); prop->setWriteCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast(prop->settings().data()); if (s) { if (s->autoSpacingActive()) { s->setAutoSpacing(true, prop->value().toReal()); } else { s->setSpacing(prop->value().toReal()); } } }); QObject::connect(updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue())); prop->requestReadValue(); props << toQShared(prop); } } return KisPaintOpSettings::uniformProperties(settings) + props; } void KisBrushBasedPaintOpSettings::onPropertyChanged() { m_savedBrush.clear(); KisOutlineGenerationPolicy::onPropertyChanged(); } bool KisBrushBasedPaintOpSettings::hasPatternSettings() const { return true; } \ No newline at end of file