File indexing completed on 2024-05-19 04:26:23

0001 /*
0002  *  SPDX-FileCopyrightText: 2007 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #ifndef _KIS_NODE_H
0007 #define _KIS_NODE_H
0008 
0009 #include "kis_types.h"
0010 
0011 #include "kis_base_node.h"
0012 
0013 #include "kritaimage_export.h"
0014 
0015 #include <QVector>
0016 #include <KisRegion.h>
0017 
0018 class QRect;
0019 class QStringList;
0020 
0021 class KoProperties;
0022 
0023 class KisNodeVisitor;
0024 class KisNodeGraphListener;
0025 class KisNodeProgressProxy;
0026 class KisBusyProgressIndicator;
0027 class KisAbstractProjectionPlane;
0028 class KisProjectionLeaf;
0029 class KisKeyframeChannel;
0030 class KisTimeSpan;
0031 class KisUndoAdapter;
0032 struct KisFrameChangeUpdateRecipe;
0033 
0034 /**
0035  * A KisNode is a KisBaseNode that knows about its direct peers, parent
0036  * and children and whether it can have children.
0037  *
0038  * THREAD-SAFETY: All const methods of this class and setDirty calls
0039  *                are considered to be thread-safe(!). All the others
0040  *                especially add(), remove() and setParent() must be
0041  *                protected externally.
0042  *
0043  * NOTE: your subclasses must have the Q_OBJECT declaration, even if
0044  * you do not define new signals or slots.
0045  */
0046 class KRITAIMAGE_EXPORT KisNode : public KisBaseNode
0047 {
0048     friend class KisFilterMaskTest;
0049     Q_OBJECT
0050 
0051 public:
0052     /**
0053      * The struct describing the position of the node
0054      * against the filthy node.
0055      * NOTE: please change KisBaseRectsWalker::getPositionToFilthy
0056      *       when changing this struct
0057      */
0058     enum PositionToFilthy {
0059         N_ABOVE_FILTHY = 0x08,
0060         N_FILTHY_PROJECTION = 0x20,
0061         N_FILTHY = 0x40,
0062         N_BELOW_FILTHY = 0x80
0063     };
0064 
0065     /**
0066      * Create an empty node without a parent.
0067      */
0068     KisNode(KisImageWSP image);
0069 
0070     /**
0071      * Create a copy of this node. The copy will not have a parent
0072      * node.
0073      */
0074     KisNode(const KisNode & rhs);
0075 
0076     /**
0077      * Delete this node
0078      */
0079     ~KisNode() override;
0080 
0081     virtual KisNodeSP clone() const = 0;
0082 
0083     bool accept(KisNodeVisitor &v) override;
0084     void accept(KisProcessingVisitor &visitor, KisUndoAdapter *undoAdapter) override;
0085 
0086     /**
0087      * Re-implement this method to add constraints for the
0088      * subclasses that can be added as children to this node
0089      *
0090      * @return false if the given node is not allowed as a child to this node
0091      */
0092     virtual bool allowAsChild(KisNodeSP) const = 0;
0093 
0094     /**
0095      * Set the entire node extent dirty; this percolates up to parent
0096      * nodes all the way to the root node. By default this is the
0097      * empty rect (through KisBaseNode::extent())
0098      */
0099     virtual void setDirty();
0100 
0101     /**
0102      * Add the given rect to the set of dirty rects for this node;
0103      * this percolates up to parent nodes all the way to the root
0104      * node.
0105      */
0106     void setDirty(const QRect & rect);
0107 
0108     /**
0109      * Add the given rects to the set of dirty rects for this node;
0110      * this percolates up to parent nodes all the way to the root
0111      * node.
0112      */
0113     virtual void setDirty(const QVector<QRect> &rects);
0114 
0115     /**
0116      * Add the given region to the set of dirty rects for this node;
0117      * this percolates up to parent nodes all the way to the root
0118      * node, if propagate is true;
0119      */
0120     void setDirty(const KisRegion &region);
0121 
0122     /**
0123      * Convenience override of multirect version of setDirtyDontResetAnimationCache()
0124      *
0125      * @see setDirtyDontResetAnimationCache(const QVector<QRect> &rects)
0126      */
0127     void setDirtyDontResetAnimationCache();
0128 
0129     /**
0130      * Convenience override of multirect version of setDirtyDontResetAnimationCache()
0131      *
0132      * @see setDirtyDontResetAnimationCache(const QVector<QRect> &rects)
0133      */
0134     void setDirtyDontResetAnimationCache(const QRect &rect);
0135 
0136     /**
0137      * @brief setDirtyDontResetAnimationCache does almost the same thing as usual
0138      * setDirty() call, but doesn't reset the animation cache (since onion skins are
0139      * not used when rendering animation.
0140      */
0141     void setDirtyDontResetAnimationCache(const QVector<QRect> &rects);
0142 
0143     /**
0144      * Informs animation cache that the frames in the given range are
0145      * no longer valid and need to be recached.
0146      * @param range frames to invalidate
0147      */
0148     void invalidateFrames(const KisTimeSpan &range, const QRect &rect);
0149 
0150     virtual void handleKeyframeChannelFrameChange(const KisKeyframeChannel *channel, int time);
0151     virtual void handleKeyframeChannelFrameAdded(const KisKeyframeChannel *channel, int time);
0152     void handleKeyframeChannelFrameAboutToBeRemoved(const KisKeyframeChannel *channel, int time);
0153     void handleKeyframeChannelFrameHasBeenRemoved(const KisKeyframeChannel *channel, int time);
0154 
0155     /**
0156      * Informs that the current world time should be changed.
0157      * Might be caused by e.g. undo operation
0158      */
0159     void requestTimeSwitch(int time);
0160 
0161     /**
0162      * \return a pointer to a KisAbstractProjectionPlane interface of
0163      *         the node. This interface is used by the image merging
0164      *         framework to get information and to blending for the
0165      *         layer.
0166      *
0167      * Please note the difference between need/change/accessRect and
0168      * the projectionPlane() interface. The former one gives
0169      * information about internal composition of the layer, and the
0170      * latter one about the total composition, including layer styles,
0171      * pass-through blending and etc.
0172      */
0173     virtual KisAbstractProjectionPlaneSP projectionPlane() const;
0174 
0175     /**
0176      * Synchronizes LoD caches of the node with the current state of it.
0177      * The current level of detail is fetched from the image pointed by
0178      * default bounds object
0179      */
0180     virtual void syncLodCache();
0181     virtual KisPaintDeviceList getLodCapableDevices() const;
0182 
0183     /**
0184      * The rendering of the image may not always happen in the order
0185      * of the main graph. Pass-through nodes make some subgraphs
0186      * linear, so it the order of rendering change. projectionLeaf()
0187      * is a special interface of KisNode that represents "a graph for
0188      * projection rendering". Therefore the nodes in projectionLeaf()
0189      * graph may have a different order the main one.
0190      */
0191     virtual KisProjectionLeafSP projectionLeaf() const;
0192 
0193 
0194     void setImage(KisImageWSP newImage) override;
0195 
0196 protected:
0197 
0198     /**
0199      * \return internal changeRect() of the node. Do not mix with \see
0200      *         projectionPlane()
0201      *
0202      * Some filters will cause a change of pixels those are outside
0203      * a requested rect. E.g. we change a rect of 2x2, then we want to
0204      * apply a convolution filter with kernel 4x4 (changeRect is
0205      * (2+2*3)x(2+2*3)=8x8) to that area. The rect that should be updated
0206      * on the layer will be exactly 8x8. More than that the needRect for
0207      * that update will be 14x14. See \ref needRect.
0208      */
0209     virtual QRect changeRect(const QRect &rect, PositionToFilthy pos = N_FILTHY) const;
0210 
0211     /**
0212      * \return internal needRect() of the node. Do not mix with \see
0213      *         projectionPlane()
0214      *
0215      * Some filters need pixels outside the current processing rect to
0216      * compute the new value (for instance, convolution filters)
0217      * See \ref changeRect
0218      * See \ref accessRect
0219      */
0220     virtual QRect needRect(const QRect &rect, PositionToFilthy pos = N_FILTHY) const;
0221 
0222 
0223     /**
0224      * \return internal accessRect() of the node. Do not mix with \see
0225      *         projectionPlane()
0226      *
0227      * Shows the area of image, that may be accessed during accessing
0228      * the node.
0229      *
0230      * Example. You have a layer that needs to prepare some rect on a
0231      * projection, say expectedRect. To perform this, the projection
0232      * of all the layers below of the size needRect(expectedRect)
0233      * should be calculated by the merger beforehand and the layer
0234      * will access some other area of image inside the rect
0235      * accessRect(expectedRect) during updateProjection call.
0236      *
0237      * This knowledge about real access rect of a node is used by the
0238      * scheduler to avoid collisions between two multithreaded updaters
0239      * and so avoid flickering of the image.
0240      *
0241      * Currently, this method has nondefault value for shifted clone
0242      * layers only.
0243      */
0244     virtual QRect accessRect(const QRect &rect, PositionToFilthy pos = N_FILTHY) const;
0245 
0246     /**
0247      * Called each time direct child nodes are added or removed under this
0248      * node as parent. This does not track changes inside the child nodes
0249      * or the child nodes' properties.
0250      */
0251     virtual void childNodeChanged(KisNodeSP changedChildNode);
0252 
0253 public: // Graph methods
0254 
0255     /**
0256      * @return the graph sequence number calculated by the associated
0257      * graph listener. You can use it for checking for changes in the
0258      * graph.
0259      */
0260     int graphSequenceNumber() const;
0261 
0262     /**
0263      * @return the graph listener this node belongs to. 0 if the node
0264      * does not belong to a graph listener.
0265      */
0266     KisNodeGraphListener * graphListener() const;
0267 
0268     /**
0269      * Set the graph listener for this node. The graphlistener will be
0270      * informed before and after the list of child nodes has changed.
0271      */
0272     void setGraphListener(KisNodeGraphListener * graphListener);
0273 
0274     /**
0275      * Returns the parent node of this node. This is 0 only for a root
0276      * node; otherwise this will be an actual Node
0277      */
0278     KisNodeSP parent() const;
0279 
0280     /**
0281      * Returns the first child node of this node, or 0 if there are no
0282      * child nodes.
0283      */
0284     KisNodeSP firstChild() const;
0285 
0286     /**
0287      * Returns the last child node of this node, or 0 if there are no
0288      * child nodes.
0289      */
0290     KisNodeSP lastChild() const;
0291 
0292     /**
0293      * Returns the previous sibling of this node in the parent's list.
0294      * This is the node *above* this node in the composition stack. 0
0295      * is returned if this child has no more previous siblings (==
0296      * firstChild())
0297      */
0298     KisNodeSP prevSibling() const;
0299 
0300     /**
0301      * Returns the next sibling of this node in the parent's list.
0302      * This is the node *below* this node in the composition stack. 0
0303      * is returned if this child has no more next siblings (==
0304      * lastChild())
0305      */
0306     KisNodeSP nextSibling() const;
0307 
0308     /**
0309      * Returns how many direct child nodes this node has (not
0310      * recursive).
0311      */
0312     quint32 childCount() const;
0313 
0314     /**
0315      * Retrieve the child node at the specified index.
0316      *
0317      * @return 0 if there is no node at this index.
0318      */
0319     KisNodeSP at(quint32 index) const;
0320 
0321     /**
0322      * Retrieve the index of the specified child node.
0323      *
0324      * @return -1 if the specified node is not a child node of this
0325      * node.
0326      */
0327     int index(const KisNodeSP node) const;
0328 
0329 
0330     /**
0331      * Return a list of child nodes of the current node that conform
0332      * to the specified constraints. There are no guarantees about the
0333      * order of the nodes in the list. The function is not recursive.
0334      *
0335      * @param nodeTypes. if not empty, only nodes that inherit the
0336      * classnames in this stringlist will be returned.
0337      * @param properties. if not empty, only nodes for which
0338      * KisNodeBase::check(properties) returns true will be returned.
0339      */
0340     QList<KisNodeSP> childNodes(const QStringList & nodeTypes, const KoProperties & properties) const;
0341 
0342 Q_SIGNALS:
0343     /**
0344      * Don't use this signal anywhere other than KisNodeShape. It's a hack.
0345      */
0346     void sigNodeChangedInternal();
0347 
0348 public:
0349 
0350     /**
0351      * @return the node progress proxy used by this node, if this node has no progress
0352      *         proxy, it will return the proxy of its parent, if the parent has no progress proxy
0353      *         it will return 0
0354      */
0355     KisNodeProgressProxy* nodeProgressProxy() const;
0356 
0357     KisBusyProgressIndicator* busyProgressIndicator() const;
0358 
0359 private:
0360 
0361     /**
0362      * Create a node progress proxy for this node. You need to create a progress proxy only
0363      * if the node is going to appear in the layerbox, and it needs to be created before
0364      * the layer box is made aware of the proxy.
0365      */
0366     void createNodeProgressProxy();
0367 
0368 protected:
0369     KisBaseNodeSP parentCallback() const override;
0370     void notifyParentVisibilityChanged(bool value) override;
0371     void baseNodeChangedCallback() override;
0372     void baseNodeInvalidateAllFramesCallback() override;
0373     void baseNodeCollapsedChangedCallback() override;
0374 
0375 protected:
0376     void addKeyframeChannel(KisKeyframeChannel* channel) override;
0377     virtual KisFrameChangeUpdateRecipe handleKeyframeChannelFrameAboutToBeRemovedImpl(const KisKeyframeChannel *channel, int time);
0378 
0379 private:
0380 
0381     friend class KisNodeFacade;
0382     friend class KisNodeTest;
0383     friend class KisLayer; // Note: only for setting the preview mask!
0384     /**
0385      * Set the parent of this node.
0386      */
0387     void setParent(KisNodeWSP parent);
0388 
0389     /**
0390      * Add the specified node above the specified node. If aboveThis
0391      * is 0, the node is added at the bottom.
0392      */
0393     bool add(KisNodeSP newNode, KisNodeSP aboveThis);
0394 
0395     /**
0396      * Removes the node at the specified index from the child nodes.
0397      *
0398      * @return false if there is no node at this index
0399      */
0400     bool remove(quint32 index);
0401 
0402     /**
0403      * Removes the node from the child nodes.
0404      *
0405      * @return false if there's no such node in this node.
0406      */
0407     bool remove(KisNodeSP node);
0408 
0409     KisNodeSP prevChildImpl(KisNodeSP child);
0410     KisNodeSP nextChildImpl(KisNodeSP child);
0411 
0412 private:
0413 
0414     struct Private;
0415     Private * const m_d;
0416 
0417 };
0418 
0419 Q_DECLARE_METATYPE(KisNodeSP)
0420 
0421 Q_DECLARE_METATYPE(KisNodeWSP)
0422 
0423 #endif