File indexing completed on 2024-10-27 04:07:33

0001 /*
0002  *  SPDX-FileCopyrightText: 2011 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __KIS_NODE_DUMMIES_GRAPH_H
0008 #define __KIS_NODE_DUMMIES_GRAPH_H
0009 
0010 #include <QList>
0011 #include <QMap>
0012 
0013 #include "kritaui_export.h"
0014 #include "kis_types.h"
0015 #include "kis_node.h"
0016 
0017 class KisNodeShape;
0018 
0019 /**
0020  * KisNodeDummy is a simplified representation of a node
0021  * in the node stack. It stores all the hierarchy information
0022  * about the node, so you needn't access from the node
0023  * directly (actually, you cannot do it usually, because UI
0024  * works in a different thread and race conditions are possible).
0025  *
0026  * The dummy stores a KisNodeShape which can store a pointer to
0027  * to node. You can access to the node data through it, but take
0028  * care -- not all the information is accessible in
0029  * multithreading environment.
0030  *
0031  * The ownership on the KisNodeShape is taken by the dummy.
0032  * The ownership on the children of the dummy is taken as well.
0033  */
0034 
0035 class KRITAUI_EXPORT KisNodeDummy : public QObject
0036 {
0037     Q_OBJECT
0038 
0039 public:
0040     /**
0041      * Take care that KisNodeDummy does not take ownership over
0042      * the \p nodeShape since the handling of the removal of the
0043      * children of the shape is done by flake. So please handle it
0044      * manually.
0045      *
0046      * The children dummies of the dummy are still owned by the
0047      * dummy and are deleted automatically.
0048      */
0049     KisNodeDummy(KisNodeShape *nodeShape, KisNodeSP node);
0050     ~KisNodeDummy() override;
0051 
0052     KisNodeDummy* firstChild() const;
0053     KisNodeDummy* lastChild() const;
0054     KisNodeDummy* nextSibling() const;
0055     KisNodeDummy* prevSibling() const;
0056     KisNodeDummy* parent() const;
0057 
0058     KisNodeDummy* at(int index) const;
0059     int childCount() const;
0060     int indexOf(KisNodeDummy *child) const;
0061 
0062     KisNodeSP node() const;
0063 
0064     bool isGUIVisible(bool showGlobalSelection) const;
0065 
0066 private:
0067     friend class KisNodeShapesGraph; // for ::nodeShape() method
0068     friend class KisNodeShapesGraphTest;
0069     KisNodeShape* nodeShape() const;
0070 
0071     friend class KisNodeDummiesGraph;
0072     QList<KisNodeDummy*> m_children;
0073 
0074     KisNodeShape *m_nodeShape;
0075     KisNodeSP m_node;
0076 };
0077 
0078 /**
0079  * KisNodeDummiesGraph manages the hierarchy of dummy objects
0080  * representing nodes in the UI environment.
0081  */
0082 
0083 class KRITAUI_EXPORT KisNodeDummiesGraph
0084 {
0085 public:
0086     KisNodeDummiesGraph();
0087 
0088     /**
0089      * Returns the root dummy of the graph. Take it into account that
0090      * root may be null, while the image is being switched.
0091      */
0092     KisNodeDummy* rootDummy() const;
0093 
0094     KisNodeDummy* nodeToDummy(KisNodeSP node);
0095     bool containsNode(KisNodeSP node) const;
0096     int dummiesCount() const;
0097 
0098     /**
0099      * Adds a dummy \p node to the position specified
0100      * by \p parent and \p aboveThis.
0101      *
0102      * It is not expected that you would add a dummy twice.
0103      */
0104     void addNode(KisNodeDummy *node, KisNodeDummy *parent, KisNodeDummy *aboveThis);
0105 
0106     /**
0107      * Moves a dummy \p node from its current position to
0108      * the position specified by \p parent and \p aboveThis.
0109      *
0110      * It is expected that the dummy \p node has been added
0111      * to the graph with addNode() before calling this function.
0112      */
0113     void moveNode(KisNodeDummy *node, KisNodeDummy *parent, KisNodeDummy *aboveThis);
0114 
0115     /**
0116      * Removes the dummy \p node from the graph.
0117      *
0118      * WARNING: The dummy is only "unlinked" from the graph. Neither
0119      * deletion of the node nor deletion of its children happens.
0120      * The dummy keeps maintaining its children so after unlinking
0121      * it from the graph you can just type to free memory recursively:
0122      * \code
0123      * graph.removeNode(node);
0124      * delete node;
0125      * \endcode
0126      */
0127     void removeNode(KisNodeDummy *node);
0128 
0129 private:
0130     void unmapDummyRecursively(KisNodeDummy *dummy);
0131 
0132 private:
0133     typedef QMap<KisNodeSP, KisNodeDummy*> NodeMap;
0134 
0135 private:
0136     KisNodeDummy *m_rootDummy;
0137     NodeMap m_dummiesMap;
0138 };
0139 
0140 #endif /* __KIS_NODE_DUMMIES_GRAPH_H */