File indexing completed on 2024-05-19 04:29:01

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_MANAGER
0007 #define KIS_NODE_MANAGER
0008 
0009 #include <QObject>
0010 #include <QList>
0011 #include <QAction>
0012 
0013 #include "kis_types.h"
0014 #include "kis_base_node.h"
0015 #include "kis_image.h"
0016 #include <kritaui_export.h>
0017 
0018 class KisKActionCollection;
0019 
0020 class KoCompositeOp;
0021 class KoColorSpace;
0022 class KUndo2MagicString;
0023 
0024 class KisFilterStrategy;
0025 class KisViewManager;
0026 class KisActionManager;
0027 class KisView;
0028 class KisNodeSelectionAdapter;
0029 class KisNodeInsertionAdapter;
0030 class KisNodeDisplayModeAdapter;
0031 class KisNodeJugglerCompressed;
0032 class KoProperties;
0033 
0034 /**
0035  * The node manager passes requests for new layers or masks on to the mask and layer
0036  * managers.
0037  */
0038 class KRITAUI_EXPORT KisNodeManager : public QObject
0039 {
0040 
0041     Q_OBJECT
0042 
0043 public:
0044 
0045     KisNodeManager(KisViewManager * view);
0046     ~KisNodeManager() override;
0047 
0048     void setView(QPointer<KisView>imageView);
0049 
0050 Q_SIGNALS:
0051 
0052     /// emitted whenever a node is selected.
0053     void sigNodeActivated(KisNodeSP node);
0054 
0055     /// for the layer box: this sets the current node in the layerbox
0056     /// without telling the node manager that the node is activated,
0057     /// preventing loops (I think...)
0058     void sigUiNeedChangeActiveNode(KisNodeSP node);
0059 
0060     void sigUiNeedChangeSelectedNodes(const KisNodeList &nodes);
0061 
0062 public:
0063 
0064     void setup(KisKActionCollection * collection, KisActionManager* actionManager);
0065     void updateGUI();
0066 
0067     /// Convenience function to get the active layer or mask
0068     KisNodeSP activeNode();
0069 
0070     /// convenience function to get the active layer. If a mask is
0071     /// active, it's parent layer is the active layer.
0072     KisLayerSP activeLayer();
0073 
0074     /// Get the paint device the user wants to paint on now
0075     KisPaintDeviceSP activePaintDevice();
0076 
0077     /**
0078      * @return the active color space used for composition, meaning the color space
0079      * of the active mask, or the color space of the parent of the active layer
0080      */
0081     const KoColorSpace* activeColorSpace();
0082 
0083     /**
0084      * Sets the name for the node in a universal way (masks/layers)
0085      */
0086     void setNodeName(KisNodeSP node, const QString &name);
0087 
0088     /**
0089      * Sets opacity for the node in a universal way (masks/layers)
0090      */
0091     void setNodeOpacity(KisNodeSP node, qint32 opacity);
0092 
0093     /**
0094      * Sets compositeOp for the node in a universal way (masks/layers)
0095      */
0096     void setNodeCompositeOp(KisNodeSP node, const KoCompositeOp* compositeOp);
0097 
0098     KisNodeList selectedNodes();
0099 
0100     KisNodeSelectionAdapter* nodeSelectionAdapter() const;
0101     KisNodeInsertionAdapter* nodeInsertionAdapter() const;
0102     KisNodeDisplayModeAdapter* nodeDisplayModeAdapter() const;
0103 
0104     static bool isNodeHidden(KisNodeSP node, bool isGlobalSelectionHidden);
0105 
0106     bool trySetNodeProperties(KisNodeSP node, KisImageSP image, KisBaseNode::PropertyList properties) const;
0107 
0108 
0109     bool canModifyLayers(KisNodeList nodes, bool showWarning = true);
0110     bool canModifyLayer(KisNodeSP node, bool showWarning = true);
0111 
0112     bool canMoveLayers(KisNodeList nodes, bool showWarning = true);
0113     bool canMoveLayer(KisNodeSP node, bool showWarning = true);
0114 
0115 public Q_SLOTS:
0116 
0117     /**
0118      * Explicitly activates \p node
0119      * The UI will be noticed that active node has been changed.
0120      * Both sigNodeActivated and sigUiNeedChangeActiveNode are emitted.
0121      *
0122      * WARNING: normally you needn't call this method manually. It is
0123      * automatically called when a node is added to the graph. If you
0124      * have some special cases when you need to activate a node, consider
0125      * adding them to KisDummiesFacadeBase instead. Calling this method
0126      * directly  should be the last resort.
0127      *
0128      * \see slotUiActivatedNode for comparison
0129      */
0130     void slotNonUiActivatedNode(KisNodeSP node);
0131 
0132     /**
0133      * Activates \p node.
0134      * All non-ui listeners are notified with sigNodeActivated,
0135      * sigUiNeedChangeActiveNode is *not* emitted.
0136      *
0137      * \see activateNode
0138      */
0139     void slotUiActivatedNode(KisNodeSP node);
0140 
0141     /**
0142      * Adds a list of nodes without searching appropriate position for
0143      * it.  You *must* ensure that the nodes are allowed to be added
0144      * to the parent, otherwise you'll get an assert.
0145      */
0146     void addNodesDirect(KisNodeList nodes, KisNodeSP parent, KisNodeSP aboveThis);
0147 
0148     /**
0149      * Moves a list of nodes without searching appropriate position
0150      * for it.  You *must* ensure that the nodes are allowed to be
0151      * added to the parent, otherwise you'll get an assert.
0152      */
0153     void moveNodesDirect(KisNodeList nodes, KisNodeSP parent, KisNodeSP aboveThis);
0154 
0155     /**
0156      * Copies a list of nodes without searching appropriate position
0157      * for it.  You *must* ensure that the nodes are allowed to be
0158      * added to the parent, otherwise you'll get an assert.
0159      */
0160     void copyNodesDirect(KisNodeList nodes, KisNodeSP parent, KisNodeSP aboveThis);
0161 
0162     /**
0163      * Create new layer from actually visible
0164      */
0165     void createFromVisible();
0166 
0167     void slotPinToTimeline(bool value);
0168 
0169     // Isolation Mode..
0170 
0171     void toggleIsolateActiveNode();
0172     void setIsolateActiveLayerMode(bool checked);
0173     void setIsolateActiveGroupMode(bool checked);
0174 
0175     void changeIsolationMode(bool isolateActiveLayer, bool isolateActiveGroup);
0176     void changeIsolationRoot(KisNodeSP isolationRoot);
0177 
0178     /**
0179      * Responds to external changes in isolation mode (i.e. from KisImage).
0180      */
0181     void handleExternalIsolationChange();
0182     void reinitializeIsolationActionGroup();
0183 
0184     // General Node Management..
0185 
0186     void moveNodeAt(KisNodeSP node, KisNodeSP parent, int index);
0187     KisNodeSP createNode(const QString& nodeType, bool quiet = false, KisPaintDeviceSP copyFrom = 0);
0188     void convertNode(const QString &nodeType);
0189     void nodesUpdated();
0190     void nodeProperties(KisNodeSP node);
0191     /// pop up a window for changing the source of the selected Clone Layers
0192     void changeCloneSource();
0193     void nodeOpacityChanged(qreal opacity);
0194     void nodeCompositeOpChanged(const KoCompositeOp* op);
0195     void duplicateActiveNode();
0196     void removeNode();
0197     void mirrorNodeX();
0198     void mirrorNodeY();
0199     void mirrorAllNodesX();
0200     void mirrorAllNodesY();
0201 
0202     void mirrorNode(KisNodeSP node, const KUndo2MagicString& commandName, Qt::Orientation orientation, KisSelectionSP selection);
0203     void mirrorNodes(KisNodeList nodes, const KUndo2MagicString& commandName, Qt::Orientation orientation, KisSelectionSP selection);
0204 
0205     void activateNextNode(bool siblingsOnly = false);
0206     void activateNextSiblingNode();
0207     void activatePreviousNode(bool siblingsOnly = false);
0208     void activatePreviousSiblingNode();
0209     void switchToPreviouslyActiveNode();
0210 
0211     /**
0212      * move the active node up the nodestack.
0213      */
0214     void raiseNode();
0215 
0216     /**
0217      * move the active node down the nodestack
0218      */
0219     void lowerNode();
0220 
0221     void saveNodeAsImage();
0222     void saveVectorLayerAsImage();
0223 
0224     void slotSplitAlphaIntoMask();
0225     void slotSplitAlphaWrite();
0226     void slotSplitAlphaSaveMerged();
0227 
0228     void toggleLock();
0229     void toggleVisibility();
0230     void toggleAlphaLock();
0231     void toggleInheritAlpha();
0232 
0233     /**
0234      * @brief slotSetSelectedNodes set the list of nodes selected in the layerbox. Selected nodes are not necessarily active nodes.
0235      * @param nodes the selected nodes
0236      */
0237     void slotSetSelectedNodes(const KisNodeList &nodes);
0238 
0239     void slotImageRequestNodeReselection(KisNodeSP activeNode, const KisNodeList &selectedNodes);
0240 
0241     void cutLayersToClipboard();
0242     void copyLayersToClipboard();
0243     void pasteLayersFromClipboard(bool changeOffset = false, QPointF offset = QPointF());
0244 
0245     void createQuickGroup();
0246     void createQuickClippingGroup();
0247     void quickUngroup();
0248 
0249     void selectAllNodes();
0250     void selectVisibleNodes();
0251     void selectLockedNodes();
0252     void selectInvisibleNodes();
0253     void selectUnlockedNodes();
0254 
0255 private Q_SLOTS:
0256 
0257     friend class KisNodeActivationActionCreatorVisitor;
0258     /**
0259      * @brief slotUiActivateNode inspects the sender to see which node needs to be activated.
0260      */
0261     void slotUiActivateNode();
0262 
0263 
0264 public:
0265     void removeSingleNode(KisNodeSP node);
0266     KisLayerSP createPaintLayer();
0267 
0268 private:
0269     /**
0270      * Scales opacity from the range 0...1
0271      * to the integer range 0...255
0272      */
0273     qint32 convertOpacityToInt(qreal opacity);
0274     void removeSelectedNodes(KisNodeList selectedNodes);
0275     void slotSomethingActivatedNodeImpl(KisNodeSP node);
0276     bool createQuickGroupImpl(KisNodeJugglerCompressed *juggler,
0277                               const QString &overrideGroupName,
0278                               KisNodeSP *newGroup,
0279                               KisNodeSP *newLastChild);
0280     void selectLayersImpl(const KoProperties &props, const KoProperties &invertedProps);
0281 
0282     struct Private;
0283     Private * const m_d;
0284 };
0285 
0286 #endif