File indexing completed on 2024-05-12 15:58:10
0001 /* 0002 * SPDX-FileCopyrightText: 2007 Boudewijn Rempt <boud@valdyas.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #ifndef _KIS_BASE_NODE_H 0007 #define _KIS_BASE_NODE_H 0008 0009 #include <QObject> 0010 #include <QIcon> 0011 #include <QUuid> 0012 #include <QString> 0013 0014 #include <KoID.h> 0015 0016 #include "kis_shared.h" 0017 #include "kis_paint_device.h" 0018 #include "kis_processing_visitor.h" // included, not forward declared for msvc 0019 0020 class KoProperties; 0021 class KoColorSpace; 0022 class KoCompositeOp; 0023 class KisNodeVisitor; 0024 class KisUndoAdapter; 0025 class KisKeyframeChannel; 0026 0027 #include "kritaimage_export.h" 0028 0029 /** 0030 * A KisBaseNode is the base class for all components of an image: 0031 * nodes, layers masks, selections. A node has a number of properties, 0032 * can be represented as a thumbnail and knows what to do when it gets 0033 * a certain paint device to process. A KisBaseNode does not know 0034 * anything about its peers. You should not directly inherit from a 0035 * KisBaseNode; inherit from KisNode instead. 0036 */ 0037 class KRITAIMAGE_EXPORT KisBaseNode : public QObject, public KisShared 0038 { 0039 0040 Q_OBJECT 0041 0042 public: 0043 /** 0044 * Describes a property of a document section. 0045 * 0046 * FIXME: using a QList instead of QMap and not having an untranslated identifier, 0047 * either enum or string, forces applications to rely on the order of properties 0048 * or to compare the translated strings. This makes it hard to robustly extend the 0049 * properties of document section items. 0050 */ 0051 struct Property 0052 { 0053 QString id; 0054 0055 /** i18n-ed name, suitable for displaying */ 0056 QString name; 0057 0058 /** Whether the property is a boolean (e.g. locked, visible) which can be toggled directly from the widget itself. */ 0059 bool isMutable {false}; 0060 0061 /** Provide these if the property isMutable. */ 0062 QIcon onIcon; 0063 QIcon offIcon; 0064 0065 /** If the property isMutable, provide a boolean. Otherwise, a string suitable for displaying. */ 0066 QVariant state; 0067 0068 /** If the property is mutable, specifies whether it can be put into stasis. When a property 0069 is in stasis, a new state is created, and the old one is stored in stateInStasis. When 0070 stasis ends, the old value is restored and the new one discarded */ 0071 bool canHaveStasis {false}; 0072 0073 /** If the property isMutable and canHaveStasis, indicate whether it is in stasis or not */ 0074 bool isInStasis {false}; 0075 0076 /** If the property isMutable and canHaveStasis, provide this value to store the property's 0077 state while in stasis */ 0078 bool stateInStasis {false}; 0079 0080 bool operator==(const Property &rhs) const { 0081 return rhs.name == name && rhs.state == state && isInStasis == rhs.isInStasis; 0082 } 0083 0084 Property(): isMutable( false ), isInStasis(false) { } 0085 0086 /// Constructor for a mutable property. 0087 Property( const KoID &n, const QIcon &on, const QIcon &off, bool isOn ) 0088 : id(n.id()), name( n.name() ), isMutable( true ), onIcon( on ), offIcon( off ), state( isOn ), 0089 canHaveStasis( false ), isInStasis(false) { } 0090 0091 /** Constructor for a mutable property accepting stasis */ 0092 Property( const KoID &n, const QIcon &on, const QIcon &off, bool isOn, 0093 bool _isInStasis, bool _stateInStasis = false ) 0094 : id(n.id()), name(n.name()), isMutable( true ), onIcon( on ), offIcon( off ), state( isOn ), 0095 canHaveStasis( true ), isInStasis( _isInStasis ), stateInStasis( _stateInStasis ) { } 0096 0097 /// Constructor for a nonmutable property. 0098 Property( const KoID &n, const QString &s ) 0099 : id(n.id()), name(n.name()), isMutable( false ), state( s ), isInStasis(false) { } 0100 }; 0101 0102 /** Return this type for PropertiesRole. */ 0103 typedef QList<Property> PropertyList; 0104 0105 public: 0106 0107 /** 0108 * Create a new, empty base node. The node is unnamed, unlocked 0109 * visible and unlinked. 0110 */ 0111 KisBaseNode(KisImageWSP image); 0112 0113 /** 0114 * Create a copy of this node. 0115 */ 0116 KisBaseNode(const KisBaseNode & rhs); 0117 0118 /** 0119 * Delete this node 0120 */ 0121 ~KisBaseNode() override; 0122 0123 0124 /** 0125 * Return the paintdevice you can use to change pixels on. For a 0126 * paint layer these will be paint pixels, for an adjustment layer or a mask 0127 * the selection paint device. 0128 * 0129 * @return the paint device to paint on. Can be 0 if the actual 0130 * node type does not support painting. 0131 */ 0132 virtual KisPaintDeviceSP paintDevice() const = 0; 0133 0134 /** 0135 * @return the rendered representation of a node 0136 * before the effect masks have had their go at it. Can be 0. 0137 */ 0138 virtual KisPaintDeviceSP original() const = 0; 0139 0140 /** 0141 * @return the fully rendered representation of this layer: its 0142 * rendered original and its effect masks. Can be 0. 0143 */ 0144 virtual KisPaintDeviceSP projection() const = 0; 0145 0146 /** 0147 * @return a special device from where the color sampler tool should sample 0148 * color when in layer-only mode. For most of the nodes just shortcuts 0149 * to projection() device. TODO: can it be null? 0150 */ 0151 virtual KisPaintDeviceSP colorSampleSourceDevice() const; 0152 0153 virtual const KoColorSpace *colorSpace() const = 0; 0154 0155 /** 0156 * Return the opacity of this layer, scaled to a range between 0 0157 * and 255. 0158 * XXX: Allow true float opacity 0159 */ 0160 quint8 opacity() const; //0-255 0161 0162 /** 0163 * Set the opacity for this layer. The range is between 0 and 255. 0164 * The layer will be marked dirty. 0165 * 0166 * XXX: Allow true float opacity 0167 */ 0168 void setOpacity(quint8 val); //0-255 0169 0170 /** 0171 * return the 8-bit opacity of this layer scaled to the range 0172 * 0-100 0173 * 0174 * XXX: Allow true float opacity 0175 */ 0176 quint8 percentOpacity() const; //0-100 0177 0178 /** 0179 * Set the opacity of this layer with a number between 0 and 100; 0180 * the number will be scaled to between 0 and 255. 0181 * XXX: Allow true float opacity 0182 */ 0183 void setPercentOpacity(quint8 val); //0-100 0184 0185 /** 0186 * Return the composite op associated with this layer. 0187 */ 0188 virtual const KoCompositeOp *compositeOp() const = 0; 0189 const QString& compositeOpId() const; 0190 0191 /** 0192 * Set a new composite op for this layer. The layer will be marked 0193 * dirty. 0194 */ 0195 void setCompositeOpId(const QString& compositeOpId); 0196 0197 /** 0198 * @return unique id, which is now used by clone layers. 0199 */ 0200 QUuid uuid() const; 0201 0202 /** 0203 * Set the uuid of node. This should only be used when loading 0204 * existing node and in constructor. 0205 */ 0206 void setUuid(const QUuid& id); 0207 0208 /** 0209 * return the name of this node. This is the same as the 0210 * QObject::objectName. 0211 */ 0212 QString name() const { 0213 return objectName(); 0214 } 0215 0216 /** 0217 * set the QObject::objectName. This is also the user-visible name 0218 * of the layer. The reason for this is that we want to see the 0219 * layer name also when debugging. 0220 */ 0221 void setName(const QString& name) { 0222 setObjectName(name); 0223 baseNodeChangedCallback(); 0224 } 0225 0226 /** 0227 * @return the icon used to represent the node type, for instance 0228 * in the layerbox and in the menu. 0229 */ 0230 virtual QIcon icon() const { 0231 return QIcon(); 0232 } 0233 0234 /** 0235 * Return a the properties of this base node (locked, visible etc, 0236 * with the right icons for their representation and their state. 0237 * 0238 * Subclasses can extend this list with new properties, like 0239 * opacity for layers or visualized for masks. 0240 * 0241 * The order of properties is, unfortunately, for now, important, 0242 * so take care which properties superclasses of your class 0243 * define. 0244 * 0245 * KisBaseNode defines visible = 0, locked = 1 0246 * KisLayer defines opacity = 2, compositeOp = 3 0247 * KisMask defines active = 2 (KisMask does not inherit kislayer) 0248 */ 0249 virtual PropertyList sectionModelProperties() const; 0250 0251 /** 0252 * Change the section model properties. 0253 */ 0254 virtual void setSectionModelProperties(const PropertyList &properties); 0255 0256 /** 0257 * Return all the properties of this layer as a KoProperties-based 0258 * serializable key-value list. 0259 */ 0260 const KoProperties & nodeProperties() const; 0261 0262 /** 0263 * Set a node property. 0264 * @param name name of the property to be set. 0265 * @param value value to set the property to. 0266 */ 0267 void setNodeProperty(const QString & name, const QVariant & value); 0268 0269 /** 0270 * Merge the specified properties with the properties of this 0271 * layer. Wherever these properties overlap, the value of the 0272 * node properties is changed. No properties on the node are 0273 * deleted. If there are new properties in this list, they will be 0274 * added on the node. 0275 */ 0276 void mergeNodeProperties(const KoProperties & properties); 0277 0278 /** 0279 * Compare the given properties list with the properties of this 0280 * node. 0281 * 0282 * @return false only if the same property exists in both lists 0283 * but with a different value. Properties that are not in both 0284 * lists are disregarded. 0285 */ 0286 bool check(const KoProperties & properties) const; 0287 0288 /** 0289 * Accept the KisNodeVisitor (for the Visitor design pattern), 0290 * should call the correct function on the KisNodeVisitor for this 0291 * node type, so you need to override it for all leaf classes in 0292 * the node inheritance hierarchy. 0293 * 0294 * return false if the visitor could not successfully act on this 0295 * node instance. 0296 */ 0297 virtual bool accept(KisNodeVisitor &) { 0298 return false; 0299 } 0300 0301 /** 0302 * Accept the KisNodeVisitor (for the Visitor design pattern), 0303 * should call the correct function on the KisProcessingVisitor 0304 * for this node type, so you need to override it for all leaf 0305 * classes in the node inheritance hierarchy. 0306 * 0307 * The processing visitor differs from node visitor in the way 0308 * that it accepts undo adapter, that allows the processing to 0309 * be multithreaded 0310 */ 0311 virtual void accept(KisProcessingVisitor &visitor, KisUndoAdapter *undoAdapter) { 0312 Q_UNUSED(visitor); 0313 Q_UNUSED(undoAdapter); 0314 } 0315 0316 /** 0317 * @return a thumbnail in requested size. The thumbnail is a rgba 0318 * QImage and may have transparent parts. Returns a fully 0319 * transparent QImage of the requested size if the current node 0320 * type cannot generate a thumbnail. If the requested size is too 0321 * big, return a null QImage. 0322 */ 0323 virtual QImage createThumbnail(qint32 w, qint32 h, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio); 0324 0325 /** 0326 * @return a thumbnail in requested size for the defined timestamp. 0327 * The thumbnail is a rgba Image and may have transparent parts. 0328 * Returns a fully transparent QImage of the requested size if the 0329 * current node type cannot generate a thumbnail. If the requested 0330 * size is too big, return a null QImage. 0331 */ 0332 virtual QImage createThumbnailForFrame(qint32 w, qint32 h, int time, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio); 0333 0334 /** 0335 * Ask this node to re-read the pertinent settings from the krita 0336 * configuration. 0337 */ 0338 virtual void updateSettings() { 0339 } 0340 0341 /** 0342 * @return true if this node is visible (i.e, active (except for 0343 * selection masks where visible and active properties are 0344 * different)) in the graph 0345 * 0346 * @param bool recursive if true, check whether all parents of 0347 * this node are visible as well. 0348 */ 0349 virtual bool visible(bool recursive = false) const; 0350 0351 /** 0352 * Set the visible status of this node. Visible nodes are active 0353 * in the graph (except for selections masks which can be active 0354 * while hidden), that is to say, they are taken into account 0355 * when merging. Invisible nodes play no role in the final image 0356 *, but will be modified when modifying all layers, for instance 0357 * when cropping. 0358 * 0359 * Toggling the visibility of a node will not automatically lead 0360 * to recomposition. 0361 * 0362 * @param visible the new visibility state 0363 * @param isLoading if true, the property is set during loading. 0364 */ 0365 virtual void setVisible(bool visible, bool loading = false); 0366 0367 /** 0368 * Return the locked status of this node. Locked nodes cannot be 0369 * edited. 0370 */ 0371 bool userLocked() const; 0372 0373 /** 0374 * Return whether or not the given node is isolated. 0375 */ 0376 bool belongsToIsolatedGroup() const; 0377 0378 /** 0379 * Return whether or not the given node is the root of 0380 * isolation. 0381 */ 0382 bool isIsolatedRoot() const; 0383 0384 /** 0385 * Set the locked status of this node. Locked nodes cannot be 0386 * edited. 0387 */ 0388 virtual void setUserLocked(bool l); 0389 0390 /** 0391 * @return true if the node can be edited: 0392 * 0393 * if checkVisibility is true, then the node is only editable if it is visible and not locked. 0394 * if checkVisibility is false, then the node is editable if it's not locked. 0395 */ 0396 bool isEditable(bool checkVisibility = true) const; 0397 0398 /** 0399 * @return true if the node is editable and has a paintDevice() 0400 * which which can be used for accessing pixels. It is an 0401 * equivalent to (isEditable() && paintDevice()) 0402 */ 0403 bool hasEditablePaintDevice() const; 0404 0405 /** 0406 * @return the x-offset of this layer in the image plane. 0407 */ 0408 virtual qint32 x() const { 0409 return 0; 0410 } 0411 0412 /** 0413 * Set the x offset of this layer in the image place. 0414 * Re-implement this where it makes sense, by default it does 0415 * nothing. It should not move child nodes. 0416 */ 0417 virtual void setX(qint32) { 0418 } 0419 0420 /** 0421 * @return the y-offset of this layer in the image plane. 0422 */ 0423 virtual qint32 y() const { 0424 return 0; 0425 } 0426 0427 /** 0428 * Set the y offset of this layer in the image place. 0429 * Re-implement this where it makes sense, by default it does 0430 * nothing. It should not move child nodes. 0431 */ 0432 virtual void setY(qint32) { 0433 } 0434 0435 /** 0436 * Returns an approximation of where the bounds on actual data are 0437 * in this node. 0438 */ 0439 virtual QRect extent() const { 0440 return QRect(); 0441 } 0442 0443 /** 0444 * Returns the exact bounds of where the actual data resides in 0445 * this node. 0446 */ 0447 virtual QRect exactBounds() const { 0448 return QRect(); 0449 } 0450 0451 /** 0452 * Sets the state of the node to the value of @param collapsed 0453 */ 0454 void setCollapsed(bool collapsed); 0455 0456 /** 0457 * returns the collapsed state of this node 0458 */ 0459 bool collapsed() const; 0460 0461 /** 0462 * Sets a color label index associated to the layer. The actual 0463 * color of the label and the number of available colors is 0464 * defined by Krita GUI configuration. 0465 */ 0466 void setColorLabelIndex(int index); 0467 0468 /** 0469 * \see setColorLabelIndex 0470 */ 0471 int colorLabelIndex() const; 0472 0473 /** 0474 * Returns true if the offset of the node can be changed in a LodN 0475 * stroke. Currently, all the nodes except shape layers support that. 0476 */ 0477 bool supportsLodMoves() const; 0478 0479 /** 0480 * Returns true if the node can be painted via KisPaintDevice. Notable 0481 * exceptions are selection-based layers and masks. 0482 */ 0483 virtual bool supportsLodPainting() const; 0484 0485 /** 0486 * Return the keyframe channels associated with this node 0487 * @return list of keyframe channels 0488 */ 0489 QMap<QString, KisKeyframeChannel*> keyframeChannels() const; 0490 0491 /** 0492 * Get the keyframe channel with given id. 0493 * If the channel does not yet exist and the node supports the requested 0494 * channel, it will be created if create is true. 0495 * @param id internal name for channel 0496 * @param create attempt to create the channel if it does not exist yet 0497 * @return keyframe channel with the id, or null if not found 0498 */ 0499 KisKeyframeChannel *getKeyframeChannel(const QString &id, bool create); 0500 KisKeyframeChannel *getKeyframeChannel(const QString &id) const; 0501 0502 /** 0503 * @return If true, node will be visible on animation timeline even when inactive. 0504 */ 0505 bool isPinnedToTimeline() const; 0506 0507 /** 0508 * Set whether node should be visible on animation timeline even when inactive. 0509 */ 0510 void setPinnedToTimeline(bool pinned); 0511 0512 bool isAnimated() const; 0513 void enableAnimation(); 0514 0515 virtual void setImage(KisImageWSP image); 0516 KisImageWSP image() const; 0517 0518 0519 /** 0520 * Fake node is not present in the layer stack and is not used 0521 * for normal projection rendering algorithms. 0522 */ 0523 virtual bool isFakeNode() const; 0524 0525 protected: 0526 0527 void setSupportsLodMoves(bool value); 0528 0529 /** 0530 * FIXME: This method is a workaround for getting parent node 0531 * on a level of KisBaseNode. In fact, KisBaseNode should inherit 0532 * KisNode (in terms of current Krita) to be able to traverse 0533 * the node stack 0534 */ 0535 virtual KisBaseNodeSP parentCallback() const { 0536 return KisBaseNodeSP(); 0537 } 0538 0539 virtual void notifyParentVisibilityChanged(bool value) { 0540 Q_UNUSED(value); 0541 } 0542 0543 /** 0544 * This callback is called when some meta state of the base node 0545 * that can be interesting to the UI has changed. E.g. visibility, 0546 * lockness, opacity, compositeOp and etc. This signal is 0547 * forwarded by the KisNode and KisNodeGraphListener to the model 0548 * in KisLayerBox, so it can update its controls when information 0549 * changes. 0550 */ 0551 virtual void baseNodeChangedCallback() { 0552 } 0553 0554 /** 0555 * This callback is called when collapsed state of the base node 0556 * has changed. This signal is forwarded by the KisNode and 0557 * KisNodeGraphListener to the model in KisLayerBox, so it can 0558 * update its controls when information changes. 0559 */ 0560 virtual void baseNodeCollapsedChangedCallback() { 0561 } 0562 0563 0564 virtual void baseNodeInvalidateAllFramesCallback() { 0565 } 0566 0567 /** 0568 * Add a keyframe channel for this node. The channel will be added 0569 * to the common hash table which will be available to the UI. 0570 * 0571 * WARNING: the \p channel object *NOT* become owned by the node! 0572 * The caller must ensure manually that the lifetime of 0573 * the object coincide with the lifetime of the node. 0574 */ 0575 virtual void addKeyframeChannel(KisKeyframeChannel* channel); 0576 0577 /** 0578 * Attempt to create the requested channel. Used internally by getKeyframeChannel. 0579 * Subclasses should implement this method to catch any new channel types they support. 0580 * @param id channel to create 0581 * @return newly created channel or null 0582 */ 0583 virtual KisKeyframeChannel * requestKeyframeChannel(const QString &id); 0584 0585 public: 0586 /** 0587 * Ideally, this function would be used to query for keyframe support 0588 * before trying to create channels. The ability to query would help 0589 * in cases such as animation curves where you might want to ask 0590 * which channels it supports before allowing the user to add. 0591 * 0592 * @param id querried channel 0593 * @return bool whether it supports said channel or not. 0594 */ 0595 virtual bool supportsKeyframeChannel(const QString &id); 0596 0597 Q_SIGNALS: 0598 void keyframeChannelAdded(KisKeyframeChannel *channel); 0599 void opacityChanged(quint8 value); 0600 0601 private: 0602 0603 struct Private; 0604 Private * const m_d; 0605 0606 }; 0607 0608 KRITAIMAGE_EXPORT QDebug operator<<(QDebug dbg, const KisBaseNode::Property &prop); 0609 0610 Q_DECLARE_METATYPE( KisBaseNode::PropertyList ) 0611 0612 0613 #endif