11#include <QDomDocument>
13#include <QPainterPath>
48#define SANITY_CHECK_CACHE
50#ifdef SANITY_CHECK_CACHE
56 : disableDirtyNotifications(false)
58 , versionRandomSource(int(reinterpret_cast<
std::intptr_t>(this)))
59 , versionCookie(versionRandomSource.generate())
65 modelName(rhs.modelName),
66 resourcesInterface(rhs.resourcesInterface),
67 canvasResourcesInterface(rhs.canvasResourcesInterface),
68 resourceCacheInterface(rhs.resourceCacheInterface),
69 disableDirtyNotifications(false)
71 , versionRandomSource(int(reinterpret_cast<
std::intptr_t>(this)))
72 , versionCookie(rhs.versionCookie)
90#ifdef SANITY_CHECK_CACHE
99 m_oldNotificationsState(d->disableDirtyNotifications)
101 m_d->disableDirtyNotifications =
true;
105 m_d->disableDirtyNotifications = m_oldNotificationsState;
137 d->updateListener = listener;
142 return d->updateListener;
148 Q_UNUSED(currentNode);
160 bool disableDirtyBefore =
d->disableDirtyNotifications;
161 d->disableDirtyNotifications =
true;
162 if (
getBool(
"Texture/Pattern/Enabled")) {
163 if (
getBool(
"Texture/Pattern/isRandomOffsetX")) {
167 if (
getBool(
"Texture/Pattern/isRandomOffsetY")) {
173 d->disableDirtyNotifications = disableDirtyBefore;
211 maskingSettings->setPaintOpSize(qMin(maxMaskingBrushSize, masterSizeCoeff *
paintOpSize()));
214 if (
d->resourceCacheInterface) {
215 maskingSettings->setResourceCacheInterface(
218 d->resourceCacheInterface)));
221 return maskingSettings;
236 return d->canvasResourcesInterface;
246 d->resourceCacheInterface = cacheInterface;
251 return d->resourceCacheInterface;
264 maskingSettings->regenerateResourceCache(wrappedCacheInterface);
270#ifdef SANITY_CHECK_CACHE
271 return d->versionCookie;
284 return d->resourcesInterface;
294 QString paintopID =
getString(
"paintop");
295 if (paintopID.isEmpty())
300 while (i.hasNext()) {
302 settings->setProperty(i.key(), QVariant(i.value()));
307#ifdef SANITY_CHECK_CACHE
308 settings->
d->versionCookie = this->
d->versionCookie;
317 allKeys <<
"paintop";
319 QHash<QString, QVariant> preserved;
320 Q_FOREACH (
const QString &key, allKeys) {
328 for (
auto it = preserved.constBegin(); it != preserved.constEnd(); ++it) {
342 proxy->setProperty(
"OpacityValue",
value);
350 proxy->setProperty(
"FlowValue",
value);
358 if (!proxy->hasProperty(
"brush_definition"))
return;
362 doc.setContent(proxy->getString(
"brush_definition"));
364 QDomElement element = doc.documentElement();
365 QDomElement elementChild = element.elementsByTagName(
"MaskGenerator").item(0).toElement();
370 proxy->setProperty(
"brush_definition", doc.toString());
378 if (!proxy->hasProperty(
"PressureScatter"))
return;
380 proxy->setProperty(
"ScatterValue",
value);
389 proxy->setProperty(
"CompositeOp",
value);
396 return proxy->getDouble(
"OpacityValue", 1.0);
404 return proxy->getDouble(
"FlowValue", 1.0);
412 if (!proxy->hasProperty(
"brush_definition"))
return 1.0;
415 doc.setContent(proxy->getString(
"brush_definition"));
417 QDomElement element = doc.documentElement();
418 QDomElement elementChild = element.elementsByTagName(
"MaskGenerator").item(0).toElement();
420 if (elementChild.attributeNode(
"hfade").value().toDouble() >= elementChild.attributeNode(
"vfade").value().toDouble()) {
421 return elementChild.attributeNode(
"hfade").value().toDouble();
423 return elementChild.attributeNode(
"vfade").value().toDouble();
433 return proxy->getDouble(
"ScatterValue", 0.0);
442 return proxy->getDouble(
"Texture/Pattern/Scale", 0.5);
458 proxy->setProperty(
"EraserMode",
value);
466 return proxy->getBool(
"EraserMode",
false);
476 return getDouble(
"SavedEraserSize", 0.0);
498 return getDouble(
"SavedEraserOpacity", 0.0);
509 return getDouble(
"SavedBrushOpacity", 0.0);
550 return 1000.0 / rate;
583 QRectF ellipse(0, 0, width * scale, height * scale);
584 ellipse.translate(-ellipse.center());
585 path.addEllipse(ellipse);
595 QPointF
const& start, qreal maxLength, qreal angle)
597 if (maxLength == 0.0) maxLength = 50.0;
598 maxLength = qMax(maxLength, 50.0);
602 QLineF guideLine = QLineF::fromPolar(
length, baseAngle + angle);
603 guideLine.translate(start);
605 ret.moveTo(guideLine.p1());
606 ret.lineTo(guideLine.p2());
607 guideLine.setAngle(baseAngle - angle);
608 ret.lineTo(guideLine.p2());
609 ret.lineTo(guideLine.p1());
631 d->resourceCacheInterface.clear();
633#ifdef SANITY_CHECK_CACHE
634 d->versionCookie =
d->versionRandomSource.generate();
646 return config->getBool(
"lodUserAllowed",
true);
651 config->setProperty(
"lodUserAllowed",
value);
661 return getDouble(
"lodSizeThreshold", 100.0);
677 if (props.isEmpty()) {
680 props.append(createProperty(opacity, settings, updateProxy));
681 props.append(createProperty(size, settings, updateProxy));
682 props.append(createProperty(flow, settings, updateProxy));
qreal length(const QPointF &vec)
float value(const T *src, size_t ch)
const QString COMPOSITE_OVER
const QString COMPOSITE_MULT
const QString COMPOSITE_ERASE
const QString COMPOSITE_ALPHA_DARKEN
int maxMaskingBrushSize() const
static KisLockedPropertiesServer * instance()
KisLockedPropertiesProxySP createLockedPropertiesProxy(KisPropertiesConfiguration *settings)
static KisPaintOpRegistry * instance()
KisPaintOpSettingsSP createSettings(const KoID &id, KisResourcesInterfaceSP resourcesInterface) const
~DirtyNotificationsLocker()
bool m_oldNotificationsState
KisPaintOpSettings::Private * m_d
DirtyNotificationsLocker(KisPaintOpSettings::Private *d)
static bool qFuzzyIsNull(half h)
#define SANITY_CHECK_CACHE
const QString AIRBRUSH_ENABLED
const QString AIRBRUSH_RATE
const QString SPACING_USE_UPDATES
QSharedPointer< T > toQShared(T *ptr)
Container< QSharedPointer< T > > listWeakToStrong(const Container< QWeakPointer< T > > &container, bool allOrNothing=true)
Container< QWeakPointer< T > > listStrongToWeak(const Container< QSharedPointer< T > > &container)
KisPinnedSharedPtr< KisPaintOpSettings > KisPaintOpSettingsSP
QPointF alignForZoom(const QPointF &pt, qreal zoom)
QString toString(const QString &value)
const char MaskingBrushEnabledTag[]
const char MaskingBrushUseMasterSizeTag[]
const char MaskingBrushPaintOpId[]
const char MaskingBrushMasterSizeCoeffTag[]
const char MaskingBrushPresetPrefix[]
const char MaskingBrushCompositeOpTag[]
virtual ~UpdateListener()
virtual void onPropertyChanged()
virtual void regenerateResourceCache(KoResourceCacheInterfaceSP cacheInterface)
void setSavedEraserSize(qreal value)
static QPainterPath makeTiltIndicator(KisPaintInformation const &info, QPointF const &start, qreal lengthScale, qreal angle)
virtual bool isValid() const
virtual QString indirectPaintingCompositeOp() const
qreal savedEraserOpacity() const
QString paintOpCompositeOp()
quint64 sanityVersionCookie() const
virtual void setRandomOffset(const KisPaintInformation &paintInformation)
static void setLodUserAllowed(KisPropertiesConfigurationSP config, bool value)
KisRandomSource versionRandomSource
static bool isLodUserAllowed(const KisPropertiesConfigurationSP config)
virtual qreal paintOpOpacity()
virtual bool needsAsynchronousUpdates() const
void setSavedBrushSize(qreal value)
virtual bool hasPatternSettings() const
qreal savedEraserSize() const
KisResourcesInterfaceSP resourcesInterface
~KisPaintOpSettings() override
static KisOptimizedBrushOutline ellipseOutline(qreal width, qreal height, qreal scale, qreal rotation)
void setCanvasResourcesInterface(KoCanvasResourcesInterfaceSP canvasResourcesInterface)
QString effectivePaintOpCompositeOp()
KisPaintOpSettings(KisResourcesInterfaceSP resourcesInterface)
virtual bool mouseReleaseEvent()
bool disableDirtyNotifications
virtual qreal paintOpSize() const =0
void setPaintOpCompositeOp(const QString &value)
bool hasMaskingSettings() const
QPointer< KisPaintOpConfigWidget > settingsWidget
void setPaintOpFlow(qreal value)
virtual KisOptimizedBrushOutline brushOutline(const KisPaintInformation &info, const OutlineMode &mode, qreal alignForZoom)
virtual KisPaintOpSettingsSP clone() const
virtual qreal airbrushInterval() const
virtual bool lodSizeThresholdSupported() const
void setModelName(const QString &modelName)
qreal savedBrushSize() const
qreal savedBrushOpacity() const
virtual void resetSettings(const QStringList &preserveProperties=QStringList())
void setProperty(const QString &name, const QVariant &value) override
virtual void setPaintOpOpacity(qreal value)
virtual qreal paintOpPatternSize()
void setEraserMode(bool value)
void setPaintOpFade(qreal value)
qreal lodSizeThreshold() const
void setResourcesInterface(KisResourcesInterfaceSP resourcesInterface)
virtual void setResourceCacheInterface(KoResourceCacheInterfaceSP cacheInterface)
virtual bool isAirbrushing() const
void setSavedBrushOpacity(qreal value)
void setSavedEraserOpacity(qreal value)
const QScopedPointer< Private > d
virtual bool mousePressEvent(const KisPaintInformation &paintInformation, Qt::KeyboardModifiers modifiers, KisNodeWSP currentNode)
KisPaintOpSettingsSP createMaskingSettings() const
KoCanvasResourcesInterfaceSP canvasResourcesInterface
QList< KisUniformPaintOpPropertyWSP > uniformProperties
void setLodSizeThreshold(qreal value)
UpdateListenerWSP updateListener
void setPaintOpScatter(qreal value)
QString maskingBrushCompositeOp() const
void setUpdateListener(UpdateListenerWSP listener)
virtual bool useSpacingUpdates() const
KoResourceCacheInterfaceSP resourceCacheInterface
virtual QList< int > requiredCanvasResources() const
Private(const Private &rhs)
void setPropertyNotSaved(const QString &name)
Marks a property that should not be saved by toXML.
QString getString(const QString &name, const QString &def=QString()) const
void clearProperties()
Clear the map of properties.
virtual bool hasProperty(const QString &name) const
virtual void setProperty(const QString &name, const QVariant &value)
bool getBool(const QString &name, bool def=false) const
int getInt(const QString &name, int def=0) const
double getDouble(const QString &name, double def=0.0) const
void getPrefixedProperties(const QString &prefix, KisPropertiesConfiguration *config) const
virtual bool getProperty(const QString &name, QVariant &value) const
virtual QMap< QString, QVariant > getProperties() const