File indexing completed on 2024-06-09 04:21:55

0001 /*
0002  *  SPDX-FileCopyrightText: 2008 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #ifndef KIS_GENERATOR_LAYER_H_
0007 #define KIS_GENERATOR_LAYER_H_
0008 
0009 #include <boost/none.hpp>
0010 
0011 #include "kis_selection_based_layer.h"
0012 #include <kritaimage_export.h>
0013 #include <KisDelayedUpdateNodeInterface.h>
0014 
0015 #include <QScopedPointer>
0016 
0017 class KisFilterConfiguration;
0018 
0019 /**
0020  * A generator layer is a special kind of layer that can be prefilled
0021  * with some pixel pattern generated by a KisGenerator plugin.
0022  * A KisGenerator is similar to a filter, but doesn't take
0023  * input pixel data and creates new pixel data.
0024  *
0025  * It is not possible to destructively paint on a generator layer.
0026  *
0027  * XXX: what about threadedness?
0028  */
0029 class KRITAIMAGE_EXPORT KisGeneratorLayer
0030         : public KisSelectionBasedLayer,
0031           public KisDelayedUpdateNodeInterface
0032 {
0033     Q_OBJECT
0034 
0035 public:
0036     /**
0037      * Create a new Generator layer with the given configuration
0038      * and selection. Note that the selection will be _copied_
0039      * (using COW, though).
0040      */
0041     KisGeneratorLayer(KisImageWSP image, const QString &name, KisFilterConfigurationSP  kfc, KisSelectionSP selection);
0042     KisGeneratorLayer(const KisGeneratorLayer& rhs);
0043     ~KisGeneratorLayer() override;
0044 
0045     KisNodeSP clone() const override {
0046         return KisNodeSP(new KisGeneratorLayer(*this));
0047     }
0048 
0049     void setFilter(KisFilterConfigurationSP filterConfig, bool checkCompareConfig = true) override;
0050     /**
0051      * Changes the filter configuration without triggering an update.
0052      */
0053     void setFilterWithoutUpdate(KisFilterConfigurationSP filterConfig, bool checkCompareConfig = true);
0054 
0055     bool accept(KisNodeVisitor &) override;
0056     void accept(KisProcessingVisitor &visitor, KisUndoAdapter *undoAdapter) override;
0057 
0058     QIcon icon() const override;
0059     KisBaseNode::PropertyList sectionModelProperties() const override;
0060 
0061     /**
0062      * re-run the generator. This happens over the bounds
0063      * of the associated selection.
0064      */
0065     void update();
0066     /**
0067      * re-runs the generator with the specified configuration.
0068      * Used for previewing the layer inside the stroke.
0069      */
0070     QWeakPointer<boost::none_t> previewWithStroke(const KisStrokeId stroke);
0071 
0072     using KisSelectionBasedLayer::setDirty;
0073     void setDirty(const QVector<QRect> &rects) override;
0074     /**
0075      * Updates the selected tiles without triggering the update job.
0076      */
0077     void setDirtyWithoutUpdate(const QVector<QRect> &rects);
0078     void setX(qint32 x) override;
0079     void setY(qint32 y) override;
0080 
0081     void resetCache() override;
0082 
0083     void forceUpdateTimedNode() override;
0084     bool hasPendingTimedUpdates() const override;
0085 
0086 private Q_SLOTS:
0087     void slotDelayedStaticUpdate();
0088 
0089 private:
0090     /**
0091      * Injects render jobs into the given stroke.
0092      */
0093     void requestUpdateJobsWithStroke(const KisStrokeId stroke, const KisFilterConfigurationSP configuration);
0094     /**
0095      * Resets the projection cache without triggering the update job.
0096      */
0097     void resetCacheWithoutUpdate();
0098 
0099 public:
0100     // KisIndirectPaintingSupport
0101     KisLayer* layer() {
0102         return this;
0103     }
0104 
0105 private:
0106     struct Private;
0107     const QScopedPointer<Private> m_d;
0108 };
0109 
0110 #endif
0111