File indexing completed on 2024-05-12 15:58:28
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 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 onlion 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 void handleKeyframeChannelUpdate(const KisTimeSpan &range, const QRect &rect); 0151 0152 /** 0153 * Informs that the current world time should be changed. 0154 * Might be caused by e.g. undo operation 0155 */ 0156 void requestTimeSwitch(int time); 0157 0158 /** 0159 * \return a pointer to a KisAbstractProjectionPlane interface of 0160 * the node. This interface is used by the image merging 0161 * framework to get information and to blending for the 0162 * layer. 0163 * 0164 * Please note the difference between need/change/accessRect and 0165 * the projectionPlane() interface. The former one gives 0166 * information about internal composition of the layer, and the 0167 * latter one about the total composition, including layer styles, 0168 * pass-through blending and etc. 0169 */ 0170 virtual KisAbstractProjectionPlaneSP projectionPlane() const; 0171 0172 /** 0173 * Synchronizes LoD caches of the node with the current state of it. 0174 * The current level of detail is fetched from the image pointed by 0175 * default bounds object 0176 */ 0177 virtual void syncLodCache(); 0178 virtual KisPaintDeviceList getLodCapableDevices() const; 0179 0180 /** 0181 * The rendering of the image may not always happen in the order 0182 * of the main graph. Pass-through nodes make some subgraphs 0183 * linear, so it the order of rendering change. projectionLeaf() 0184 * is a special interface of KisNode that represents "a graph for 0185 * projection rendering". Therefore the nodes in projectionLeaf() 0186 * graph may have a different order the main one. 0187 */ 0188 virtual KisProjectionLeafSP projectionLeaf() const; 0189 0190 0191 void setImage(KisImageWSP newImage) override; 0192 0193 protected: 0194 0195 /** 0196 * \return internal changeRect() of the node. Do not mix with \see 0197 * projectionPlane() 0198 * 0199 * Some filters will cause a change of pixels those are outside 0200 * a requested rect. E.g. we change a rect of 2x2, then we want to 0201 * apply a convolution filter with kernel 4x4 (changeRect is 0202 * (2+2*3)x(2+2*3)=8x8) to that area. The rect that should be updated 0203 * on the layer will be exactly 8x8. More than that the needRect for 0204 * that update will be 14x14. See \ref needeRect. 0205 */ 0206 virtual QRect changeRect(const QRect &rect, PositionToFilthy pos = N_FILTHY) const; 0207 0208 /** 0209 * \return internal needRect() of the node. Do not mix with \see 0210 * projectionPlane() 0211 * 0212 * Some filters need pixels outside the current processing rect to 0213 * compute the new value (for instance, convolution filters) 0214 * See \ref changeRect 0215 * See \ref accessRect 0216 */ 0217 virtual QRect needRect(const QRect &rect, PositionToFilthy pos = N_FILTHY) const; 0218 0219 0220 /** 0221 * \return internal accessRect() of the node. Do not mix with \see 0222 * projectionPlane() 0223 * 0224 * Shows the area of image, that may be accessed during accessing 0225 * the node. 0226 * 0227 * Example. You have a layer that needs to prepare some rect on a 0228 * projection, say expectedRect. To perform this, the projection 0229 * of all the layers below of the size needRect(expectedRect) 0230 * should be calculated by the merger beforehand and the layer 0231 * will access some other area of image inside the rect 0232 * accessRect(expectedRect) during updateProjection call. 0233 * 0234 * This knowledge about real access rect of a node is used by the 0235 * scheduler to avoid collisions between two multithreaded updaters 0236 * and so avoid flickering of the image. 0237 * 0238 * Currently, this method has nondefault value for shifted clone 0239 * layers only. 0240 */ 0241 virtual QRect accessRect(const QRect &rect, PositionToFilthy pos = N_FILTHY) const; 0242 0243 /** 0244 * Called each time direct child nodes are added or removed under this 0245 * node as parent. This does not track changes inside the child nodes 0246 * or the child nodes' properties. 0247 */ 0248 virtual void childNodeChanged(KisNodeSP changedChildNode); 0249 0250 public: // Graph methods 0251 0252 /** 0253 * @return the graph sequence number calculated by the associated 0254 * graph listener. You can use it for checking for changes in the 0255 * graph. 0256 */ 0257 int graphSequenceNumber() const; 0258 0259 /** 0260 * @return the graph listener this node belongs to. 0 if the node 0261 * does not belong to a grap listener. 0262 */ 0263 KisNodeGraphListener * graphListener() const; 0264 0265 /** 0266 * Set the graph listener for this node. The graphlistener will be 0267 * informed before and after the list of child nodes has changed. 0268 */ 0269 void setGraphListener(KisNodeGraphListener * graphListener); 0270 0271 /** 0272 * Returns the parent node of this node. This is 0 only for a root 0273 * node; otherwise this will be an actual Node 0274 */ 0275 KisNodeSP parent() const; 0276 0277 /** 0278 * Returns the first child node of this node, or 0 if there are no 0279 * child nodes. 0280 */ 0281 KisNodeSP firstChild() const; 0282 0283 /** 0284 * Returns the last child node of this node, or 0 if there are no 0285 * child nodes. 0286 */ 0287 KisNodeSP lastChild() const; 0288 0289 /** 0290 * Returns the previous sibling of this node in the parent's list. 0291 * This is the node *above* this node in the composition stack. 0 0292 * is returned if this child has no more previous siblings (== 0293 * firstChild()) 0294 */ 0295 KisNodeSP prevSibling() const; 0296 0297 /** 0298 * Returns the next sibling of this node in the parent's list. 0299 * This is the node *below* this node in the composition stack. 0 0300 * is returned if this child has no more next siblings (== 0301 * lastChild()) 0302 */ 0303 KisNodeSP nextSibling() const; 0304 0305 /** 0306 * Returns how many direct child nodes this node has (not 0307 * recursive). 0308 */ 0309 quint32 childCount() const; 0310 0311 /** 0312 * Retrieve the child node at the specified index. 0313 * 0314 * @return 0 if there is no node at this index. 0315 */ 0316 KisNodeSP at(quint32 index) const; 0317 0318 /** 0319 * Retrieve the index of the specified child node. 0320 * 0321 * @return -1 if the specified node is not a child node of this 0322 * node. 0323 */ 0324 int index(const KisNodeSP node) const; 0325 0326 0327 /** 0328 * Return a list of child nodes of the current node that conform 0329 * to the specified constraints. There are no guarantees about the 0330 * order of the nodes in the list. The function is not recursive. 0331 * 0332 * @param nodeTypes. if not empty, only nodes that inherit the 0333 * classnames in this stringlist will be returned. 0334 * @param properties. if not empty, only nodes for which 0335 * KisNodeBase::check(properties) returns true will be returned. 0336 */ 0337 QList<KisNodeSP> childNodes(const QStringList & nodeTypes, const KoProperties & properties) const; 0338 0339 /** 0340 * @brief findChildByName finds the first child that has the given name 0341 * @param name the name to look for 0342 * @return the first child with the given name 0343 */ 0344 KisNodeSP findChildByName(const QString &name); 0345 0346 /** 0347 * @brief nodeByUniqueID searches the node tree for a node with the given name and returns it. 0348 * @param uuid the unique id of the node 0349 * @return the node with the given unique id, or 0 if no node is found. 0350 */ 0351 KisNodeSP findChildByUniqueID(const QUuid &uuid); 0352 0353 Q_SIGNALS: 0354 /** 0355 * Don't use this signal anywhere other than KisNodeShape. It's a hack. 0356 */ 0357 void sigNodeChangedInternal(); 0358 0359 public: 0360 0361 /** 0362 * @return the node progress proxy used by this node, if this node has no progress 0363 * proxy, it will return the proxy of its parent, if the parent has no progress proxy 0364 * it will return 0 0365 */ 0366 KisNodeProgressProxy* nodeProgressProxy() const; 0367 0368 KisBusyProgressIndicator* busyProgressIndicator() const; 0369 0370 private: 0371 0372 /** 0373 * Create a node progress proxy for this node. You need to create a progress proxy only 0374 * if the node is going to appear in the layerbox, and it needs to be created before 0375 * the layer box is made aware of the proxy. 0376 */ 0377 void createNodeProgressProxy(); 0378 0379 protected: 0380 KisBaseNodeSP parentCallback() const override; 0381 void notifyParentVisibilityChanged(bool value) override; 0382 void baseNodeChangedCallback() override; 0383 void baseNodeInvalidateAllFramesCallback() override; 0384 void baseNodeCollapsedChangedCallback() override; 0385 0386 protected: 0387 void addKeyframeChannel(KisKeyframeChannel* channel) override; 0388 private: 0389 0390 friend class KisNodeFacade; 0391 friend class KisNodeTest; 0392 friend class KisLayer; // Note: only for setting the preview mask! 0393 /** 0394 * Set the parent of this node. 0395 */ 0396 void setParent(KisNodeWSP parent); 0397 0398 /** 0399 * Add the specified node above the specified node. If aboveThis 0400 * is 0, the node is added at the bottom. 0401 */ 0402 bool add(KisNodeSP newNode, KisNodeSP aboveThis); 0403 0404 /** 0405 * Removes the node at the specified index from the child nodes. 0406 * 0407 * @return false if there is no node at this index 0408 */ 0409 bool remove(quint32 index); 0410 0411 /** 0412 * Removes the node from the child nodes. 0413 * 0414 * @return false if there's no such node in this node. 0415 */ 0416 bool remove(KisNodeSP node); 0417 0418 KisNodeSP prevChildImpl(KisNodeSP child); 0419 KisNodeSP nextChildImpl(KisNodeSP child); 0420 0421 private: 0422 0423 struct Private; 0424 Private * const m_d; 0425 0426 }; 0427 0428 Q_DECLARE_METATYPE(KisNodeSP) 0429 0430 Q_DECLARE_METATYPE(KisNodeWSP) 0431 0432 #endif