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 ®ion); 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