File indexing completed on 2024-05-12 15:58:41

0001 /*
0002  *  SPDX-FileCopyrightText: 2006 Boudewijn Rempt <boud@valdyas.org>
0003  *  SPDX-FileCopyrightText: 2009 Dmitry Kazakov <dimula73@gmail.com>
0004  *
0005  *  SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #ifndef KIS_SELECTION_BASED_LAYER_H_
0009 #define KIS_SELECTION_BASED_LAYER_H_
0010 
0011 #include <QObject>
0012 #include "kis_types.h"
0013 #include "kis_layer.h"
0014 #include "kis_indirect_painting_support.h"
0015 #include <kritaimage_export.h>
0016 #include "kis_node_filter_interface.h"
0017 
0018 class KisFilterConfiguration;
0019 
0020 /**
0021  * @class KisSelectionBasedLayer
0022  * @brief Describes base behaviour for
0023  * selection base classes like KisAdjustmentLayer and KisGeneratorLayer.
0024  * These classes should have a persistent selection that controls
0025  * the area where filter/generators are applied. The area outside
0026  * this selection is not affected by the layer
0027  */
0028 class KRITAIMAGE_EXPORT KisSelectionBasedLayer : public KisLayer, public KisIndirectPaintingSupport, public KisNodeFilterInterface
0029 {
0030     Q_OBJECT
0031 
0032 public:
0033     /**
0034      * creates a new layer with the given selection.
0035      * Note that the selection will be _copied_ (with COW, though).
0036      * @param image the image to set this layer to
0037      * @param name name of the layer
0038      * @param selection is a mask used by the layer to know
0039      * where to apply the filter/generator.
0040      */
0041     KisSelectionBasedLayer(KisImageWSP image, const QString &name, KisSelectionSP selection, KisFilterConfigurationSP filterConfig);
0042     KisSelectionBasedLayer(const KisSelectionBasedLayer& rhs);
0043     ~KisSelectionBasedLayer() override;
0044 
0045 
0046     /**
0047      * tells whether the @node can be a child of this layer
0048      * @param node to be connected node
0049      * @return tells if to be connected is a child of KisMask
0050      */
0051     bool allowAsChild(KisNodeSP node) const override;
0052 
0053     void setImage(KisImageWSP image) override;
0054 
0055     KisPaintDeviceSP original() const override;
0056     KisPaintDeviceSP paintDevice() const override;
0057 
0058     bool needProjection() const override;
0059 
0060     /**
0061      * resets cached projection of lower layer to a new device
0062      * @return void
0063      */
0064     virtual void resetCache();
0065 
0066     /**
0067      * for KisLayer::setDirty(const KisRegion&)
0068      */
0069     using KisLayer::setDirty;
0070 
0071     /**
0072      * Mark a layer as dirty. We can't use KisLayer's one
0073      * as our extent() function doesn't fit for this
0074      */
0075     void setDirty() override;
0076 
0077 public:
0078 
0079     /**
0080      * Returns the selection of the layer
0081      *
0082      * Do not mix it with selection() which returns
0083      * the currently active selection of the image
0084      */
0085     KisSelectionSP internalSelection() const;
0086 
0087     /**
0088      * sets the selection of this layer to a copy of
0089      * selection
0090      * @param selection the selection to set
0091      * @return void
0092      */
0093 
0094     void setInternalSelection(KisSelectionSP selection);
0095 
0096     /**
0097      * When painted in indirect painting mode, the internal selection
0098      * might not contain actual selection, because a part of it is
0099      * stored on an indirect painting device. This method returns the
0100      * merged copy of the real selection. The area in \p rect only is
0101      * guaranteed to be prepared. The content of the rest of the
0102      * selection is undefined.
0103      */
0104     KisSelectionSP fetchComposedInternalSelection(const QRect &rect) const;
0105 
0106     /**
0107      * gets this layer's x coordinate, taking selection into account
0108      * @return x-coordinate value
0109      */
0110     qint32 x() const override;
0111 
0112     /**
0113      * gets this layer's y coordinate, taking selection into account
0114      * @return y-coordinate value
0115      */
0116     qint32 y() const override;
0117 
0118     /**
0119      * sets this layer's y coordinate, taking selection into account
0120      * @param x x coordinate
0121      */
0122     void setX(qint32 x) override;
0123 
0124     /**
0125      * sets this layer's y coordinate, taking selection into account
0126      * @param y y coordinate
0127      */
0128     void setY(qint32 y) override;
0129 
0130     bool supportsLodPainting() const override;
0131 
0132 public:
0133 
0134     /**
0135      * gets an approximation of where the bounds on actual data
0136      * are in this layer, taking selection into account
0137      */
0138     QRect extent() const override;
0139 
0140     /**
0141      * returns the exact bounds of where the actual data resides
0142      * in this layer, taking selection into account
0143      */
0144     QRect exactBounds() const override;
0145 
0146     /**
0147      * copies the image and reformats it to thumbnail size
0148      * and returns the new thumbnail image.
0149      * @param w width of the thumbnail to create
0150      * @param h height of the thumbnail to create
0151      * @return the thumbnail image created.
0152      */
0153     QImage createThumbnail(qint32 w, qint32 h, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio) override;
0154 
0155 
0156 protected:
0157     // override from KisLayer
0158     void copyOriginalToProjection(const KisPaintDeviceSP original,
0159                                   KisPaintDeviceSP projection,
0160                                   const QRect& rect) const override;
0161     // override from KisNode
0162     QRect needRect(const QRect &rect, PositionToFilthy pos = N_FILTHY) const override;
0163 
0164 protected:
0165     void initSelection();
0166 
0167     QRect cropChangeRectBySelection(const QRect &rect) const;
0168 
0169     /**
0170      * Sets if the selection should be used in
0171      * copyOriginalToProjection() method.
0172      *
0173      * Default value is 'true'. The descendants should override it to
0174      * get desired behaviour.
0175      *
0176      * Must be called only once in the child's constructor
0177      */
0178     void setUseSelectionInProjection(bool value) const;
0179 
0180     KisKeyframeChannel *requestKeyframeChannel(const QString &id) override;
0181     bool supportsKeyframeChannel(const QString &id) override;
0182 
0183 
0184 public Q_SLOTS:
0185     void slotImageSizeChanged();
0186 
0187     /**
0188      * gets this layer. Overriddes function in
0189      * KisIndirectPaintingSupport
0190      * @return this AdjustmentLayer
0191      */
0192     KisLayer* layer() {
0193         return this;
0194     }
0195 
0196 private:
0197     struct Private;
0198     Private * const m_d;
0199 };
0200 
0201 #endif /* KIS_SELECTION_BASED_LAYER_H_ */
0202